@DATABASE GatewayLibrary
@$VER: V 19.0 (15.03.2000)
@(C) © 1998-2000 by Michaela Prüß, All Rights Reserved
@AUTHOR Michaela Prüß
@MASTER Development/Gateway5
@WORDWRAP

@REMARK Created with Guided by Linus McCabe


@NODE "MAIN" "Gateway.Library Funktionen"
@NEXT README
@SMARTWRAP
{LINDENT 3}
     Gateway.Library V 18.1.x (20.10.1999)

    @{" Ganz wichtig " LINK README}  Vor Benutzung lesen!
    @{" Copyright    " LINK COPYRIGHT}  Copyright, Nutzung!
    @{" Name Gateway " LINK GATEWAY}  Gateway-5 ist nicht Gateway 2000!

     Funktionen:

    @{" GateRequest   " LINK GateRequest}  Einfacher Requester

    @{" trim          " LINK trim}  Leerzeichen entfernen
    @{" trim_cr       " LINK trim_cr}  Leerzeichen und CR/LF entfernen
    @{" rtrim         " LINK rtrim}  Rechtsbündige Leerzeichen entfernen
    @{" trim_includes " LINK trim_includes}  trim für Include-File-Namen
    @{" mail_trim     " LINK mail_trim}  trim für eMail

    @{" set           " LINK set}  String auf feste Länge
    @{" lset          " LINK lset}  String auf feste Länge setzen
    @{" lsetmin       " LINK lsetmin}  String auf eine Mindestlänge setzen

    @{" instr         " LINK instr}  Teilstring suchen
    @{" instr_pat     " LINK instr_pat}  Teilstring mit Pattern suchen
    @{" midstr        " LINK midstr}  Teilstring ausschneiden

    @{" newstr        " LINK newstr}  Teilstring im Hauptstring ersetzen
    @{" wordwrp       " LINK wordwrp}  Wordumbruch Zeilenende
    @{" kill_ansi     " LINK kill_ansi}  Ansicodes entfernen

    @{" fn_splitt     " LINK fn_splitt}  Vollen Datei u. Pfadnamen aufsplitten
    @{" fn_build      " LINK fn_build}  Neuen Dateinamen bilden

    @{" time_to_zahl  " LINK time_to_zahl}  Zeit in Zahl wandeln
    @{" date_to_zahl  " LINK date_to_zahl}  Datum in Zahl wandeln
    @{" date_to_day   " LINK date_to_day}  Tag im Jahr (ca.) berechnen
    @{" addval        " LINK addval}  Zahlenstring und Zahl zu neuem String

    @{" ltofa         " LINK ltofa}  Formatierte Zahlausgabe 

    @{" string        " LINK string}  String mit Zeichen füllen
    @{" newer         " LINK newer}  Datum+Zeit neuer als 2.Paar?
    @{" upstr         " LINK upstr}  String in Großbuchstaben
    @{" lowstr        " LINK lowstr}  String in Kleinbuchstaben

    @{" StrCaseCmp    " LINK StrCaseCmp}  Strings vergleichen
    @{" strdup        " LINK strdup}  Dupliziere String 

    @{" swapmem       " LINK swapmem}  Speicherbereiche vertauschen
    @{" memncmp       " LINK memncmp}  Speicherbereiche vergleichen

    @{" index         " LINK indexfkt}  Suchen eines Zeichens im String

@ENDNODE
@NODE "README" "Wichtig!!!"
@TOC MAIN
@NEXT MAIN
@PREV COPYRIGHT
@SMARTWRAP
{LINDENT 3}
@{U} "Wichtig! Unbedingt zuerst lesen" @{UU}@{LINDENT 6}

Die Gateway.Library ist eine Sammlung von (meist String-)Funktionen
die im Gateway-BBS-System verwendung finden. Die Library entstand erst
lange nach dem Kernprogramm das über Jahre gewachsen ist. Die Funktionen
die sich jetzt in der Library befinden waren im Programm verstreut und
sind teilweise mit erheblichen Zeitabständen entstanden. Daher sind die
Variablennamen nicht einheitlich und manche Funktion würde heute sicher-
lich anders realisiert. Fakt ist, das Programm nutzt die meisten der
Funktionen sehr stark und das an vielen verschiedenen Stellen. Dadurch
ist es kaum möglich, eine Funktion in der Schnittstelle zu verändern.

Neben diesen alten Routinen finden sich noch Stringsfunktionen, die
allgemein bekannt sein dürften, wie z.B. 'strdup'. Diese Funktionen
werden von Gateway selbst oder von den Gateway-Tools benutzt. Da sie
im vbcc-Compiler nicht vorhanden waren habe ich sie in der Library
untergebracht. Ich bin drauf und dran, die allgemeinen C-Standard-
Stringfunktionen komplett in die Library zu verlegen. Man muß sie
ja nicht nutzen, könnte es jedoch und ich habe später bei den geplanten
Crosscompilaten keine Probleme. Mal schauen.

