   Dokumentation zu UTIL.A
   geschrieben von Holger Weets

   Letzte nderung: 03.04.92

   Diese Bibliothek wurde mit und fuer SOZOBON-C entwickelt und ist
   Shareware, darf also zusammen mit dieser Dokumentation von jedem frei
   kopiert werden, mu allerdings bei regelmiger Benutzung durch Zu-
   sendung eines Betrages von 20,- DM erworben werden.

   Updates:
      - gem_name() sollte jetzt fehlerfrei arbeiten
      - get_key() wartet jetzt auf einen Tastendruck
      - get_key(), xinkey(), sinkey(), chrdel() &strdel() wurden in
        Assmebler neu implementiert
      - in der Dokumentation fehlte die Funktion input()
      - exinkey(), dtostr(), strtod() berarbeitet


   Die Funktionen:

   void chrdel(char *string, int pos)
        string -- String, aus dem ein Zeichen entfernt werden soll
        pos    -- Index des zu loeschenden Zeichens

      Mit dieser Funktion knnen einzelne Zeichen aus einem String entfernt
      werden.



   void chrins(char *string, int pos, char c)
        string -- String, in den ein Zeichen eingefuegt werden soll
        pos    -- Index der Einfuege-Position
        c      -- einzufuegendes Zeichen

      Mit dieser Funktion koennen einzelne Zeichen in strings eingefuegt
      werden.


   void strins(char *src, char *ins)
        src -- String, in den eingefgt werden soll
        ins -- String, der eingefgt werden soll

      Mit dieser Funktion kann ein String am Anfang eines anderen eingefgt
      werden. Eine Positionsangabe als Parameter ist deshalb nicht ntig,
      trotzdem knnen hiermit die Strings an beliebige Stelle in andere
      Strings eingefgt werden, zu diesem Zweck ist die Funktion wie folgt
      aufzurufen:
         strins(string + offset, ins_string);


   void strdel(char *str, int anz)
        str -- String aus dem gelscht werden soll
        anz -- soviele Zeichen werden vom Anfang des Strings gelscht

      Mit dieser Funktion knnen Zeichen am Anfang eines Strings gelscht
      werden. Um Zeichen aus der String-Mitte zu lschen, kann die Funktion
      wie folgt aufgerufen werden:
         strdel(string + offset, Anzahl)


   void get_key(char *c, int *scan)
        c    -- ASCII-Code des Zeichens
        scan -- modifizierter Scancode des Zeichens

      Mit dieser Routine knnen einzelne Zeichen von der Tastatur eingelesen
      werden. Zurckgeliefert wird - sofern vorhanden - der ASCII-Code des
      Zeichens, sowie sein wie folgt modifizierter Scancode:
      Auer dem eigentlichen Scancode wird noch mittels Kbshift() der Status
      der Kontroll-Tasten geholt. Dieser wird zunchst so modifiziert, das in
      ihm maximal noch die Bits fr Shift- links/rechts, Control- und
      Alternate- Taste gesetzt sein knnen. Danach wird noch eine einheitliche
      Darstellung beider Shift-Tasten vorgenommen, und die so entstandenen
      Bits 'hinten' an den Scancode angehngt (Bits 8-11).
      Der Fall, das Bit 2 in der Systemvariablen 'conterm' gesetzt ist, wird
      ebenfalls behandelt. (Siehe dazu im Profibuch unter conterm).
      get_key() wartet, bis eine Taste gedrckt wurde.


   void inkey(char *c, int *scan)
      Diese Funktion wartet auf einen Tastendruck, d.h. die Kontrolle wird
      erst dann wieder an die aufrufende Routine zurckgegeben, wenn tat-
      schlich eine Taste gedrcket wurde und somit ein definiertes Ergebnis
      zurck-geliefert werden kann. Die zurckgegebenen Werte sind der
      ASCII-Code der gedrckten Taste und ihr Scan-Code.


   char ainkey()
      Diese Funktion liest - sofern vorhanden - ein Zeichen aus dem Tastatur-
      puffer und liefert dessen ASCII-Code zurck.
      Falls kein Zeichen vorhanden war, wird 0 zurckgegeben.


   int sinkey()
      Diese Funktion liest - sofern vorhanden - ein Zeichen aus dem Tastatur-
      puffer und liefert dessen Scan-Code zurck.
      Falls kein Zeichen vorhanden war, wird 0 zurckgegeben.


   int xinkey()
      Diese Funktion liest - sofern vorhanden - ein Zeichen aus dem Tastatur-
      puffer und liefert einen Wert zurck, welcher sich zusammensetzt aus
      dem Scancode der gedrckten Taste (Bits 0-7) und dem Status der
      Kontrolltasten (Bits 9-15). Dadurch ist es mglich, alle Tasten-
      kombinationen zu unterscheiden (selbst ob die Taste mit der linken oder
      der rechten Shift-Taste gedrckt wurde).
      Falls kein Zeichen vorhanden war, wird 0 zurckgegeben.


   int exinkey()
      Diese Funktion liest - sofern vorhanden - ein Zeichen aus dem Tastatur-
      puffer und liefert einen Wert zurck, welcher sich zusammensetzt aus
      dem Scancode der gedrckten Taste (Bits 0-7) und dem Status der
      Kontrolltasten (Bits 9-15). Der Unterschied zu xinkey() (siehe oben)
      besteht darin, da keine Unterscheidung zwischen linker und rechter
      Shift-Taste gemacht wird, insbesondere mu diese Unterscheidung nicht
      mehr im eigenen Programm implementiert werden. Ich habe diese Funktion
      deshalb geschrieben, weil die beschriebene Tasten-Unterscheidung wohl
      nie gebraucht werden wird und bei der Implementierung beispielsweise
      eines Editors sogar lstig ist.
      Falls kein Zeichen im Tastatur-Puffer vorhanden war, wird 0
      zurckgegeben.


   int input(int anzahl, char *set, char *buf, int flag)
      Komfortabler Zeileneditor. Dabei sind
      - anz  -- Gre des Eingabebereiches (max. 80)
      - set  -- die erlaubten Zeichen; ist <set> leer, dann sind alle Zeichen
                erlaubt
      - buf  -- Die eingegebene Zeile; kann am Anfang einen Defaultstring
                enthalten, der editiert werden kann
      - flag -- Eingabe bei unbekanntem Zeichen abbrechen ?
      Rckgabewert ist 0, falls mit Return/Enter abgbrochen wurde. Falls <flag>
      gesetzt ist, dann wird als Return-Wert der Scancode der Taste zurck-
      gegeben, die zur Beendigung der Eingabe gefhrt hat, oder 0, falls dies
      Return/Enter war.
      Folgende Tasten werden interpretiert:
      - Cursor rechts/links
      - Backspace
      - Delete
      - Esc (lscht die Eingabezeile)


   unsigned int strtod(char *str)
                str  -- hier steht das Datum drin

      Diese Funktion wandelt einen String-Inhalt in das Datum im Dos-Format
      um.
      Der String mu dabei folgendes Format haben: "TT.MM.JJJJ", Tag und
      Monat mssen zweistellig vorliegen und Jahr vierstellig. Das verwendete
      Trennzeichen (im Beispiel der Punkt) ist beliebig whlbar, nur einstellig
      mu es sein.


   unsigned int strtot(char *str)
                str -- hier steht die Uhrzeit drin

      Diese Funktion wandelt einen String-Inhalt in die Uhrzeit im
      Dos-Format um.
      Der String mu dabei folgendes Format haben: "SS:MM", Stunden und
      Minuten mssen zweistellig vorliegen. Das verwendete Trennzeichen
      (im Beispiel der Doppelpunkt) ist beliebig whlbar, nur einstellig
      mu es sein.


   void ttostr(char *str, unsigned int systime, char *delim)
        systime -- System-Zeit im Dos-Format
        str     -- Ergebnis-String
        delim   -- Trennzeichen

      Diese Funktion wandelt die System-Zeit in einen String um.
      Zurckgeliefert wird eine Zeichenkette der Form:
         <Stunden><Trennzeichen><Minuten>
      wobei <Stunden> und <Minuten> zweistellig sind (fehlende Zeichen
      werden mit '0' aufgefllt),
      Beispiel: "01:13"


   void dtostr(char *str, unsigned int sysdate, char *delim)
        sysdate -- die Systemzeit im Dos-Format
        str     -- der Ergenis-String
        delim   -- das Trennzeichen

      Diese Funktion wandelt das System-Datum in einen String um.
      Zurckgeliefert wird eine Zeichenkette der Form
         <Tag><Trennzeichen><Monat><Trennzeichen><Jahr>
      wobei <Tag> und <Monat> zweistellig und <Jahr> vierstellig sind
      (fehlende Zeichen werden vorn mit '0' aufgefllt),
      Beispiel: "01.04.1990"


   unsigned long drv_free(int drive)
                 drive -- Nummer des Laufwerks (0 = A: etc.)

      Diese Funktion liefert den freien Speicherplatz fr ein beliebiges
      Laufwerk.


   void zerlege(char *name, char *pfad)
        name -- Eingabe-Parameter, hier steht der zu zerlegende Pfad drin
                Ausgabe-Parameter, hier steht hinterher der Dateiname ohne
                Pfad drin
        pfad -- Ausgabe-Parameter, hier steht hinterher der Pfad ohne den
                Dateinamen drin
      Diese Funktion zerlegt einen Zugriffspfad in Pfad und Namen, wobei
      <name> Ein- und Ausgabe-Parameter ist und pfad nur Ausgabe-Parameter.


   int copy(char *src, char *dest)
       src  -- vollstndiger Name der Quelldatei
       dest -- vollstndiger Name der Zieldatei

      Diese Funktion kopiert die Datei <src> nach <dest>. Beide Namen mssen
      vollstndig angegeben sein.

      Beispiel:
         copy("A:\TEST.C", "C:\")   GEHT NICHT
         copy("A:\TEST.C", "C:\TEST.D") kopiert die Datei TEST.C von
         Drive A: unter dem Namen TEST.D auf Laufwerk C:

      Rckgabe-Wert ist entweder 0, dann hat alles geklappt, oder aber eine
      GEMDOS-Fehlernummer, dann ist etwas schiefgegangen.

      Das Kopieren der Dateien groer Dateien geht um so schneller, je mehr
      Speicherplatz vorhanden ist. Die Routine kopiert nmlich so viele
      Bytes wie mglich auf einmal
      ('wie mglich' = gesamter Speicherplatz - 8K).


   void chsuf(char *dest, char *src, char *ext)
        dest -- hier kommt der neue Name rein
        src  -- hier steht der Datei-Name
        ext  -- neue Extension (Namens-Endung) der Datei

      Diese Funktion ndert die Extension des Dateinamens <src>
      in <ext> und liefert das Ergebnis in <dest> zurck.

      Beispiel :
         'chsuf(neu, "A:\TEST.C", "PRG")' liefert 'A:\TEST.PRG' in <neu>


   void gem_name(char *dest, char *src, int flag)
      Diese Funktion formatiert einen im TOS-Format vorliegenden Dateinamen
      in GEM-Format.
      Dabei ist TOS-Format z.B. 'TEST.C' also sozusagen unformatiert
      und GEM-Format ist dann
      'TEST    C', falls der String in ein formatiertes Textfeld einer
         Dialogbox eingetragen werden soll (flag != 0 setzen), oder
      'TEST     C', falls er z.B. in ein Directory-Fenster soll
         (flag = 0 setzen).
      In der Variablen <dest> steht das Ergebnis, die Variable <src> wird
      nicht verndert.


   void tos_name(char *dest, char *src)
      Diese Funktion ist das Gegenstck zu gem_name(), sie wandelt Datei-
      namen, welche im GEM-Format vorliegen, in TOS-Format um.
      In der Variablen <dest> steht das Ergebnis, die Variable <src> wird
      nicht verndert.
      Diese Funktion ist immer dann praktisch, wenn Dateinamen in Verbindung
      mit Fenstern oder Dialogboxen verwendet werden.
      Beispiel: 'TEST    C' wird zu 'TEST.C'


   int wild(char *test, char *pattern)
      Diese Funktion implementiert einen Pattern-Matching-Alogorithmus, wie
      er z.B. unter UNIX blich ist. Erlaubt sind die Wildcards
      - *   - pat auf JEDE Zeichenkette (insbesondere auch den '.'),
              funktioniert somit NICHT, wie vom TOS gewohnt.
      - ?   - pat auf JEDES einzelne Zeichen (insbesondere auch den '.'),
              funktioniert somit ebenfalls NICHT, wie vom TOS gewohnt
      - []  - erzeugt eine Menge von Zeichen, die an der aktuellen Stelle
              erlaubt sind
              '[abc]*' pat auf 'axxx', 'bxyz', 'cabs' aber nicht auf 'xabc'
         -! - wenn das erste Zeichen in der eckigen Klammer ein '!' ist, so
              passen alle Zeichen, die NICHT in der Menge sind
              '[!abc]*' pat auf 'def', aber nicht auf 'axy'
         -\ - maskiert die Sonderzeichen (\! am Anfang einer Menge meint
              das '!' selbst, \] meint nicht das Ende der Menge, sondern das
              Zeichen ']'
              \nnn wird in das Zeichen umgewandelt, fuer das die OKTAL-Zahl
              nnn steht (\033 meint Escape (dezimal 27) )
      Diese Routine ist NICHT von mir, sondern wurde von Fred Fish unter
      UNIX und AmigaDos implementiert. Ich habe sie lediglich im Hinblick
      auf Portierung durchgesehen und dann i.w. bernommen.


   char *xfgets(char *buffer, int len, FILE *file)
      Diese Funktion fhrt im wesentlichen die Arbeit von fgets() aus.
      Nachdem der Buffer eingelesen wurde, wird jedoch im Gegensatz zu
      fgets() das Zeilen-Ende-Zeichen noch entfernt. ES WIRD NICHT GEPRFT,
      OB TATSCHLICH EINS VORHANDEN IST ! deshalb ist diese Fuktion nur
      verwendbar, wenn eine ganze Zeile Text eingelesen werden soll.

