system/dos/1.8.7/src/fetch

Raw file
Back to index

PACKET fetch DEFINES                   (* Copyright (C) 1985, 86, 87 *)
                                       (* Frank Klapper              *)
                                       (* 27.04.87                   *) 
  fetch,
  check file:

LET ascii             = 1,
    ascii german      = 2,
    transparent       = 3,
    row text          = 5,
    ds                = 6,
    dump              = 7,
    atari st          = 10,
    ibm               = 11,

  (*line end chars    = ""10""12""13"",*)
    min line end char = ""10"",
    max line end char = ""13"",
    lf                = ""10"",
    cr                = ""13"",
    tab code          = 9,
    lf  code          = 10,
    ff  code          = 12,
    cr  code          = 13,
    ctrl z            = ""26"", 

    page cmd          = "#page#",

    row text length   = 4000,
    row text type     = 1000;

BOUND STRUCT (INT size,
              ROW row text length TEXT cluster row) VAR cluster struct;

FILE VAR file;

TEXT VAR buffer;
INT VAR buffer length;

PROC fetch (TEXT CONST name, DATASPACE VAR file ds, INT CONST mode):

  SELECT mode OF 
    CASE ascii, ascii german, atari st, ibm, transparent:
                      fetch filemode (file ds, name, mode)
    CASE row text   : fetch row textmode (file ds, name)
    CASE ds         : fetch dsmode       (file ds, name)
    CASE dump       : fetch dumpmode     (file ds, name)
    OTHERWISE error stop ("Unzulässige Betriebsart")
  END SELECT.

END PROC fetch;

PROC fetch filemode (DATASPACE VAR file space, TEXT CONST name,
                     INT CONST code type):
  enable stop;
  initialize fetch filemode;
  open fetch dos file (name);
  WHILE NOT was last fetch cluster REP
    get text of cluster;
    write lines;
(***************************************)
    IF lines (file) > 3900
      THEN putline (file, ">>> FREMDDATEI FUER EUMEL ZU LANG. ES KÖNNEN DATEN FEHLEN <<<");
           LEAVE fetch filemode
    FI;
(***************************************)
  UNTIL file end via ctrl z
  PER;
  write last line if necessary; 
  close fetch dos file.
 
initialize fetch filemode:
  buffer := "";
  buffer length := 0;
  forget (file space);
  file space := nilspace;
  file := sequential file (output, file space);
  BOOL VAR file end via ctrl z := FALSE.
 
get text of cluster:
  cat next fetch dos cluster (buffer);
  IF ascii code
    THEN ctrl z is buffer end
  FI;
  adapt code (buffer, buffer length + 1, code type);
  buffer length := length (buffer).

ascii code:
  (code type = ascii) OR (code type = ascii german).

ctrl z is buffer end:
  INT  CONST ctrl z pos :: pos (buffer, ctrl z, buffer length + 1);
  file end via ctrl z := ctrl z pos > 0;
  IF file end via ctrl z
    THEN buffer := subtext (buffer, 1, ctrl z pos - 1);
         buffer length := length (buffer)
  FI.

write lines:
  INT VAR line begin pos := 1, line end pos;
  compute line end pos;
  WHILE line end pos > 0 REP
    putline (file, subtext (buffer, line begin pos, line end pos));
    exec (PROC (TEXT CONST, INT CONST) control char conversion, file, code type);
    line begin pos := line end pos + 1;
    compute line end pos
  PER;
  buffer := subtext (buffer, line begin pos);
  buffer length := length (buffer);
  IF buffer length > 5 000
    THEN putline (file, buffer);
         exec (PROC (TEXT CONST, INT CONST) control char conversion, file, code type);
         buffer := "";
         buffer length := 0
  FI.

compute line end pos:
  line end pos := line begin pos;
  REP
    line end pos := pos (buffer, min line end char, max line end char, line end pos);
    INT CONST line end code :: code (buffer SUB line end pos);
    SELECT line end code OF
      CASE lf code: look for cr
      CASE 11     : line end pos INCR 1
      CASE cr code: look for lf
    END SELECT
  UNTIL line end code <> 11
  PER.