Gateway verwendet heute eine Link-Library mit sehr vielen, oft recht
komplexen Funktionen, die zu sehr großen Teilen Amiga-DOS direkt oder
indirekt benötigen. Da einige dieser Funktionen in den PMM-Programmen
benutzt werden und diese Funktionen teilweise wiederum die Gateway.Library
benötigen, geht hiermit erstmals eine Gateway.Library ohne das BBS-System
heraus.
Und da ich es ausgesprochen blöd finde, wenn eine Library undokumentiert
im System gammelt, während irgendjemand vielleicht irgendwas davon ge-
brauchen könnte, habe ich hier eine Dokumentation der Library beigelegt.
Auch wenn es kaum anzunehmen ist, das sich viele Leute dafür interessieren.

Etliche Funktionen lassen sich auch mit einem sprintf oder ähnlichen
Befehlen lösen. Das hat nur den Nachteil, das meist eine Buffervariable
notwendig ist und es sich bei diesen Funktionen um Funktionen mit varargs
handelt was alleine schon langsam genug ist. Die Formaterkennung und das
nachfolge Einsetzen der Variable in den String sind garantiert auch nochmals
langsamer als die Funktionen der Library. Von unnötigen CPU-Belastungen mal
ganz zu schweigen. Während das im einfachen Benutzerbetrieb des Rechners ja
noch egal sein mag, im Multi-User-Betrieb einer Mailbox ist das nicht mehr
brauchbar.
Aus gleichen Gründen haben die Stringfunktionen eine feste interne Puffer-
größe. Strings mit mehr als 4096 Bytes lassen die Funktionen crashen.
Ausgenommen die 'mem'-Funktionen, upstr, lowstr und StrCaseCmp, die haben
keine Limits.

Einige Funktionen, mögen zu dem Zeitpunkt da diese Dokumentation gelesen
wird, längst überflüssig geworden sein. Oder es wird nicht mit vbcc
gearbeitet und die Funktionen sind vorhanden.
Fest steht, zum heutigen Zeitpunkt gibt es die Funktionen in vbcc nicht,
zum Teil gab es sie jedoch auf dem Compiler, auf dem alles mal entwickelt
wurde und daher wurden sie genau nachempfunden. Das trifft z.B. auf swapmem
zu, eine Funktion die zum Teil unter dem Namen swab bei anderen Compilern
auftaucht. Funktionell ist es auf jeden Fall identisch.

Die Library ist Bestandteil von Gateway-5 und unterliegt den gleichen
Copright's. Jede Benutzung erfolgt ausschließlich auf eigene Gefahr.
Für die Richtigkeit der hier gemachten Angaben wird keinerlei Garantie
übernommen. Desweiteren besteht keine Anspruch darauf, das die Funktionen
in zukünftigen Libraryfunktionen erhalten oder unverändert bleiben.
@ENDNODE
@NODE "COPYRIGHT" "Copyright"
@TOC MAIN
@NEXT GATEWAY
@PREV README
@SMARTWRAP
{LINDENT 3}
@{U} "Copyright und Nutzungsbedingungen!" @{UU}@{LINDENT 6}

@{B}Die @{I}gateway.library@{UI} ist Copyright by Michaela Prüß. Alle Rechte vorbehalten.@{UB}

Solange die Library in unveränderten Zustand verbleibt, darf sie frei kopiert
werden. Unveränderter Zustand heißt auch, das die der Library beiliegenden
Files unverändert bei der Library verbleiben müssen.

@{B}Jede Veränderung an den Files ist untersagt und führt sofort zum Verlust@{UB}
@{B}der Nutzungslizenz.@{UB}

@{U}Ausnahme:@{UU}
Da Compiler die im Standard Funktionen enthalten, welche in der Library
definiert sind, kann es zu Problemen mit den Library-Includes kommen.
In diesem Fall dürfen diese beiden Datei lokal angepasst werden.
Wer eine solche Anpassung vornimmt schickt die Files bitte an mich
zurück, ich nehme sie ggf. in das Archiv auf.

Eine Gewährleistung, gleich welcher Art, wird weder für die Library noch
für den Inhalt der sonstigen Files übernommen. Schadensersatz ist generell
ausgeschlossen, selbst wenn durch die Nutzung Datenverluste entstehen
sollten. Die benutzung erfolgt generell auf eigenes Risiko.

Änderungen an der Library können jderzeit vorgenommen werden.


Copyright's, Lizenzen und Sources dritter:

