(*------------------------------------------

  :Module.      CDInput.mod
  :Author.      Albert Weinert  [awn]
  :Address.     Krähenweg 21 , 50829 Köln
  :EMail.       Usenet_> aweinert@darkness.gun.de
  :EMail.       Z-Netz_> A.WEINERT@DARKNESS.ZER
  :Phone.       0221 / 580 29 84
  :Revision.    R.1
  :Date.        17-May-1993
  :Copyright.   Albert Weinert
  :Language.    Oberon-2
  :Translator.  Amiga Oberon 3.00d
  :Contents.    Liest eine Catalog Description Datei und legt dies in einer Liste ab.
  :Imports.     MoreStrings.mod [hG|awn], C2OData.mod, Cd2OberonLocale.mod [awn]
  :Remarks.     <Was Du willst, evtl. Usage>
  :Bugs.        <Bekannte Fehler>
  :Usage.       <Angaben zur Anwendung>
  :History.     .0     [awn] 16-May-1993 : Erstellt
  :History.     .1     [awn] 17-May-1993 : Fehlernummern werden nun gesetzt
  :History.            so das der User auf weiss wo und woran der Fehler lag.

--------------------------------------------*)
MODULE CDInput;

IMPORT  ms:=MoreStrings,
        str:=Strings,
        cd:=C2OData,
        Conversions,
        BT:=BasicTypes,
        fs:=FileSystem,
        SYSTEM,
        cl:=Cd2OberonLocale;

VAR lastnum : LONGINT;
    line    : LONGINT;

  PROCEDURE GetID(string: ARRAY OF CHAR;VAR idname:ARRAY OF CHAR; VAR idnum:LONGINT):BOOLEAN;
  (*------------------------------------------
    :Input.     string = Zeichekette
    :Output.    idname = Bezeichnung der ID, idnum = Nummer der ID
    :Semantic.  Extrahiert den ID Namen und die ID Nummer aus einem ID Strings und teste
    :Semantic.  dabei auf deren korrektheit.
    :Note.
    :Update.    16-May-1993 [awn] - erstellt.
  --------------------------------------------*)
    VAR num : ARRAY 64 OF CHAR;
        pos, npos : LONGINT;
        ok: BOOLEAN;
    BEGIN
      IF string # "" THEN
        ms.GetWord(idname,string,1);
        ms.GetWord(num,string,2);
        IF (num[0] # "(") OR (num[str.Length(num)-1] # ")") THEN
            cd.error:=cl.errIWrongIDDesc;
            cd.para1:=line;
           RETURN FALSE;
        ELSE
          str.Delete(num,0,1);
          pos:=str.Occurs(num,"/");
          IF pos = -1 THEN
            cd.error:=cl.errIWrongIDDesc;
            cd.para1:=line;
            RETURN FALSE
          END;
          npos:=str.OccursPos(num,"/",pos+1);
          IF npos = -1 THEN
            cd.error:=cl.errIWrongIDDesc;
            cd.para1:=line;
            RETURN FALSE
          END;
          str.Delete(num,pos,str.Length(num)-pos);
          IF num # "" THEN
            ok:=Conversions.StrToInt(num,idnum,10);
            lastnum:=idnum;
            RETURN ok;
          ELSE
            INC(lastnum);
            idnum:=lastnum;
            RETURN TRUE;
            cd.error:=cl.errIWrongID;
            cd.para1:=line;
          END;
        END;
      ELSE
        cd.error:=cl.errINoIdDesc;
        cd.para1:=line;
        RETURN FALSE;
      END;
    END GetID;

  PROCEDURE GetString(VAR fh:fs.File;VAR string : BT.DynString):BOOLEAN;
  (*------------------------------------------
    :Input.     fh = FileHandle
    :Output.    string = Zeichenkette die in der Datei steht
    :Semantic.  Erstellt die Zeichenkette aus der Datei die gerade anliegt
    :Note.      Es werden auch mehrzeilige Zeichenketten zu einer zusammen gefügt
    :Note.      dafür müssen die Zeilen, bis auf die letzte mit einem `\` enden.
    :Update.    16-May-1993 [awn] - erstellt.
    :Update.    17-May-1993 [awn] - Fehlernummer werden jetzt gesetzt
  --------------------------------------------*)
    VAR first : BOOLEAN;
        ok : BOOLEAN;
        exit : BOOLEAN;
        pos: LONGINT;

    BEGIN
      ok:=TRUE;
      exit:=FALSE;
      IF string # NIL THEN
        string^:="";
      END;
      first:=TRUE;
      WHILE ok & ~exit DO
        IF ~first THEN
          ok:=fs.ReadLongString(fh);
          INC(line);
        END;
        first:=FALSE;
        IF ok THEN
          pos:=ms.FirstNoSpace(fh.string^);
          IF fh.string[pos] # ";" THEN
            pos:=ms.LastNoSpace(fh.string^);
            IF fh.string[pos-1] = "\\" THEN
              fh.string[pos-1]:= "\o";
            ELSE
              exit:=TRUE;
            END;
            ms.AddString(string,fh.string^);
          ELSE
            cd.error:=cl.errCommentInString;
            cd.para1:=line;
            ok:=FALSE;
          END;
        END;
      END;
      RETURN ok;
    END GetString;

  PROCEDURE Import*(VAR name:ARRAY OF CHAR):BOOLEAN;
  (*------------------------------------------
    :Input.     name = Name der Catalog Description Datei
    :Output.
    :Semantic.
    :Note.
    :Update.    16-May-1993 [awn] - erstellt.
    :Update.    17-May-1993 [awn] - Fehlernummer werden jetzt gesetzt
  --------------------------------------------*)
    VAR fh: fs.File;
        ok, ID: BOOLEAN;
        pos : LONGINT;
        idname : ARRAY 256 OF CHAR;
        idnum  : LONGINT;
        node : cd.Node;
        string : BT.DynString;
    BEGIN
      ok:=FALSE;
      ID:=TRUE;
      IF fs.Open(fh,name,FALSE) THEN
        ok:=TRUE;
        WHILE fs.ReadLongString(fh) AND ok DO
          INC(line);
          pos:=ms.FirstNoSpace(fh.string^);
          IF fh.string[pos] # ";" THEN
            IF ID THEN
              ok:=GetID(fh.string^,idname,idnum);
              IF ok THEN
                NEW(node);
                IF node # NIL THEN
                  ms.AddString(node.IDName,idname);
                  node.IDNumber:=idnum;
                  ID:=FALSE;
                  cd.SList.AddTail(node);
                ELSE
                  cd.error:=cl.errNoMemory;
                  cd.para1:=SYSTEM.ADR(name);
                  ok:=FALSE;
                END;
              END;
            ELSE
              ok:=GetString(fh,string);
              IF ok THEN
                NEW(node.string,str.Length(string^)+20);
                IF node.string # NIL THEN
                  COPY(string^,node.string^);
                ELSE
                  cd.error:=cl.errNoMemory;
                  cd.para1:=SYSTEM.ADR(name);
                  ok:=FALSE;
                END;
              END;
              ID:=TRUE;
            END;
          END;
        END;
      END;
      RETURN ok;
    END Import;
END CDInput.