look for cr:
  IF line end pos = buffer length
    THEN line end pos := 0
  ELIF (buffer SUB line end pos + 1) = cr
    THEN line end pos INCR 1
  FI.

look for lf:
  IF line end pos = buffer length
    THEN line end pos := 0
  ELIF (buffer SUB line end pos + 1) = lf
    THEN line end pos INCR 1
  FI.

write last line if necessary:
  IF buffer length > 0
    THEN putline (file, buffer);
         exec (PROC (TEXT CONST, INT CONST) control char conversion, file, code type);
  FI.

END PROC fetch filemode;

PROC adapt code (TEXT VAR text buffer, INT CONST start pos, code type):
  SELECT code type OF
    CASE ascii       : cancel bit 8
    CASE ascii german: cancel bit 8; ascii german adaption
    CASE atari st    : atari st adaption
    CASE ibm         : ibm adaption
  (*CASE transparent : do nothing *)
  END SELECT.

cancel bit 8:
  INT VAR set pos := pos (text buffer, ""128"", ""255"", start pos);
  WHILE set pos > 0 REP
    replace (text buffer, set pos, seven bit char);
    set pos := pos (text buffer, ""128"", ""255"", set pos + 1)
  PER.

seven bit char:
  code (code (text buffer SUB set pos) AND 127).