Die Library basiert zum Teil auf den Souces der example.library von
Andreas Kleinert. Zum Teil mußten einige Dinge darin verändert werden
da sich meine vbcc-Version augenscheinlich nicht kompatibel zu der
Version verhält für die die Library irgendwann angepasst wurde. Falls
dies hier von Andreas Kleinert gelesen wird: Ich habe aus Zeitgründen
keine Ursachen erforscht, sondern lediglich alles entfernt, was hier
zu Komplikationen geführt hat. Wenn mehr Zeit ist werde ich versuchen
die "saubere" Library anzupassen und dann die Änderungen melden.

vbcc ist Copyright bei Volker Barthelmann (und zum Teil Frank Wille).

Gateway-5, gateway.library und Pmm sind Copyright bei Michaela Prüß.

Amiga ist ein Warenzeichen von AMIGA INC.

@ENDNODE
@NODE "GATEWAY" "GATEWAY"
@SMARTWRAP
{LINDENT 3}
@{U} "Ein Name, zwei Dinge!" @{UU}@{LINDENT 6}

Dies in (nicht nur) eigener Sache:

Bis heute gab/gibt es:
GATEWAY
GATEWAY-II
GATEWAY-III
GATEWAY-IV
Gateway-5

Es soll hier an dieser Stelle ganz klar gesagt werden: Dies ist eine BBS-Software die in keiner Weise etwas mit dem jetzigen Inhaber des Amiga's zu tun hat. Da ich mich aber auf einen rechtlich gültigen Namensschutz stützen kann werde ich den Namen der BBS-Software nicht abändern. Bis jetzt hat das auch niemand verlangt.

Aber um Problemen und Verwechselungen, gleich welcher Art, im Voraus zu begegnen, hänge ich inzwischen allen meinen Veröffentlichungen diese Information an.

Ich erhebe auch lediglich Titelschutz auf den Namen GATEWAY als BBS-Software und als Fernseh-Sendung (das interaktive TV-Programm GATEWAY lief über ein Jahr lang im Berliner Kabelnetz).
Hier sei noch erwähnt, das der Mitträger der TV-Sendung ebenfalls die Rechte hat. Das ist "Der freie Kanal" in Berlin.

@ENDNODE
@NODE "GateRequest" "GateRequest"
@{LINDENT 3}
@{U} "ULONG GateRequest(UBYTE *title_d1,UBYTE *body,UBYTE *gadgets);" @{UU}@{LINDENT 6}

Zeigt einen einfachen Requester via EasyRequest
Diese Funktion dient zum Test ob die Library anläuft.


Aufrufwerte:
------------
UBYTE *title_d1  - Überschrift des Requesters
UBYTE *body      - Text des Requesters
UBYTE *gadgets   - Beschriftung der Auswahlknöpfe


Rückgabe:
---------
ULONG            - Nummer des gewählten Gadgets

@ENDNODE
@NODE "ltofa" "ltofa"
@{LINDENT 3}
@{U} "char *ltofa(char *tx_d1,ULONG l);" @{UU}@{LINDENT 6}

(Long TO formatted ascii)

Die Funktion formatiert eine Zahl (ähnlich einem 'PRINT USING') mit Punkten an den nach der 3. ,6. und 9. Ziffer.
Die Rückgabe hat das Muster "#.###.###.###"
Nicht benutzte Positionen sind mit Leerzeichen aufgefüllt, die Rückgabe hat immer die Länge 13 + Nullbyte.
Beispiele:
1234567890 => '1.234.567.890'
482        => '          482'
48526      => '       48.526'


Aufrufwerte:
------------
char  *tx_d1      - Pointer auf ein mindestens 14 Zeichen großes Char-Feld. In dem Feld wird die Eingabe aufbereitet zurückgeliefert.
ULONG  l          - Die Zahl, die formatiert werden soll.


Rückgabe:
---------
char  *           - Pointer auf tx_d1

@ENDNODE
@NODE "trim" "trim"
@{LINDENT 3}
@{U} "void trim(UBYTE *trptr);" @{UU}@{LINDENT 6}

Funktion zum Entfernen von Leerzeichen am Anfang und Ende von Strings. Entfernt werden die Ascii-Codes 32, 160 und 9.
Leerzeichen, geschiftete Leerzeichen und Tabulatoren werden abgeschnitten. Diese Funktion dient zum Säubern von Zeichenketten die aus Dateien eingelesen werden.


Aufrufwerte:
------------
UBYTE  *trtpr     - Pointer auf den String der bereinigt wird. Nach dem Funktionsaufruf ist der String bereinigt.


Rückgabe:
---------
N/A

@ENDNODE
@NODE "trim_cr" "trim_cr"
@{LINDENT 3}
@{U} "void trim_cr(UBYTE *trptr);" @{UU}@{LINDENT 6}

