XtraRexx - Version v0.44b

Автор: Martin Kiewitz

Дата: 24.02.2005

Скачать библиотеку в ZIP архиве.


                        Written and (c) by Martin Kiewitz
                            Dedicated to Gerd Kiewitz
-------------------------------------------------------------------------------

        This software is 'e-mail ware'. This means, if you use it, please send
         me an e-mail or a greeting card. I just want to see, how many people
         are using it.

  ============
  | FOREWORD |
  ============

        Well, I'm using REXX since 4-5 years. It's a very powerful language
         especially because of the DLL addon support. One may just write a
         simple OS/2-DLL and enhance REXX that way.

        I started doing XtraRexx 3 years ago. I enhanced it everytime I needed
         more functions especially for CGI programming. XtraRexx is now very
         powerful and offers all sorts of functions. I also implemented some
         "standard" functions, which are mostly included in almost any REXX
         extension DLL. Some important internal code is written in assembly
         language for absolute speed (6bit<->8bit, CRC calculation).
         Most of the code was done using IBM C.

        XtraRexx has especially fast template processing functions. They are
         meant for processing HTML templates - fill in variables, do loops
         and include/exclude parts of the file in the output. It's everything
         one needs and you still maintain control over it via REXX.

        XtraRexx v0.42 now also includes powerful Date/Time-functions for
         calculating with date and time data.

        Now I thought about releasing it to the public. I bet at least some
         programmers will start using it for CGI programming and such stuff.
         I wrote this documentation in around 3-4 hours, so please forgive
         typos.
         BTW. I won't release the source-code, at least for now - so don't ask.

        XtraRexx v0.43 contains a whole set of file/directory functions.
         It also offers an addition to the session-routines -
         XtraEnumSessions(), XtraSetOwnTitle() and XtraGetOwnTitle().

        XtraRexx v0.44 contains 2 additional Date/Time functions that are able
         to convert a UNIX date into XtraRexx internal format. XtraDateFormat &
         XtraTimeFormat were also extended to support UNIX-stamp output.
         This version also contains a bugfix to several XtraFile-functions,
          that didn't work as specified. To be exact on functions having an
          optional offset parameter as 3rd parameter, the offset was taken from
          the 2nd parameter.

        NOTE: This DLL is currently in-development and BETA software. I'm using
               it myself in a productive (web/2) environment - anyway, do so
               ONLY if you checked all functionality by yourself. I'm not
               responsible for broken servers, broken data or whatsoever. Also
               if there is a bug, please tell me. Anyway, don't rely on me
               fixing it within a few days.

  ================
  | INSTALLATION |
  ================

         Just copy XtraRexx.DLL into your \OS2\DLL directory. That's it.
         XtraRexx will always remain backward-compatible to prior versions.

         If you are a programmer, please use the XtraVersion API and check for
          the required version number like this:
           If XtraVersion()<"0.44" Then Do
              say "XtraRexx v0.44+ required."
              exit
           End

  ===================
  | BASIC FUNCTIONS |
  ===================

       ---------------------------------
        v0.42+ - XtraLoadFuncs([quiet])
       ---------------------------------
       This is used to connect all functions automatically to REXX space.
        You may also specify the optional parameter "quiet" (case-sensitive) to
        disable the copyright message (for CGI usage).

       Returns:
        none

       Example:
        call RxFuncAdd "XtraLoadFuncs","XtraRexx","XtraLoadFuncs"
        call XtraLoadFuncs

       --------------------------
        v0.42+ - XtraDropFuncs()
       --------------------------
       This is used to disconnect all functions automatically. It's not needed
        to use it.

       Returns:
        none

       ------------------------
        v0.42+ - XtraVersion()
       ------------------------
       This is used to get the current version number of XtraRexx.

       Returns:
        XtraRexx Version number in the format "x.xx"

       Example:
        say XtraVersion() - would put "0.44" on the screen.

       ----------------------------------
        v0.42+ - XtraSleep(Milliseconds)
       ----------------------------------
       This is used to sleep a specific amount of milliseconds.

       Returns:
        none

       Example:
        call XtraSleep 1000 - would sleep 1 second

       -------------------------------
        v0.42+ - XtraUnlock(Filename)
       -------------------------------
       Will unlock a currently locked file. This is used for replacing DLL
        files w/o needing to use the locked file device driver functionality.

       Returns:
        "DONE", if action got done
        "NOTREQ", if action is not required (DLL not currently locked)
        "ERROR", if any error occured

       Example:
        say XtraUnlock("C:\OS2\DLL\XtraRexx.dll")

       -----------------------------
        v0.42+ - XtraGetBootDrive()
       -----------------------------
       Will get the driveletter from the drive that the system booted from.

       Returns:
        "x:", where x is the drive-letter

       Example:
        say XtraGetBootDrive() - could put "C:" on the screen

       ---------------------------------------
        v0.42+ - XtraGetPictureInfo(Filename)
       ---------------------------------------
       Will identify a picture and get the resolution of the picture as well
        The file is identified via binary analysation and not by looking at the
        filename-extension!

       Returns:
        "", if not identified
        "NNN RxRxR", where NNN is the type (JPG,PNG,GIF) and RxRxR is the
         resolution. The first R is the width in pixel, the second R is the
         height and the last R are the bits per pixel.

       Example:
        say XtraGetPictureInfo("test.jpg") - could reply "JPG 128x64x24"
            
       -------------------------------
        v0.42+ - XtraGetCRC32(String)
       -------------------------------
       Will get the CRC32 value of the specified string.

       Returns:
        "FFFFFFFF", reply is always 8 chars hexadecimal code

       Example:
        say XtraGetCRC32("test") - would put "D87F7E0C" on the screen

       --------------------------------------------
        v0.42+ - XtraSwitchToSession(Session-Name)
       --------------------------------------------
       Will switch focus to a session whose name begins with the given name.

       Returns:
        "OK", if operation succeeded
        "NOTFOUND", if session was not found

       Example:
        call XtraSwitchToSession "PMMail/2"
        /* would switch to PMMail/2 */

       ------------------------------------------------------------------------
        v0.42+ - XtraSetPosOfSession(Session-Name, VerticalPos, HorizontalPos)
       ------------------------------------------------------------------------
       Will set the absolute position of a session "on-screen". This also
        works using multiple desktops and may be used to rearrange windows
        when starting up a system or even change position of windows after
        some time for displaying different stuff.

        VerticalPos: 0 means left-most
        HorizontalPos: 0 means lower-most

        The position given means the position of the lower-left edge of the
         window!

       Returns:
        "OK", if operation succeeded
        "NOTFOUND", if session was not found

       Example:
        call XtraSetPosOfSession "PMMail/2", 0, 0
        /* would put PMMail/2 at the left-most, lower-most position on the */
        /*  screen */

       --------------------------------------
        v0.43+ - XtraEnumSessions(Stem-Name)
       --------------------------------------
       Will enumerate (list) all visible session-names into a stem.

       Returns:
        nothing, fills in stem

       Example:
        call XtraEnumSessions "AllSessions."
        say "Session count: "AllSessions.0
        say "First session: "AllSessions.1
        /* would display total visible sessions and the name of the first */
        /*  session */

       ----------------------------
        v0.43+ - XtraGetOwnTitle()
       ----------------------------
       Will get the current title-bar text of the current window.
        Due to the nature of OS/2, XtraRexx has to generate and destroy a
        helper message queue on every call.

       Returns:
        Current title

       Example:
        say XtraGetOwnTitle()
        /* would display current title bar to screen */

       ---------------------------------
        v0.43+ - XtraSetOwnTitle(Title)
       ---------------------------------
       Will set the current title-bar text of the current window.
        Due to the nature of OS/2, XtraRexx has to generate and destroy a
        helper message queue on every call.

       Returns:
        nothing

       Example:
        call XtraSetOwnTitle "This is a test title-bar"
        /* would make appear the specified string on the window title-bar */

       --------------------------------
        v0.42+ - XtraIsDesktopLocked()
       --------------------------------
       Will find out, if the desktop is currently locked.

       Returns:
        "LOCKED", if desktop locked
        "UNLOCKED", if desktop unlocked

       Example:
        say XtraIsDesktopLocked()
                                              
  ======================
  | TEMPLATE FUNCTIONS |
  ======================

       This specifies the 3 template functions used for processing e.g. HTML
        template files. Those files may contain template codes like this here:

       
         - Lets REXX code insert data using the name "value"

       
       
       
         - Lets REXX code choose wether to insert template data or not.
            REXX is only called on "incif". On "else-incif" XtraRexx will do
            the opposite action of what the REXX script told it on "incif".
            NOTE: else-incif also requires the *same* name. Also else-incif
                   may be ommited, if not needed.

       
       
         - Lets REXX code choose how often the loop shall be processed. It's
            also possible to skip the contents of the loop.

        All of these template codes are reentrant, which means you may specify
         a loop within a loop and so on.
        Template codes are CASE-SENSITIVE. You have to specify actions in
         lowcase (will NOT work).

        Now for the API:

       -------------------------------------
        v0.42+ - XtraTemplateInit(Filename)
       -------------------------------------
       Will initiate template processing on a specific file. Will open the file
        for processing.

       Returns:
        "0", if open failed
        "1", if everything worked out

       Example:
        If XtraTemplateInit("test.html") Then Do
           say "Template file opened"
        End

       --------------------------------
        v0.42+ - XtraTemplateProcess()
       --------------------------------
       This will process the template till end-of-file or till a template code
        is found that needs REXX processing. In that case, it will reply the
        template code. In any case, it will write any template data (but the
        codes of course) to STDOUT.

       Returns:
        "", when End-Of-File reached
        "ACTION:NAME", where ACTION is the action-type of the template code
                        and NAME is the name mentioned in it.

       Example:
        Do Forever
           SSI = XtraTemplateProcess()
           if Length(SSI)=0 Then leave

           Data = ""
           Select
             When SSI="insert:myvalue"           Then Data = "XtraRexx is great"
             Otherwise Nop
           End
           call CharOut ,Data
        End
        /* This here would process a template and insert "XtraRexx is great" */
        /*  as myvalue */

       ---------------------------------
        v0.42+ - XtraTemplateDoAction()
       ---------------------------------
       This is used, when XtraRexx is told to actually process one iteration
        of a loop or process an "incif" template code. Calling it won't process
        it immediately. It will get processed when calling XtraTemplateProcess
        again.

       Returns:
        none

       Example:
        call XtraTemplateDoAction

       -------------------
        Big example code:
       -------------------
       This here is for showing you the usage of loop and incif codes.

        QuestCount   = 2
        Questions.1  = "Do you like XtraRexx?"
        Questions.2  = "Do you like OS/2?"
        QuestDisclaimer.1 = "YES"
        QuestDisclaimer.2 = "NO"

        say "Content-type: text/html"
        say ""
        call XtraTemplateInit "mytemplate.html"

        Do Forever
           SSI = XtraTemplateProcess()
           if Length(SSI)=0 Then leave
     
           Data = ""
           Select
             When SSI="insert:CGI_URL"           Then Data = CGI_URL
             When SSI="loop:quests"              Then Do
              CurQuest = 1
              If QuestCount>=CurQuest Then
                 call XtraTemplateDoAction
             End
             When SSI="end-loop:quests"          Then Do
              CurQuest = CurQuest+1
              If QuestCount>=CurQuest Then
                 call XtraTemplateDoAction
             End
             When SSI="insert:question"          Then Data = Questions.CurQuest
             When SSI="incif:disclaimer"         Then Do
              If QuestDisclaimer.CurQuest="YES"  Then
                 call XtraTemplateDoAction
             Otherwise Nop
           End
           call CharOut ,Data
        End

        Template-file:
        
         
          


         
           
              
           
           
              
              
              
              
           
        
          


        
                 
              
  yes no
               
                  Disclaimer
               
              

         
        

         I removed FORM code and so on to make it more readable. This example
          is only meant to get the feeling for it.

  ======================
  | DIRECT/C FUNCTIONS |
  ======================

       Direct/C are some conversion functions that I ported over from old
        sourcecode of mine. I'm using parts of it for BASE64 en/decoding in my
        e-mail filter REXX script - and the speed is faster than any tool or
        program that I got my hands on.

       --------------------------------
        v0.42+ - DirectC_CvWrd(String)
       --------------------------------
       Will convert a 2-char string into a decimal value using Intel-ordering.

       Returns:
        "0", if the string length is not 2
        "x", where x is a decimal number ranging from 0 to 65535

       Example:
        say DirectC_CvWrd(D2C(1)||D2C(0))
        /* Will put "1" on the screen */
        say DirectC_CvWrd(D2C(0)||D2C(1))
        /* Will put "256" on the screen */

       --------------------------------
        v0.42+ - DirectC_CvDwd(String)
       --------------------------------
       Will convert a 4-char string into a decimal value using Intel-ordering.

       Returns:
        "0", if the string length is not 4
        "x", where x is a decimal number ranging from 0 to 4294967295

       Example:
        say DirectC_CvWrd(D2C(1)||D2C(0)||D2C(0)||D2C(0))
        /* Will put "1" on the screen */
        say DirectC_CvWrd(D2C(0)||D2C(1)||D2C(0)||D2C(0))
        /* Will put "256" on the screen */

       ---------------------------------------
        v0.42+ - DirectC_Set6bitTable(String)
       ---------------------------------------
       This enables the Encode/Decode From/To 6-bit functions. You need to give
        a 64-char string, so that XtraRexx is able to know what char to use.

       Returns:
        none

       Example:
        call DirectC_Set6bitTable "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
        /* Table used for BASE64 en/decoding */

       ---------------------------------------
        v0.42+ - DirectC_EncodeTo6bit(String)
       ---------------------------------------
       Encodes an 8-bit string into 6-bit using the 6-bit table.

       Returns:
        The 6-bit string of course

       Example:
        say DirectC_EncodeTo6bit("test")
        /* Will put "dGVzdA" on the screen (when the 6-bit MIME table is used) */

       -----------------------------------------
        v0.42+ - DirectC_DecodeFrom6bit(String)
       -----------------------------------------
       Decodes an 6-bit string into 8-bit using the 6-bit table.

       Returns:
        The 8-bit string of course

       Example:
        say DirectC_DecodeFrom6bit("dGVzdA")
        /* Will put "test" on the screen (when the 6-bit MIME table is used) */

       ---------------------------------------------------------------------------
        v0.42+ - DirectC_EncodeTo6bitViaFile(InputFile, CharsPerLine, OutputFile)
       ---------------------------------------------------------------------------
       Encodes the contents of a whole 8-bit file and appends them onto a file.
       CharsPerLine defines how many chars will be ENCODED per ASCII output
        line. This is not the size of the output ascii line.

       Returns:
        Size of the new output file in decimal

       Example:
        call DirectC_EncodeTo6bitViaFile "test.exe", 1024, "test.mime"

       ------------------------------------------------------------------------------------------
        v0.42+ - DirectC_DecodeFrom6bitViaFile(InputFile, InputOffset, OutputFile, BoundaryLine)
       ------------------------------------------------------------------------------------------
       Decodes the contents of a file (6-bit) into another file (8-bit).
        InputOffset is the offset from where decoding will start. The first
        char of a file has offset 1!

       One may also set a BoundaryLine to stop decoding when finding a line
        that *starts* using those characters (case-sensitive).
       When specifying "" as boundary, XtraRexx will decode till end-of-file.

       Returns:
        Offset within InputFile, where stream ends (1 based again)

       Example:
        call DirectC_DecodeFrom6bitViaFile "test.mime", 1, "test.exe", ""

  =======================
  | DATE/TIME FUNCTIONS |
  =======================

       Those functions were done for easy time/date calculation within REXX.

       Dates are 8-char strings in the format of "YYYYMMDD".
       Times are 4-char strings in the format of "HHMM".

       This format is great for saving, comparsion and sorting.
       e.g. to compare 2 dates simply use: If BeginDate>EndDate Then

       -------------------------------
        v0.42+ - XtraDateGetCurrent()
       -------------------------------
       This simply gets the current date.

       Returns:
        "YYYYMMDD"

       Example:
        say XtraDateGetCurrent()
        /* This should put the current date in our internal format on the screen */

       ------------------------------------
        v0.42+ - XtraDateNormalize(String)
       ------------------------------------
       This is used, when a user inputs a date and you want to analyse and
        extract his input. It may also be used for getting the date out of
        SysFileTree() data and so on. XtraRexx will use both short and long
        month names for analysation as well (ffs. XtraDateSetMonthNames).
        Also mentioning day types (monday, tuesday, etc.) is possible (ffs.
        XtraDateSetDayNames).

       The method used is quite complex and almost gets any date format that
        is possible. It's also intelligent in a way that you may simply specify
        just a day and XtraRexx will get the month and year for it.

       e.g. on 4th january 2005:
            specifying "5" will reply "20050105"
            specifying "4" will reply "20050204"
            specifying "4 12" will reply" 20051204"

       It's also possible to tell XtraRexx to walk backwards using "-".

       e.g. on 4th january 2005:
            specifying "5-" will reply "20041205"
            specifying "4-" will reply "20050104"
            specifying "4 12-" will reply "20041204"

       Specifying an empty string will reply the current date.

       Returns:
        "YYYYMMDD"
        or "", if date invalid (or not extractable)

       Example:
        say XtraDateNormalize("1 nov 2005")
        /* This should put "20051101" on the screen */
        say XtraDateNormalize("11/1/2005")
        /* This should put "20051101" on the screen */

       ------------------------------------------
        v0.42+ - XtraDateAddDays(Date, DayCount)
       ------------------------------------------
       This is used, when adding days to a date.

       Returns:
        "YYYYMMDD"

       Example:
        say XtraDateAddDays("20050104", 5)
        /* This should put "20050109" on the screen */

       ------------------------------------------
        v0.42+ - XtraDateSubDays(Date, DayCount)
       ------------------------------------------
       This is used, when subtracting days from a date.

       Returns:
        "YYYYMMDD"

       Example:
        say XtraDateSubDays("20050104", 5)
        /* This should put "20041230" on the screen */

       ----------------------------------------------
        v0.42+ - XtraDateAddMonths(Date, MonthCount)
       ----------------------------------------------
       This is used, when adding months to a date.

       Returns:
        "YYYYMMDD"

       Example:
        say XtraDateAddMonths("20050104", 5)
        /* This should put "20050604" on the screen */

       ----------------------------------------------
        v0.42+ - XtraDateSubMonths(Date, MonthCount)
       ----------------------------------------------
       This is used, when subtracting months from a date.

       Returns:
        "YYYYMMDD"

       Example:
        say XtraDateSubMonths("20050104", 5)
        /* This should put "20040804" on the screen */

       --------------------------------------------
        v0.42+ - XtraDateAddYears(Date, YearCount)
       --------------------------------------------
       This is used, when adding years to a date.

       Returns:
        "YYYYMMDD"

       Example:
        say XtraDateAddYears("20050104", 5)
        /* This should put "20100104" on the screen */

       --------------------------------------------
        v0.42+ - XtraDateSubYears(Date, YearCount)
       --------------------------------------------
       This is used, when subtracting years from a date.

       Returns:
        "YYYYMMDD"

       Example:
        say XtraDateAddYears("20050104", 5)
        /* This should put "20000104" on the screen */

       --------------------------------
        v0.42+ - XtraDateGetType(Date)
       --------------------------------
       This is used to get the type of a date.

       Returns:
        "x", where 1 is monday and 7 is sunday.

       Example:
        say XtraDateGetType("20050104")
        /* This should put "2" (Tuesday) on the screen */

       -------------------------------------------
        v0.42+ - XtraDateAddType(DateType, Count)
       -------------------------------------------
       This is used, when adding to a datetype.

       Returns:
        "x", where 1 is monday and 7 is sunday.

       Example:
        say XtraDateAddType(2, 6)
        /* This should put "1" (Monday) on the screen */

       -------------------------------------------
        v0.42+ - XtraDateSubType(DateType, Count)
       -------------------------------------------
       This is used, when subtracting from a datetype.

       Returns:
        "x", where 1 is monday and 7 is sunday.

       Example:
        say XtraDateSubType(2, 6)
        /* This should put "3" (Wednesday) on the screen */

       -------------------------------------------------
        v0.42+ - XtraDateGetNextTypeDay(Date, DateType)
       -------------------------------------------------
       This gets the following date after the specified date that has the given
        type. This never replies with the given Date!

       Returns:
        "YYYYMMDD"

       Example:
        say XtraDateGetNextTypeDay("20050104", 2)
        /* This should put "20050111" on the screen */

       -----------------------------------------------------
        v0.42+ - XtraDateGetPreviousTypeDay(Date, DateType)
       -----------------------------------------------------
       This gets the previous date before or equal the given date that has the
        given type. This MAY reply the given date!

       Returns:
        "YYYYMMDD"

       Example:
        say XtraDateGetPreviousTypeDay("20050104", 2)
        /* This should put "20050104" on the screen */

       -------------------------------------
        v0.42+ - XtraDateGetMonthDays(Date)
       -------------------------------------
       This gets the total amount of days in the specified month.

       Returns:
        "x"

       Example:
        say XtraDateGetMonthDays("20050104")
        /* This should put "31" on the screen */

       -------------------------------------------------------------------
        v0.42+ - XtraDateGetDaysBetween(Date, [Time,] 2ndDate [,2ndTime])
       -------------------------------------------------------------------
       This gets the total amount of days inbetween 2 dates. One may also
        specify an additional Time for those days to be more accurate. This is
        meant for getting the exact days and minutes between 2 time-locations.

       Returns:
        "x"

       Example:
        say XtraDateGetDaysBetween("20050104", "20050105")
        /* This should put "1" on the screen */
        say XtraDateGetDaysBetween("20050104", "2300", "20050105", "0100")
        /* This should put "0" on the screen (cause its only 2 hours) */

       --------------------------------------
        v0.42+ - XtraDateGetMonthName(Month)
       --------------------------------------
       This gets the current month name for the specified month. XtraRexx
        automatically uses english names, but you may specify different ones
        using XtraDateSetMonthNames().

       Returns:
        "", if invalid month specified
        otherwise the month name e.g. "January"

       Example:
        say XtraDateGetMonthName("1")
        /* This should put "January" on the screen */

       -----------------------------------------------
        v0.42+ - XtraDateSetMonthNames(MonthNameList)
       -----------------------------------------------
       This is used to set all month names. They need to be separated by '|'.

       Returns:
        none

       Example:
        call XtraDateSetMonthNames("Januar|Februar|M„rz|April|Mai|Juni|Juli|August|September|August|Oktober|November|Dezember"
        /* This sets German month names */

       -------------------------------------------
        v0.42+ - XtraDateGetMonthShortName(Month)
       -------------------------------------------
       This gets the current short month name for the specified month. XtraRexx
        automatically uses english names, but you may specify different ones
        using XtraDateSetMonthShortNames().

       Returns:
        "", if invalid month specified
        otherwise the month name e.g. "Jan"

       Example:
        say XtraDateGetMonthShortName("1")
        /* This should put "Jan" on the screen */

       ----------------------------------------------------
        v0.42+ - XtraDateSetMonthShortNames(MonthNameList)
       ----------------------------------------------------
       This is used to set all short month names. They need to be separated by
        '|'.

       Returns:
        none

       Example:
        call XtraDateSetMonthShortNames("Jan|Feb|M„r|Apr|Mai|Jun|Jul|Aug|Sep|Aug|Okt|Nov|Dez"
        /* This sets German month names */

       ----------------------------------
        v0.42+ - XtraDateGetDayName(Day)
       ----------------------------------
       This gets the current day name for the specified month. XtraRexx
        automatically uses english names, but you may specify different ones
        using XtraDateSetDayNames().

        Note: This uses the day-type (1-7) as input *not* the day-number.

       Returns:
        "", if invalid day-type specified
        otherwise the day name e.g. "Monday"

       Example:
        say XtraDateGetDayName("1")
        /* This should put "Monday" on the screen */

       ---------------------------------------------
        v0.42+ - XtraDateSetDayNames(MonthNameList)
       ---------------------------------------------
       This is used to set all day names. They need to be separated by
        '|'.

       Returns:
        none

       Example:
        call XtraDateSetDayNames("Montag|Dienstag|Mittwoch|Donnerstag|Freitag|Samstag|Sonntag"
        /* This sets German day names */

       ---------------------------------------
        v0.42+ - XtraDateGetDayShortName(Day)
       ---------------------------------------
       This gets the current short day name for the specified month. XtraRexx
        automatically uses english names, but you may specify different ones
        using XtraDateSetDayShortNames().

        Note: This uses the day-type (1-7) as input *not* the day-number.

       Returns:
        "", if invalid day-type specified
        otherwise the day name e.g. "Mon"

       Example:
        say XtraDateGetDayShortName("1")
        /* This should put "Mon" on the screen */

       --------------------------------------------------
        v0.42+ - XtraDateSetDayShortNames(MonthNameList)
       --------------------------------------------------
       This is used to set all short day names. They need to be separated by
        '|'.

       Returns:
        none

       Example:
        call XtraDateSetDayShortNames("Mo|Di|Mi|Do|Fr|Sa|So"
        /* This sets German day names */

       -------------------------------------
        v0.42+ - XtraDateFormat(Date, Type)
       -------------------------------------
       This is used to get a displayable string out of a given date.
       Type is a string that defines the output format.

       Returns:
        Output format is listed after the output type:
          ""/"NORMAL"  : "1.1.2005"
          "ZEROED"     : "01.01.2005"
          "SHORT"      : "1.1.05"
          "SHORTZEROED": "01.01.05"
          "LETTER"     : "1. January 2005"
          "SHORTLETTER": "1. Jan 2005"
          (v0.44+)
          "UNIX"       : "1104537600" (seconds since 1.1.1970)
                         If a date out of UNIX range is passed, 0 is returned.

       Example:
        say XtraDateFormat("20050104", "")
        /* This should put "4.1.2005" on the screen */

       ---------------------------------
        v0.42+ - XtraDateValidate(Date)
       ---------------------------------
       This is used to validate a given date. Note that this is meant for
        usage on the internal format only e.g. checking HTML-POST replies etc.

       Returns:
        "VALID", if date is valid
        "INVALID", if date is invalid

       Example:
        say XtraDateValidate("20050104")
        /* This should put "VALID" on the screen */
        say XtraDateValidate("20050100")
        /* This should put "INVALID" on the screen */

       -----------------------------------------
        v0.44+ - XtraDateGetFromUnix(Unix-Date)
       -----------------------------------------
       This is used to convert a unix-styled date (seconds counting from first
        January 1970) into a XtraRexx date/time bundle. Date is replied by this
        function. You may use XtraTimeGetFromUnix() later to get the time part
        of the result. You will need to ommit the "Unix-Date" parameter in that
        case.

       You may also call XtraTimeGetFromUnix() first and use this call
        afterwards to get the date part.

       Note: Converting TO unix is possible using XtraDateFormat() and
              XtraTimeFormat().

       Returns:
        "DDDDDDDD", if Unix-Date contained a valid number
        "", if Unix-Date invalid (or Unix-Date got ommited w/o calling
             XtraTimeGetFromUnix() first)

       Example:
        say XtraDateGetFromUnix(0)
        /* This should put "19700101" on the screen */

       -------------------------------
        v0.42+ - XtraTimeGetCurrent()
       -------------------------------
       This simply gets the current time.

       Returns:
        "HHMM"

       Example:
        say XtraTimeGetCurrent()
        /* This should put the current time in our internal format on the screen */

       ------------------------------------
        v0.42+ - XtraTimeNormalize(String)
       ------------------------------------
       This is used, when a user inputs a time and you want to analyse and
        extract his input. It may also be used for getting the time out of
        SysFileTree() data and so on.

       The method used is quite complex and almost gets any time format that
        is possible. It's also intelligent in a way that you may simply specify
        just a minute and XtraRexx will get the hour for it.

       e.g. on 14:04
            specifying "5" will reply "1405"
            specifying "4" will reply "1504"

       It's also possible to tell XtraRexx to walk backwards using "-".

       e.g. on 14:04:
            specifying "5-" will reply "1305"
            specifying "4-" will reply "1304"

       Specifying an empty string will reply the current time.

       Returns:
        "HHMM"
        or "", if time invalid (or not extractable)

       Example:
        say XtraTimeNormalize("13 20")
        /* This should put "1320" on the screen */

       ------------------------------------------------
        v0.42+ - XtraTimeAddMinutes(Time, MinuteCount)
       ------------------------------------------------
       This is used, when adding minutes to a time.

       Returns:
        "HHMM"

       Example:
        say XtraTimeAddMinutes("1404", 5)
        /* This should put "1409" on the screen */

       ------------------------------------------------
        v0.42+ - XtraTimeSubMinutes(Time, MinuteCount)
       ------------------------------------------------
       This is used, when subtracting minutes from a time.

       Returns:
        "HHMM"

       Example:
        say XtraTimeSubMinutes("1404", 5)
        /* This should put "1359" on the screen */

       --------------------------------------------
        v0.42+ - XtraTimeAddHours(Time, HourCount)
       --------------------------------------------
       This is used, when adding hours to a time.

       Returns:
        "HHMM"

       Example:
        say XtraTimeAddHours("1404", 5)
        /* This should put "1904" on the screen */

       ----------------------------------------------
        v0.42+ - XtraTimeSubMinutes(Time, HourCount)
       ----------------------------------------------
       This is used, when subtracting hours from a time.

       Returns:
        "HHMM"

       Example:
        say XtraTimeSubHours("1404", 5)
        /* This should put "0904" on the screen */

       ----------------------------------------------------------------------
        v0.42+ - XtraTimeGetMinutesBetween(Time, [Date,] 2ndTime [,2ndDate])
       ----------------------------------------------------------------------
       This gets the total amount of minutes inbetween 2 times. One may also
        specify an additional Date for those times to be more accurate. This is
        meant for getting the exact days and minutes between 2 time-locations.

       Returns:
        "x"

       Example:
        say XtraTimeGetMinutesBetween("1409", "1422")
        /* This should put "13" on the screen */
        say XtraTimeGetMinutesBetween("20050104", "2300", "20050105", "0100")
        /* This should put "120" on the screen */

       -------------------------------------
        v0.42+ - XtraTimeFormat(Time, Type)
       -------------------------------------
       This is used to get a displayable string out of a given time.
       Type is a string that defines the output format.

       Returns:
        Output format is listed after the output type:
          ""/"NORMAL"  : "1:03"
          "ZEROED"     : "01:03"
          "POINTED"    : "1.03"
          "POINTEDZERO": "01.03"
          (v0.44+)
          "UNIX"       : "3780" (seconds since 0:00)

       Example:
        say XtraTimeFormat("1404", "")
        /* This should put "14:04" on the screen */

       ---------------------------------
        v0.42+ - XtraTimeValidate(Time)
       ---------------------------------
       This is used to validate a given time. Note that this is meant for
        usage on the internal format only e.g. checking HTML-POST replies etc.

       Returns:
        "VALID", if date is valid
        "INVALID", if date is invalid

       Example:
        say XtraDateValidate("1404")
        /* This should put "VALID" on the screen */
        say XtraDateValidate("2400")
        /* This should put "INVALID" on the screen */

       ---------------------------------------------
        v0.42+ - XtraTimeSetDurationNames(NameList)
       ---------------------------------------------
       This is used to set all duration names. They need to be separated by '|'.
        XtraRexx defaults to english and uses "days|day|hours|hour|minutes|minute".

       Returns:
        none

       Example:
        call XtraTimeSetDurationNames "Tage|Tag|Stunden|Stunde|Minuten|Minute"
        /* This sets German names */

       --------------------------------------------------
        v0.42+ - XtraTimeFormatDuration([Days,] Minutes)
       --------------------------------------------------
       This is used to get a displayable string out of a given duration.
        You may specify a day-count optionally. The output will only contain
        data, that is not equal 0.

        Note: This is meant to be used after the XtraDateGetDaysBetween()/
               XtraTimeGetMinutesBetween()-functions.

       Returns:
        none

       Example:
        say XtraTimeFormatDuration(0, 60)
        /* This should put "1 hour" on the screen */
        say XtraTimeFormatDuration(60)
        /* This should put "1 hour" on the screen */
        say XtraTimeFormatDuration(1, 59)
        /* This should put "1 day, 59 minutes" on the screen */
        say XtraTimeFormatDuration(1, 61)
        /* This should put "1 day, 1 hour, 1 minute" on the screen */

       -----------------------------------------
        v0.44+ - XtraTimeGetFromUnix(Unix-Date)
       -----------------------------------------
       This is used to convert a unix-styled date (seconds counting from first
        January 1970) into a XtraRexx date/time bundle. Time is replied by this
        function. You may use XtraDateGetFromUnix() later to get the date part
        of the result. You will need to ommit the "Unix-Date" parameter in that
        case.

       You may also call XtraDateGetFromUnix() first and use this call
        afterwards to get the time part.

       Note: Converting TO unix is possible using XtraDateFormat() and
              XtraTimeFormat().

       Returns:
        "TTTT", if Unix-Date contained a valid number
        "", if Unix-Date invalid (or Unix-Date got ommited w/o calling
             XtraDateGetFromUnix() first)

       Example:
        say XtraTimeGetFromUnix(0)
        /* This should put "0000" on the screen */

  =========================
  | FILE ACCESS FUNCTIONS |
  =========================

       This specifies my own set of file access functions. The built-in STREAM
        CHARIN/CHAROUT/LINEIN/LINEOUT functions are just not enough for serious
        work.

       I like FileRexx somehow, but this library is oriented around C style
        programming and I don't like having handles in my REXX scripts. If
        you like handle usage, I would say go for FileRexx instead.
        If you prefer the original REXX design, use mine instead. My routines
        need the filename specified on every call. I don't know what's the
        point in using file handles is. If you use them, you need to convert
        them from ASCII into binary form each time and that will take even a
        little longer than looking up a filename.

       Some routines of mine contain a "delay"-value. That's an amount of
        milliseconds till the call will return sharing/permission errors to the
        caller. This is meant for sharing files between multiple REXX scripts.
        In that way, one is able to delete a file, even if it's currently read
        my another process and closed after some milliseconds. The default is
        always 0 (immediate return). There is XtraFileSetDelayDefault() that is
        able to change that default for ease of use. Most functions wait around
        at least 40-50 milliseconds till they retry a command, so specifying
        less than that will result in no change of action.

       My READ/WRITE/SEEK functions REQUIRE one to open the file explicitly
        first. Built-In functions under REXX don't have this requirement.
        Also my file support and the built-in REXX support are not connected,
        so you may not use built-in and XtraRexx calls on the same files. This
        is only possible, if you close them inbetween.

       READ functions also initiate an internal cache of 4k. There is a maximum
        of 10 caches at the same time and they remember, how often each was
        used. So if the functions require another cache, where 10 caches are
        already active, XtraRexx will kick the least used cache.

       Offsets are still 1-based (like in built-in REXX). So the absolutely
        first character in a file is at offset 1. If you specify an offset as
        being 0, XtraRexx will raise an INVALID CALL REXX exit aborting the
        REXX script immediately.

       --------------------------------------------
        v0.43+ - XtraSetDefaultDelay(delaydefault)
       --------------------------------------------
       This is used to change the default delay of all file/directory functions.
        This shall be used in e.g. CGI scripts, that need this capability on
        every call. You may still override the value by mentioning it on the
        specific function. The amount is milliseconds.

       Returns:
        none

       Example:
        call XtraSetDefaultDelay 5

       -------------------------------------------------------------------
        v0.43+ - XtraFileCopy(source, destination, [option], [copydelay])
       -------------------------------------------------------------------
       This is used to copy a file/directory. You may specify option as being
        "APPEND" to make this command append the contents of source to
        destination. You may also specify "NOOVERWRITE", so that the command
        will fail, if destination already exists. Option is not case-sensitive.

       You may also specify an optional copydelay, so that this function will
        wait some time till the copy succeeds. Specifiying CopyDelay requires
        one to also specify an Option - anyway, you may specify an empty string
        as Option.

       Returns:
        "", if successful
        "NOTFOUND", if source not found or destination invalid
        "ERROR", if any other error condition occured

       Example:
        call XtraFileCopy "testfile", "testfile2"
        /* This would copy testfile into testfile2 */

       -------------------------------------------------------
        v0.43+ - XtraFileMove(FileName, NewName, [movedelay])
       -------------------------------------------------------
       This is used to move a file/directory. You may specify an optional
        MoveDelay, so that this function will wait some time till the move
        succeeds. Moves may only be done on the same drive-letter. If you
        specify 2 different drive letters, the function will fail.

       If you include a path in FileName and you do not in NewName, XtraRexx
        will rename the file to the given NewName, BUT put it into your CURRENT
        directory. If you want to rename a file/directory without specifying
        the path twice, use XtraFileRename().

       XtraRexx will check if the given NewName is a currently existing path.
        If that's the case, it will append the original file/directoryname, so
        that you don't need to specify it explicitly.

       Returns:
        "", if successful
        "NOTFOUND", if FileName not found
        "ERROR", if any other error condition occured

       Example:
        call XtraFileMove "testfile", "testfile2"
        /* This would rename testfile to testfile2 */
        call XtraFileMove "C:\testfile", "testfile2"
        /* This would move C:\testfile into the current directory and rename */
        /*  it to testfile2. */
        call XtraFileMove "TestDirectory", "C:\TestDirectory2"
        /* This would move TestDirectory from current directory into C:\ and */
        /*  rename it to TestDirectory2 */
        call XtraFileMove "TestDirectory", "C:\"
        /* This would move TestDirectory from current directory into C:\ w/o */
        /*  changing its name */

       --------------------------------------------------
        v0.43+ - XtraFileDelete(filename, [deletedelay])
       --------------------------------------------------
       This is used to delete a file. You may also specify deletedelay, so
        XtraRexx will wait a while for the delete to succeed. The filename is
        not allowed to contain wildcards.

       Returns:
        "", if delete succeeded
        "NOTFOUND", if file was not found
        "DENIED", if delete was denied through sharing or permission problems

       Example:
        say XtraFileDelete("testfile")
        /* This would delete testfile */

       -----------------------------------------------------------
        v0.43+ - XtraFileRename(FileName, NewName, [renamedelay])
       -----------------------------------------------------------
       This is used to rename a file/directory. You may specify an optional
        MoveDelay, so that this function will wait some time till the move
        succeeds. Moves may only be done on the same drive-letter. If you
        specify 2 different drive letters, the function will fail.

       If you include a path in FileName and you do not in NewName, XtraRexx
        will rename the file to the given NewName *AND* leave it in its
        previous directory. XtraFileMove() behaves differently in that
        situation.

       If the file/directoryname is ommited in NewName, XtraRexx will abort
        this function with a reply of "ERROR". You may use this sort of calling
        using XtraFileMove().

       This function is supposed to work as the "ren" command-line command.

       Returns:
        "", if successful
        "NOTFOUND", if FileName not found
        "ERROR", if any other error condition occured

       Example:
        call XtraFileRename "testfile", "testfile2"
        /* This would rename testfile to testfile2 */
        call XtraFileRename "C:\testfile", "testfile2"
        /* This would rename C:\testfile into C:\testfile2 */
        call XtraFileRename "TestDirectory", "C:\"
        /* This would FAIL, because it doesn't specify a valid file/directory- */
        /*  name as being NewName - use XtraFileMove() in this case */

       ------------------------------------
        v0.43+ - XtraFileGetSize(filename)
       ------------------------------------
       This is used to get the size of a file. The file does NOT need to be
        opened prior this call.

       Returns:
        "-1", if file was not found
        otherwise the filesize is returned as a decimal number

       Example:
        say XtraFileGetSize("testfile")
        /* This would put the filesize of testfile on the screen */

       -----------------------------------
        v0.43+ - XtraFileExists(filename)
       -----------------------------------
       This is used to find out, if a file actually exists. The file does NOT
        need to be opened prior this call.

       Returns:
        0, if file was not found
        1, if the file was found

       Example:
        say XtraFileExists("testfile")
        /* This would tell one if the file testfile exists */

       ------------------------------------
        v0.43+ - XtraFileGetTimestamp(filename)
       ------------------------------------
       This is used to get the timestamp of a file. The file does NOT need to
        be opened prior this call. It will return the last-modified stamp.
        The returned format is like the reply of the corresponding STREAM
        function. Anyway, I added 2 additional year digits to it for Y2K
        support.

       When using XtraTimeNormalize() on the time part, you will have to cut
        the last 3 characters (seconds), otherwise you won't get results.

       Returns:
        "MM-DD-YYYY  HH:MM:SS", if file was found
        "", if file was not found

       Example:
        say XtraFileGetTimestamp("testfile")
        /* This would put the timestamp of testfile on the screen */

       ------------------------------------
        v0.43+ - XtraFileGetDate(filename)
       ------------------------------------
       This is used to get the date part of the timestamp of a file.
        It works the same as XtraFileGetTimestamp, but delivers date only. Also
        it uses the normalized XtraDate format, which eases comparsion between
        dates.

       You may also normalize the first word of the XtraFileGetTimestamp to get
        the same results.

       Returns:
        "YYYYMMDD", if file was found
        "", if file was not found

       Example:
        say XtraFileGetDate("testfile")
        /* This would put the normalized date of testfile on the screen */

       ------------------------------------
        v0.43+ - XtraFileGetTime(filename)
       ------------------------------------
       This is used to get the time part of the timestamp of a file.
        It works the same as XtraFileGetTimestamp, but delivers time only. Also
        it uses the normalized XtraTime format, which eases comparsion between
        time-stamps.

       You may also normalize the second word of the XtraFileGetTimestamp to
        get the same results.

       Returns:
        "HHMM", if file was found
        "", if file was not found

       Example:
        say XtraFileGetTime("testfile")
        /* This would put the normalized time of testfile on the screen */

       ----------------------------------------------------------
        v0.43+ - XtraFileOpen(filename, [openmode], [opendelay])
       ----------------------------------------------------------
       This is used to open a file for further XtraFile functions to work.
       OpenMode and OpenDelay may be ommited.

       OpenMode is C-compatible, but with some enhancements.
        If openmode is ommited, XtraRexx will assume "r+" as mode.
        The 1st R/W field specifies opening mode, the 2nd field is sharing.

        "r"   - R   -   W - opens the file
        "w"   -   W - R   - creates/truncates the file
        "a"   -   W - R   - opens the file and seeks to end-of-file
        "r+"  - R/W -     - opens the file
        "w+"  - R/W -     - creates/truncates the file
        "a+"  - R/W -     - opens the file and seeks to end-of-file
        "rs"  - R   - R/W - opens the file
        "ws"  -   W - R/W - creates/truncates the file
        "as"  -   W - R/W - opens the file and seeks to end-of-file
        "r+s" - R/W - R/W - opens the file
        "w+s" - R/W - R/W - creates/truncates the file
        "a+s" - R/W - R/W - opens the file and seeks to end-of-file
        "rd"  - R   - R   - opens the file
        "wd"  -   W -   W - creates/truncates the file
        "ad"  -   W -   W - opens the file and seeks to end-of-file

        "!" means, if access fails - abort REXX script using INVALID CALL
             This is supposed to get used when file access is critical and one
             doesn't want to put in any special code for exiting.

        So the additions: "s" will share the file in any mode
                      and "d" will deny the opposite action of what is done
        In that way, every sharing/opening combination is possible.
        Specifying "d" and "+" option is quite useless.
        Please note that you may specify those options in any order.

        OpenDelay is an amount of milliseconds, that XtraRexx will wait till
         the file becomes available. XtraRexx will try every 50 milliseconds
         for the open to succeed. Ommiting will specify 0 as delay, so XtraRexx
         will only try to open the file one time.

        Please note that OpenDelay will be ignored, if the file could not be
         found. OpenDelay is only used on permission/sharing errors. If the
         file is not found, the function will immediately return.

        XtraFileGetLine()/XtraFilePutLine() will default to CR/LF reading. You
         may change this per file using XtraFileSetEOL(). The method is not
         specified on XtraFileOpen(), because one may want to change the method
         in the middle of reading a file or even controlling a device (modem).

       Returns:
        "", if open succeeded
        "NOTFOUND", if file was not found
        "DENIED", if open was denied through sharing or permission problems

       Example:
        say XtraFileOpen("testfile", "r+s", 2000)
        /* This would try to open the file for read&write using full sharing */
        /*  and it would wait for at most 2 seconds till the open succeeds.  */

       ------------------------------------------------
        v0.43+ - XtraFileSeek(filename, [newposition])
       ------------------------------------------------
       This is used to get and/or set the current position within a previously
        opened file. NewPosition may be ommited. In that case, XtraFileSeek
        will get the current position within the opened file only.

        Position is always 1-based, which means position 1 is the first char.
         Specifying newposition as being 0 will result in an INVALID CALL REXX
         exit.

        NewPosition may also contain a leading orientation character.
         "=" means the offset is relative to the beginning of the file
         "<" means the offset is relative to the end of the file
         "+" means the offset is relative to the current position
         "-" means the offset is relative backwards to the current position
         ">" means the same as "="

        XtraRexx will default to "=" orientation.

       Returns:
        "-1", if file was not previously opened or seek error
        otherwise the fileposition is returned as a decimal number

       Example:
        say XtraFileSeek("testfile")
        /* This would put the current position within testfile on the screen */
        say XtraFileSeek("testfile", 5)
        /* This would seek to the 5th character within testfile and put "5" */
        /*  on the screen */

       ----------------------------------
        v0.43+ - XtraFileIsEOF(filename)
       ----------------------------------
       This is used to find out, if we are beyond the end-of-file. It requires
        a filename of a previously opened file.

       Returns:
        "1", if we are at the end-of-file (or file not opened)
        "0", if we are not

       Example:
        say XtraFileIsEOF("testfile")

       ------------------------------------------------
        v0.43+ - XtraFileGetLine(filename, [position])
       ------------------------------------------------
       This is used to get an ASCII line from a previously opened file.
        Position specifies the offset to the beginning of the line. Please
        check "XtraFileSeek" for the exact options. If Position is ommited,
        XtraRexx assumes that the line is read from the current position.

        Please note that this function generates an internal filebuffer of
         4k on the first call of a new offset. Also this call is limited to a
         total length of 1280 characters per line. If the line contains more
         characters, XtraRexx will return those 1280 first and further calls
         will receive the remaining ones. It's best to have lines smaller than
         256 bytes, because otherwise XtraRexx needs to allocate an extra
         memory buffer to hold the data, which will result in a time penalty.

       Returns:
        will reply the actual line without the trailing CR/LF
        will reply an empty string, if the file was not opened previously or
         another error occured.

        If EOF is discovered before CR/LF, XtraRexx will reply no string.
         Although further calls to XtraFileGetLine will try to read more data.
         You are supposed to use XtraFileIsEOF(), if you want to distingish
         EOF from an empty string within the file.

        You may change "CR/LF" to "CR only searching" using XtraFileSetEOL().

       Example:
        say XtraFileGetLine("testfile", 1)
        /* This would put the first ASCII line of testfile on the screen */

       --------------------------------------------------------
        v0.43+ - XtraFilePutLine(filename, string, [position])
       --------------------------------------------------------
       This is used to put an ASCII line into a previously opened file.
        Position specifies the offset to the beginning of the line. Please
        check "XtraFileSeek" for the exact options. If Position is ommited,
        XtraRexx assumes that the line is put to the current position.

        Note: This call always appends CR/LF to the end of the string. If you
               don't want this to happen, use XtraFilePutChar.
               You may change "CR/LF" to "CR only output" using XtraFileSetEOL()

       Returns:
        "0", if an error occured
        "1", if operation succeeded

       Example:
        say XtraFilePutLine("testfile", "This is the first line", 1)
        /* This would put the specified line at the beginning of testfile */

       ---------------------------------------------------
        v0.43+ - XtraFileSetEOL(filename, EOL-characters)
       ---------------------------------------------------
       This is used to tell XtraFile-functions, what to look for as being
        end-of-line.

       There are currently only 2 possibilities:
        "CR", means only look for CR (for e.g. *nix files)
        "CRLF", means look for CR/LF pair (this is the standard setting)

       Note: Setting this to "CR" when reading out a CR/LF file using
              XtraFileGetLine(), will never give results via XtraFileIsEOF().
              So make sure that you are using the right EOL setting.

             Also using "CRLF" when reading a *nix file, XtraRexx will never
              give any replies on XtraFileGetLine() calls.

       -----------------------------------------------------------
        v0.43+ - XtraFileGetChars(filename, [length], [position])
       -----------------------------------------------------------
       This is used to get a number of characters from a previously opened
        file. Length may be ommited and is then assumed to be "1".
        Position specifies the offset to the beginning of the line. Please
        check "XtraFileSeek" for the exact options. If Position is ommited,
        XtraRexx assumes that the line is read from the current position.

       It's best to get 255 chars at most, because otherwise XtraRexx needs to
         allocate an extra memory buffer to hold the data, which will result in
         a time penalty. Anyway, XtraRexx is not limited to any maximum length.
         If XtraRexx can't allocate a buffer for the data, it will abort
         execution using INVALID CALL REXX exit.

       If Length is specified as being "0" and position is set, the function
        will work like a call to XtraFileSeek().

       Returns:
        will reply the requested string
        will reply an empty string, if the file was not opened previously or
         another error occured.

        If EOF is discovered before the requested length is fulfilled, XtraRexx
         will reply a smaller number of characters and still succeed.

       Example:
        say XtraFileGetChar("testfile", 2, 1)
        /* This would get the first 2 characters from testfile */
        say XtraFileGetChar("testfile", 2, 3)
        /* This would get the 2 characters from offset 3 within testfile */

       ---------------------------------------------------------
        v0.43+ - XtraFilePutChars(filename, string, [position])
       ---------------------------------------------------------
       This is used to put a string into a previously opened file.
        Position specifies the offset to the beginning of the line. Please
        check "XtraFileSeek" for the exact options. If Position is ommited,
        XtraRexx assumes that the line is put to the current position.

       Returns:
        "0", if an error occured
        "1", if operation succeeded

       Example:
        say XtraFilePutChar("testfile", "This is the first line", 1)
        /* This would put the specified chars at the beginning of testfile */

       ------------------------------------------------------------------------------
        v0.43+ - XtraFileGetLines(filename, stem-variable, [count], [Boundary-Line])
       ------------------------------------------------------------------------------
       Due speed penalties imposed by REXX on extension DLL calls, I
        implemented these multiple line processing routine. It works the same
        as XtraFileGetLine(), but is able to read in multiple lines into a stem
        variable. Also the calling options are quite different.

       An optional seek is not implemented here. Please use XtraFileSeek(), if
        you want to change the position within the file.

       If count and boundary-line are ommited, XtraRexx will read everything
        from current position till EOF into the stem-variable.

       If count is specified, XtraRexx will read UP TO "count" lines into the
        stem-variable. Specifying 0 is like ommiting the parameter and will
        read everything till EOF.

       If Boundary-Line is specified, XtraRexx will compare this string to each
        read line. If the read line BEGINS with boundary-line, it will stop
        reading. It will still put that line into the stem as well.

       Specifying Boundary-Line == "" will search for an EMPTY line.

       You are supposed to use this routine on big file data, because it will
        work much faster. Even faster than native LINEIN() REXX code!
        If you use XtraFileGetLine(), even a loop containing LINEIN() will work
        much faster on larger files. This is not because of XtraRexx!

       Returns:
        will reply "1", if any lines were read
        will reply "0", if no lines were read (EOF or any error!)

        You may change "CR/LF" to "CR only searching" using XtraFileSetEOL().

       Example:
        call XtraFileGetLines "testfile", "testlines."
        say testlines.0
        say testlines.1
        /* This would put the total line count and the first ASCII line onto */
        /*  the screen */

       ----------------------------------------------------
        v0.43+ - XtraFilePutLines(filename, stem-variable)
       ----------------------------------------------------
       Due speed penalties imposed by REXX on extension DLL calls, I
        implemented these multiple line processing routine. It works the same
        as XtraFilePutLine(), but is able to write a whole stem into a file.

       An optional seek is not implemented here. Please use XtraFileSeek(), if
        you want to change the position within the file.

       Returns:
        will reply "1", if stem successfully written
        will reply "0", if an error occured

        You may change "CR/LF" to "CR only" using XtraFileSetEOL().

       Example:
        testlines.0 = 1
        testlines.1 = "first line"
        call XtraFilePutLines "testfile", "testlines."
        /* This would write "first line" into testfile */

       ---------------------------------------------------------------
        v0.43+ - XtraFileSkipLines(filename, line-content, [position]
       ---------------------------------------------------------------
       This function skips all lines in the given filename, that match with
        the line-content parameter. This match is case-sensitive and the line
        must exactly match.

       ffs: look at Dynamic Filter/2 source

       Returns:
        will reply "1", if any lines were skipped
        will reply "0", if no lines were skipped

       Example:
        call XtraFileSkipLines "testfile", "Skip this"
        /* This would skip all lines containg "Skip this" */

       -------------------------------------------------------------------
        v0.43+ - XtraFileSkipLinesTill(filename, line-content, [position]
       -------------------------------------------------------------------
       This function skips all lines in the given filename TILL the given
        line-content is found. Line-content is matched case-sensitive BUT the
        match does only require the line length to be equal or larger than the
        line-content parameter.

       If a match is found, XtraRexx will seek to the line matching
        line-content.

       ffs: look at Dynamic Filter/2 source

       Returns:
        will reply "1", if line-content was found
        will reply "0", if EOF encountered

       Example:
        call XtraFileSkipLines "testfile", "Skip this"
        /* This would skip all lines till a line beginning with "Skip this" */
        /*  is found. In that case, file-pointer will point to "Skip this"  */
        /*  and the function would return "1" */

       ----------------------------------
        v0.43+ - XtraFileClose(filename)
       ----------------------------------
       This is used to close a previously opened file

       Returns:
        "" in any case

       Example:
        call XtraFileClose "testfile"
        /* This would close testfile */

       ----------------------------------
        v0.43+ - XtraDirCreate(pathname)
       ----------------------------------
       This is used to create a directory.

       Returns:
        "", if successful
        "EXISTS", if directory already exists
        "ERROR", if any error condition occured

       Example:
        say XtraDirCreate("C:\TestPath")
        /* This would create "TestPath" under C:\ */

       -------------------------------------------------
        v0.43+ - XtraDirDelete(pathname, [removedelay])
       -------------------------------------------------
       This is used to remove a directory. You may optionally specify a delay,
        so that this function will wait on permission/sharing errors.

       Returns:
        "", if successful
        "DENIED", if permission/sharing error occured
        "NOTFOUND", if base directory was not found or other error condition

       Example:
        say XtraDirDelete("C:\TestPath")
        /* This would remove "TestPath" from C:\ */

  ===========
  | CONTACT |
  ===========

        There were several ways to contact me.
        Just try 'jimi@klinikum-konstanz.de'.
         Please DO NOT POST THIS E-MAIL TO USENET NOR THE WEB!!!

        My official homepage is at: https://www.ecomstation.ru/kiewitzsoft/

        I'm dedicating XtraRexx to my father.