ascii german adaption:
  change all by replace (text buffer, start pos, "[", "Ä");
  change all by replace (text buffer, start pos, "\", "Ö");
  change all by replace (text buffer, start pos, "]", "Ü");
  change all by replace (text buffer, start pos, "{", "ä");
  change all by replace (text buffer, start pos, "|", "ö");
  change all by replace (text buffer, start pos, "}", "ü");
  change all by replace (text buffer, start pos, "~", "ß").

atari st adaption:
  change all by replace (text buffer, start pos, ""142"", "Ä");
  change all by replace (text buffer, start pos, ""153"", "Ö");
  change all by replace (text buffer, start pos, ""154"", "Ü");
  change all by replace (text buffer, start pos, ""132"", "ä");
  change all by replace (text buffer, start pos, ""148"", "ö");
  change all by replace (text buffer, start pos, ""129"", "ü");
  change all by replace (text buffer, start pos, ""158"", "ß").

ibm adaption:
  change all by replace (text buffer, start pos, ""142"", "Ä");
  change all by replace (text buffer, start pos, ""153"", "Ö");
  change all by replace (text buffer, start pos, ""154"", "Ü");
  change all by replace (text buffer, start pos, ""132"", "ä");
  change all by replace (text buffer, start pos, ""148"", "ö");
  change all by replace (text buffer, start pos, ""129"", "ü");
  change all by replace (text buffer, start pos, ""225"", "ß").

END PROC adapt code;

PROC change all by replace (TEXT VAR string, INT CONST begin pos,
                            TEXT CONST old, new):

  INT VAR p := pos (string, old, begin pos);
  WHILE p > 0 REP
    replace (string, p, new);
    p := pos (string, old, p + 1)
  PER.

END PROC change all by replace;

PROC control char conversion (TEXT VAR string, INT CONST code type):

  IF code type <> transparent
    THEN code conversion
  FI.

code conversion:
  INT VAR p := pos (string, ""0"", ""31"", 1);
  WHILE p > 0 REP
    convert char;
    p := pos (string, ""0"", ""31"", p)
  PER.

convert char:
  INT CONST char code := code (string SUB p);
  SELECT char code OF
    CASE tab code: expand tab
    CASE lf  code: change (string, p, p, "")
    CASE ff  code: change (string, p, p, page cmd)
    CASE cr  code: change (string, p, p, "")
    OTHERWISE ersatzdarstellung
  END SELECT.

expand tab:
  change (string, p, p, (8 - (p - 1) MOD 8) * " ").

ersatzdarstellung:
  TEXT CONST t := text (char code);
  change (string, p, p, "#" + (3 - length (t)) * "0" + t + "#").

END PROC control char conversion;

PROC fetch rowtextmode (DATASPACE VAR file space,
                        TEXT CONST name):
  enable stop; 
  open fetch dos file (name);
  initialize fetch rowtext mode;
  WHILE NOT was last fetch cluster REP
    cluster struct.size INCR 1;
    cluster struct.cluster row [cluster struct.size] := "";
    cat next fetch dos cluster (cluster struct.cluster row [cluster struct.size])
  PER; 
  close fetch dos file.
 
initialize fetch row text mode:
  forget (file space);
  file space := nilspace;
  cluster struct := file space;
  type (file space, row text type);
  cluster struct.size := 0.

END PROC fetch rowtext mode;

PROC fetch ds mode (DATASPACE VAR in ds, TEXT CONST name):
  enable stop;
  open fetch dos file (name);
  init fetch dsmode;
  WHILE NOT was last fetch cluster REP
    read next fetch dos cluster (in ds, ds block no);
  PER; 
  close fetch dos file.
 
init fetch dsmode:
  forget (in ds);
  in ds := nilspace;
  INT VAR ds block no := 2.

END PROC fetch ds mode;

PROC fetch dumpmode (DATASPACE VAR file space, TEXT CONST name):
  enable stop; 
  open fetch dos file (name);
  initialize fetch dumpmode;
  WHILE NOT was last fetch cluster REP
    TEXT VAR cluster buffer := "";
    cat next fetch dos cluster (cluster buffer);
    dump cluster
    UNTIL offset > 50 000.0
  PER; 
  close fetch dos file.
 
initialize fetch dump mode:
  BOOL VAR fertig := FALSE;
  REAL VAR offset := 0.0;
  forget (file space);
  file space := nilspace;
  file := sequential file (output, file space).

dump cluster:
  TEXT VAR dump line;
  INT VAR line, column;
  FOR line FROM 0 UPTO (cluster size DIV 16) - 1 REP
    build dump line;
    putline (file, dump line);
    offset INCR 16.0
  UNTIL fertig
  PER.

build dump line:
  TEXT VAR char line := "";
  dump line := text (offset, 6, 0);
  dump line := subtext (dump line, 1, 5);
  dump line CAT "   ";
  FOR column FROM 0 UPTO 7 REP
    convert char;
    dump line CAT " "
  PER;
  dump line CAT " ";
  FOR column FROM 8 UPTO 15 REP
    convert char;
    dump line CAT " "
  PER;
  dump line CAT "  ";
  dump line CAT char line.

convert char:
  TEXT CONST char :: cluster buffer SUB (line * 16 + column + 1);
  IF char = ""
    THEN fertig := TRUE;
         dump line CAT "  ";
         LEAVE convert char
  FI;
  INT CONST char code := code (char);
  LET hex chars = "0123456789ABCDEF";
  dump line CAT (hex chars SUB (char code DIV 16 + 1));
  dump line CAT (hex chars SUB (char code MOD 16 + 1));
  charline CAT show char.

show char:
  IF (char code > 31 AND char code < 127)
    THEN char
    ELSE "." 
  FI.

END PROC fetch dump mode;

PROC check file (TEXT CONST name):
  disable stop;
  DATASPACE VAR test ds := nilspace;
  enable check file (name, test ds);
  forget (test ds);
  IF is error
    THEN clear error;
         error stop ("Fehler beim Prüflesen der Datei """ + name + """")
  FI.

END PROC check file;

PROC enable check file (TEXT CONST name, DATASPACE VAR test ds):
  enable stop;
  open fetch dos file (name);
  WHILE NOT was last fetch cluster REP
    INT VAR dummy := 2;
    read next fetch dos cluster (test ds, dummy)
  PER; 
  close fetch dos file.
 
END PROC enable check file;

END PACKET fetch;