Funktion zum Entfernen von Leerzeichen und CR/LF am Anfang und Ende von Strings. Entfernt werden die Ascii-Codes 32, 160, 9, 10, 13 und 14.
Leerzeichen, geschiftete Leerzeichen, Linefeed, Return und Tabulatoren werden abgeschnitten. Diese Funktion dient zum Säubern von Zeichenketten die aus Dateien eingelesen werden.


Aufrufwerte:
------------
UBYTE  *trtpr     - Pointer auf den String der bereinigt wird. Nach dem Funktionsaufruf ist der String bereinigt.


Rückgabe:
---------
N/A

@ENDNODE
@NODE "rtrim" "rtrim"
@{LINDENT 3}
@{U} "void rtrim(UBYTE *trptr);" @{UU}@{LINDENT 6}

Gleiche Funktion wie trim, es wird nur der rechte Teil des Strings bearbeitet. Führende Leerzeichen/Tab's bleiben. Entfernt werden die Ascii-Codes 32, 160 und 9.
Leerzeichen, geschiftete Leerzeichen und Tabulatoren werden abgeschnitten. Diese Funktion dient zum Säubern von Zeichenketten die aus Dateien eingelesen werden.


Aufrufwerte:
------------
UBYTE  *trtpr     - Pointer auf den String der bereinigt wird. Nach dem Funktionsaufruf ist der String bereinigt.


Rückgabe:
---------
N/A

@ENDNODE
@NODE "lset" "lset"
@{LINDENT 3}
@{U} "void lset(UBYTE *lbuff, long slen);" @{UU}@{LINDENT 6}

String formatieren auf eine festgelegte Anzahl Stellen.
Ist der String kürzer als gewünscht werden an Anfang Leerzeichen eingefügt.
Ist der String länger als gewünscht wird er rechts abgeschnitten.
Zuvor wird (und deshalb würde sprintf nicht das gleiche Ergebnis liefern) ein 'trim' durchgeführt.
Es wird also der wirkliche String ohne Leerzeichen am Anfang oder Ende formatiert.


Aufrufwerte:
------------
UBYTE  *lbuff    - Pointer auf den String der bearbeitet wird. Nach dem Funktionsaufruf ist der String ggf. geändert.
long    slen     - Länge die der String nach Aufruf der Funktion haben soll.


Rückgabe:
---------
N/A

@ENDNODE
@NODE "lsetmin" "lsetmin"
@{LINDENT 3}
@{U} "void lsetmin(UBYTE *lbuff, long slen);" @{UU}@{LINDENT 6}

String formatieren auf eine festgelegte Mindestanzahl Stellen.
Ist der String kürzer als gewünscht werden an Anfang Leerzeichen eingefügt.
Zuvor wird (und deshalb würde sprintf nicht das gleiche Ergebnis liefern) ein 'trim' durchgeführt.
Es wird also der wirkliche String ohne Leerzeichen am Anfang oder Ende formatiert.
Im Gegensatz zu lset wird der String aber in keinem Falle gekürzt.


Aufrufwerte:
------------
UBYTE  *lbuff    - Pointer auf den String der bearbeitet wird. Nach dem Funktionsaufruf ist der String ggf. geändert.
long    slen     - Länge die der String nach Aufruf der Funktion mindestens haben soll.


Rückgabe:
---------
N/A

@ENDNODE
@NODE "string" "string"
@{LINDENT 3}
@{U} "void string(UBYTE *spstr, long num, long ch);" @{UU}@{LINDENT 6}

String mit einem Zeichen füllen.
Der String wird mit einem bestimmten Zeichen gefüllt.


Aufrufwerte:
------------
UBYTE  *spstr    - Pointer auf den String der die Zeichenkette erhalten soll.
long    num      - Länge des zu füllenden Bereiches.
long    ch       - Ascii-Wert des Charakters mt dem der String gefüllt wird.


Rückgabe:
---------
N/A

@ENDNODE
@NODE "instr" "instr"
@{LINDENT 3}
@{U} "long instr(UBYTE *sa, UBYTE *sb);" @{UU}@{LINDENT 6}

Suche nach einem Teilstring im String. Gesucht wird, ob der String 'sb' in 'sa' enthalten ist.
Wird der Suchstring gefunden, dann wird seine Position im String zurückgeliefert, beginnend bei 0.
Ist der Suchstring nicht vorhanden, dann wird -1 zurückgegeben.
Die Schreibweise (Groß-/Kleinbuchstaben) ist unerheblich, es wird intern immer mit Kleinbuchstaben gearbeitet.
Der deutsche Zeichensatz (ä, ö und ü) ist berücksichtigt.


Aufrufwerte:
------------
UBYTE  *sa       - String in dem gesucht werden soll.
UBYTE  *sb       - Teilstring der gesucht wird.


Rückgabe:
---------
long             - Position von sb in sa. Kann 0 bis (strlen(sa)-strlen(sb)) sein.
                   Enthält -1 wenn nichts gefunden wird.

@ENDNODE
@NODE "instr_pat" "instr_pat"
@{LINDENT 3}
@{U} "long instr_pat(UBYTE *sa, UBYTE *sb);" @{UU}@{LINDENT 6}

Suche nach einem Teilstring im String. Gesucht wird, ob der String 'sb' in 'sa' enthalten ist.
Wird der Suchstring gefunden, dann wird seine Position im String zurückgeliefert, beginnend bei 0.
Ist der Suchstring nicht vorhanden, dann wird -1 zurückgegeben.
Die Schreibweise (Groß-/Kleinbuchstaben) ist unerheblich, es wird intern immer mit Kleinbuchstaben gearbeitet.
Der deutsche Zeichensatz (ä, ö und ü) ist berücksichtigt.
Im Gegensatz zu instr() sind hierbei Pattern möglich. * für eine beliebige Zeichenkette und ? für ein beliebiges Zeichen.


Aufrufwerte:
------------
UBYTE  *sa       - String in dem gesucht werden soll.
UBYTE  *sb       - Teilstring der gesucht wird.


Rückgabe:
---------
long             - Position von sb in sa. Kann 0 bis (strlen(sa)-strlen(sb)) sein.
                   Enthält -1 wenn nichts gefunden wird.

@ENDNODE
@NODE "upstr" "upstr"
@{LINDENT 3}
@{U} "void upstr(UBYTE *trptr);" @{UU}@{LINDENT 6}

Alle Buchstaben im String in Großbuchstaben wandeln.
Im Gegensatz zu ähnlichen Funktionen wird der deutsche Zeichensatz bearbeitet.
ä -> Ä, ö -> Ö und ü -> Ü.


Aufrufwerte:
------------
UBYTE  *trptr   - Pointer auf den String der gewandelt werden soll.


Rückgabe:
---------
N/A

@ENDNODE
@NODE "lowstr" "lowstr"
@{LINDENT 3}
@{U} "void lowstr(UBYTE *trptr);" @{UU}@{LINDENT 6}

Alle Buchstaben im String in Kleinbuchstaben wandeln.
Im Gegensatz zu ähnlichen Funktionen wird der deutsche Zeichensatz bearbeitet.
Ä -> ä, Ö -> ö und Ü -> ü.


Aufrufwerte:
------------
UBYTE  *trptr   - Pointer auf den String der gewandelt werden soll.


Rückgabe:
---------
N/A

@ENDNODE
@NODE "set" "set"
@{LINDENT 3}
@{U} "void set(UBYTE *lbuff, long slen);" @{UU}@{LINDENT 6}

String auf feste Länge bringen. Zu lange Strings werden abgeschnitten, zu kurze rechts mit Leerzeichen gefüllt.
Das ganze geht auch mit einem sprintf, allerdings ist der wesentlich langsamer und braucht zusätzlich einen Pufferstring.


Aufrufwerte:
------------
UBYTE  *lbuff   - String der bearbeitet werden soll.
long    slen    - Länge die der String haben soll.


Rückgabe:
---------
N/A

@ENDNODE
@NODE "midstr" "midstr"
@{LINDENT 3}
@{U} "void midstr(UBYTE *mstr, long pos, long laenge);" @{UU}@{LINDENT 6}

String ausschneiden.
Ab der Position 'pos' (0 bis strlen(mstr)-1) die per 'laenge' angegebene Anzahl Zeichen herausschneiden.
Ist 'laenge' zu groß wird bis zum Stringende herausgeschnitten. 'laenge' -1 bedeutet das gleiche, als ab 'pos' bis zum Ende.
Ist 'pos' ungültig wird nichts bearbeitet. 


Aufrufwerte:
------------
UBYTE  *mstr    - String der bearbeitet werden soll.
long    pos     - Position ab der ausgeschnitten wird.
long    laenge  - Anzahl der auszuschneidenen Zeichen (-1 = Rest des Strings).


Rückgabe:
---------
N/A

@ENDNODE
@NODE "date_to_day" "date_to_day"
@{LINDENT 3}
@{U} "ULONG date_to_day(ULONG date);" @{UU}@{LINDENT 6}

Ermittelt den Tag im Jahr (1-365). Es wird eine Überschlagrechnung für einen
sogenannten Cruncher durchgeführt. +/- 2 Tage Abweichung stören da nicht und
können auch auftreten.


Aufrufwerte:
------------
ULONG date      - Datum im Format ttmmjjjj


Rückgabe:
---------
ULONG           - Tag im Jahr (1-365)


@ENDNODE
@NODE "date_to_zahl" "date_to_zahl"
@{LINDENT 3}
@{U} "ULONG date_to_zahl(UBYTE *da);" @{UU}@{LINDENT 6}


Datum in Ziffern überführen. Das zugewiesene Datum wird als Ziffernfolge in einem unsigned long zurückgeliefert.
Wird z.B. der 12.12.1990 als String übergeben kommt 12121990 zurück.


Aufrufwerte:
------------
UBYTE *da       - Datum im Format tt.mm.jjjj wobei der Trenner egal ist.
                  Datum könnte auch tt-mm-jjjj sein. Wichtig ist die das die Ziffern
                  korrekt positioniert sind.


Rückgabe:
---------
ULONG           - Datum als Zahl im Format ttmmjjjj wobei es hier natürlich keine
                  führenden Nullen im Tag geben kann!

@ENDNODE
@NODE "time_to_zahl" "time_to_zahl"
@{LINDENT 3}
@{U} "ULONG time_to_zahl(UBYTE *ti);" @{UU}@{LINDENT 6}

Zeit in Ziffern überführen. Die zugewiesene Zeit wird als Ziffernfolge in einem unsigned long zurückgeliefert.
Wird z.B.  17:50:00 als String übergeben kommt 175000 zurück.
Falls die Sekunden nicht erwünscht sind müssen sie trotzdem erstmal übergeben werden und dann die Rückgabe durch 100 geteilt werden.
Vorsicht! 00:00:00 liefert 0 zurück, also vorsicht mit Divisionen, immer erst prüfen.


Aufrufwerte:
------------
UBYTE  *ti      - Zeit im Format SS:mm:ss wobei der Trenner egal ist.
                  Zeit könnte auch SS/mm/ss sein. Wichtig ist die das die Ziffern
                  korrekt positioniert sind.


Rückgabe:
---------
ULONG           - Zeit als Zahl im Format SSmmss wobei es hier natürlich keine
                  führenden Nullen in den Stunden geben kann! Die Zeit 00:01:30
                  liefert 130 als Ergebnis.

@ENDNODE
@NODE "kill_ansi" "kill_ansi"
@{LINDENT 3}
@{U} "void kill_ansi(UBYTE *buffer);" @{UU}@{LINDENT 6}

Alle Ansi-Sequenzen in einem String entfernen und den reinen Ascii-String zurückliefern.
Diese Routine ist in für den Mailboxeinsatz geschaffen worden und sucht nicht wirklich alle definierten Ansi-Befehle.
Erkannt wird lediglich das ESC am Anfang und dann wird bis zum nächsten Buchstaben einschließlich geschnitten.
Ansi-Sequencen die nicht mit einem Buchstaben enden führen dazu das zuviel weggeschnitten wird!
Die Routine soll lediglich Cursorbewegungen, Farben und Attribute bereinigen um den String ohne Sonderzeichen auf einem Serverschirm abzubilden.


Aufrufwerte:
------------
UBYTE  *buffer  - String der vom Ansi bereinigt werden soll.


Rückgabe:
---------
N/A

@ENDNODE
@NODE "newer" "newer"
@{LINDENT 3}
@{U} "BOOL newer(UBYTE *d1, UBYTE *t1, UBYTE *d2, UBYTE *t2);" @{UU}@{LINDENT 6}

Vergleicht ob Datum 'd1' und Zeit 't1' NEUER als 'd2' und 't2' sind und gibt dementsprechend TRUE oder FALSE zurück.


Aufrufwerte:
------------
UBYTE  *d1     - 1. Datum in der Form tt.mm.jjjj
UBYTE  *t1     - 1. Zeit in der Form SS:mm:ss
UBYTE  *d2     - 2. Datum in der Form tt.mm.jjjj
UBYTE  *t2     - 2. Zeit in der Form SS:mm:ss


Rückgabe:
---------
BOOL           - TRUE wenn das 1. Datenpaar neuer ist als das zweite, sonst FALSE.

@ENDNODE
@NODE "swapmem" "swapmem"
@{LINDENT 3}
@{U} "void swapmem(char *src, char *dst, long n);" @{UU}@{LINDENT 6}

Speicherbereiche vertauschen. 


Aufrufwerte:
------------
char   *src    - Pointer auf 1. Speicherbereich.
char   *dst    - Pointer auf 2. Speicherbereich.
long    n      - Anzahl der Bytes die ausgetauscht werden sollen.


Rückgabe:
---------
N/A

@ENDNODE
@NODE "memncmp" "memncmp"
@{LINDENT 3}
@{U} "long memncmp(char *a, char *b, long length);" @{UU}@{LINDENT 6}

Speicherbereiche vergleichen. 


Aufrufwerte:
------------
char   *a      - Pointer auf 1. Speicherbereich.
char   *b      - Pointer auf 2. Speicherbereich.
long    lenght - Anzahl der Bytes die verglichen werden sollen.


Rückgabe:
---------
long           -  0 wenn beide Speicherbereiche gleich sind.
                  1 wenn a größer als b ist.
                 -1 wenn a kleiner als b ist.

@ENDNODE
@NODE "StrCaseCmp" "StrCaseCmp"
@{LINDENT 3}
@{U} "long StrCaseCmp(char *s1, char *s2);" @{UU}@{LINDENT 6}

String s1 und s2 werden auf gleichheit geprüft. Groß-/Kleinschrift wird nicht berücksichtigt, jedoch sehr wohl z.B. in den deutschen Umlauten.
Diese Funktion dient intern zum Vergleich von Laufwerksnamen, daher sind die deutschen Umlaute hier nicht umgewandelt.

Aufrufwerte:
------------
char   *s1     - Pointer auf 1. String.
char   *s2     - Pointer auf 2. String.


Rückgabe:
---------
long           -  0 wenn beide Speicherbereiche gleich sind.
                  1 wenn sie unterschidlich sind.

@ENDNODE
@NODE "trim_includes" "trim_includes"
@{LINDENT 3}
@{U} "void trim_includes(UBYTE *trptr);" @{UU}@{LINDENT 6}

Siehe trim.
Hier wird jedoch alles entfernt, was nicht zu einem Include-File-Namen gehören kann, z.B.
auch " am Anfang und Ende (diese Sonderversion wird von Pmm benutzt).

Aufrufwerte:
------------
UBYTE  *trtpr     - Pointer auf den String der bereinigt wird. Nach dem Funktionsaufruf ist der String bereinigt.


Rückgabe:
---------
N/A

@ENDNODE
@NODE "mail_trim" "mail_trim"
@{LINDENT 3}
@{U} "void trim_includes(UBYTE *trptr, long fkt);" @{UU}@{LINDENT 6}

Siehe trim.
Hier wird jedoch alles entfernt, was nicht zu einem eMail-Namen gehören kann, z.B.
auch < > am Anfang und Ende (diese Sonderversion wird von Gateway's eMail-System benutzt).

Aufrufwerte:
------------
UBYTE  *trtpr     - Pointer auf den String der bereinigt wird. Nach dem Funktionsaufruf ist der String bereinigt.
long    fkt       - 1, wenn < > entfernt werden sollen
                    0, wenn < > erhalten werden sollen

Rückgabe:
---------
N/A

@ENDNODE
@NODE "newstr" "newstr"
@{LINDENT 3}
@{U} "void newstr(UBYTE *istr, UBYE *nstr, long pos, long len);" @{UU}@{LINDENT 6}


Diese Funktion ist Teil des Gateway-Interpreters und dient fast ausschließlich zur
Ersetzung von Variablen durch ihren Datenwerte. Dabei wird aus istr ab der Stelle
pos eine durch len festgelegte Anzahl Zeichen entfernt. An gleicher Stelle wird
dafür nstr eingesetzt. nstr kann kürzer, länger oder genau so lang sein, wie der
entfernte string. Ist nstr leer (0 Zeichen), dann wird nur der angegebene Bereich
entfernt. 
Eine überprüfung der Gültigkeit von pos und len findet nicht statt. Das heißt im
Klartext, das fehlerhafte Werte irgendwo im Speicher herumhantieren könnten. Der
Gateway-Interpreter liefert immer verläßliche Werte an und das muß unbedingt auch
bei jedem anderen Nutzer sichergestellt werden.

Ach ja, warum ausgerechnet ISTR ? Darum:

istr = Interpretierter String
nstr = Neuer Stringbereich



Aufrufwerte:
------------
UBYTE  *istr      - Pointer auf den String der bearbeitet werden soll.
UBYTE  *nstr      - String der in istring eingesetzt werden soll.
                    Wird kein String übergeben wird nur ein Bereich entfernt.
long    pos       - Position, ab der die Ersetzung beginnt.
long    len       - Anzahl der Zeichen, die aus istr entfernt werden sollen.
                    Bei Länge 0 erfolgt nur eine Einfügung.


Rückgabe:
---------
N/A

@ENDNODE
@NODE "wordwrp" "wordwrp"
@{LINDENT 3}
@{U} "long wordwrp(UBYTE *line, UBYTE *rest, long len);" @{UU}@{LINDENT 6}

Editor-Sub-Funktion

Es wird eine Textzeile in Line übergeben und die reguläre Maximalbreite der
Zeilen in len. Typisch ist ein String mit 80 Zeichen beim einem maximalen
Wert von 79. Ist die Länge des Strings größer oder gleich dem len-Wert. dann
erfolgt ein Umbruch, wobei nach links gehend ein Leerzeichen gesucht wird.
Ab diesem wird dann line gekappt, der Rest des Strings wird in den String
'rest' übertragen und man erhält zwei Strings zurück.
Leerzeichen am Zeilenende werdem entfernt, sie zählen also nicht zu Länge
hinzu.
Läßt sich 'line' nicht zerlegen (kein Leerzeichen in den letzten 20 Bytes der
Maximallänge oder 'line' kürzer als Maximum wird ein leerer Reststring zurück-
geliefert und als Rückgabewert der Funktion eine 0.
Bei erfolgreicher Teilung liefert die Funktion eine 1 zurück.


Aufrufwerte:
------------
UBYTE  *line      - Textzeile die bei Bedarf umgebrochen werden soll.
UBYTE  *rest      - Teilstring der am Ende von Line abgeschnitten wurde, bzw.
                    char Null, wenn erfolglos.
long    len       - Anzahl Zeichen des Bildschirms bzw. Position des Umbruchs


Rückgabe:
---------
long              - 0 = Erfolglos, line wurde nicht verändert
                    1 = Erfolgreich, Line und Rest angapasst

@ENDNODE
@NODE "fn_splitt" "fn_splitt"
@{LINDENT 3}
@{U} "void fn_splitt(char *src, char *drive, char *path, char *name, char *ext);" @{UU}@{LINDENT 6}


Dient zum zerlegen von Dateinamen in ihre Hauptkomponenten. 'src' kann jede Art von
Laufwerks-, Pfad- und/oder Dateinamen sein.

drive:path/name.ext wird aufgespalten in die vier Teilkomponenten. Fehlt ein Part
ist sein String leer.
Dabei geht die Funktion davon aus, im Zweifel ist ein Dateiname. Oder einfacher:
src ist solange der Name, bis das Gegenteil bewiesen ist. Erst wird nach einem
Punkt für eine Namenserweiterung geschaut, danach ob Slash oder Doppelpunkt
zu finden und abzutrennen sind.


Aufrufwerte:
------------
char   *src       - String der zerlegt werden soll.
char   *drive     - Rückgabe Laufwerksname
char   *path      - Rückgabe Pfadnamen
char   *name      - Rückgabe Dateiname
char   *ext       - Rückgabe Dateiextension


Rückgabe:
---------
char   *          - identisch mit src


@ENDNODE
@NODE "fn_build" "fn_build"
@{LINDENT 3}
@{U} "void fn_build(char *dst, char *drive, char *path, char *name, char *ext);" @{UU}@{LINDENT 6}


Fügt die Teilkomponenten drive, path, name und ext zu einem vollständigen Dateinamen
zusammen. Drive muß mit einem Doppelpunkt enden. Fehlt am Ende des Pfadnamens der
Slash wird angehangen. Beginnt die Extension nicht mit einem Punkt wird dieser eben-
falls zugefügt. Leere Strings bleiben unberücksichtigt. So muß kein Pfad angegeben
werden, wenn z.B. die Datei in einem Drive liegt.


Aufrufwerte:
------------
char   *dst       - String der aufgebaut werden soll.
char   *drive     - Laufwerksname:
char   *path      - Pfadnamen/
char   *name      - Dateiname
char   *ext       - .Extension


Rückgabe:
---------
char   *          - Ergebnis (dst) 'drive:path/name.ext'


@ENDNODE
@NODE "addval" "addval"
@{LINDENT 3}
@{U} "void addval(UBYTE *str, ULONG n);" @{UU}@{LINDENT 6}


Zur numerischen Bearbeitung von Zahlenfeldern in Asscii-Dateien.
str wird in ein long gewandelt, n wird aufaddiert und das ganze
als 10stelliger String in str wieder zurückgeliefert.


Aufrufwerte:
------------
char   *addval    - String mit numerischem Inhalt. Nach Ende
                    der Funktion ist str auf jeden Fall 10
                    Zeichen groß 'Formatstring ist %10lu'.
ULONG   n         - Zahl, die auf den numerischen Wert von str
                    aufaddiert wird.


Rückgabe:
---------
N/A


@ENDNODE
@NODE "strdup" "strdup"
@{LINDENT 3}
@{U} "char *strdup(char *s);" @{UU}@{LINDENT 6}

Dupliziert den String *s in einen neuen Speicherbereich. 

Aufrufwerte:
------------
char   *s         - Originalstring


Rückgabe:
---------
char   *          - Kopie von *s (Unbedingt daran denken
                    das dies ein malloc ist, also den Speicher
                    am Ende wieder freigeben!

@ENDNODE
@NODE "indexfkt" "index"
@{LINDENT 3}
@{U} "char *index(const char *str, long c);" @{UU}@{LINDENT 6}

Sucht nach dem ersten Auftreten von c in str und leifert den Pointer auf diese Position zurück.


Aufrufwerte:
------------
const char *s     - Zu durchsuchender String
long        c     - Ascii-Wert des Zeichen

Rückgabe:
---------
char   *          - Pointer auf die Fundstelle von c. Falls nicht erfolgreich
                    wird 0 übergeben.

@ENDNODE
