system/dos/1986/src/save

Raw file
Back to index

PACKET save DEFINES                   (* Copyright (C) 1985 *)
                                      (* Frank Klapper      *)
                                      (* 07.05.86           *)
  save filemode, 
  save rowtextmode,
  save dsmode: 

LET       ascii        = 1,
          ascii german = 2,
          transparent  = 3,
          ebcdic       = 4,
          atari st     = 10;

LET ascii ctrl z = ""26"";

LET row text mode length = 4000;

CLUSTER VAR cluster;

DATASPACE VAR cluster space;

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

REAL VAR storage;
TEXT VAR cr lf, ff;
TEXT VAR buffer;

PROC save filemode (DATASPACE CONST file space, 
                    TEXT CONST name,
                    INT CONST code type):
  disable stop;
  cluster space := nilspace;
  cluster := cluster space;
  enable save filemode (file space, name, code type);
  buffer := "";
  forget (cluster space).

END PROC save filemode;
 
PROC enable save filemode (DATASPACE CONST file space, 
                           TEXT CONST name,
                           INT CONST code type):
  enable stop;
  open save (name);
  init save filemode;
  INT VAR line no;
  FOR line no FROM 1 UPTO lines (file) REP
    to line (file, line no);
    buffer cat file line;
    WHILE LENGTH buffer >= cluster size REP
      copy buffer to cluster;
      write disk cluster (cluster space, first non dummy ds page, next save cluster no);
      remember rest
    PER
  PER;
  cat ctrl z if necessary;
  write rest;
  close save (storage).

init save filemode:
  storage := 0.0;
  FILE VAR file := sequential file (modify, file space);
  SELECT code type OF
    CASE ascii, ascii german, atari st, transparent: cr lf := ""13""10""; ff := ""12""
    CASE ebcdic: cr lf := ""13"%"; ff := ""12""
  END SELECT;
  buffer := "".

buffer cat file line:
  exec (PROC (TEXT CONST, INT CONST) cat adapted line, file, code type).
 
copy buffer to cluster:
  write text (cluster, buffer);
  storage INCR real (min (cluster size, LENGTH buffer)).

remember rest:
  buffer := subtext (buffer, cluster size + 1).

write rest:
  WHILE buffer <> ""
    REP copy buffer to cluster; 
        write disk cluster (cluster space, first non dummy ds page, next save cluster no);
        remember rest
  PER.
 
cat ctrl z if necessary:
  IF code type <> ebcdic
    THEN buffer CAT ascii ctrl z
  FI.

END PROC enable save filemode; 
 
PROC cat adapted line (TEXT VAR line, INT CONST code type):
  IF subtext (line, 1, 6) = "#page#" 
      THEN buffer CAT ff;
           LEAVE cat adapted line
  FI;
  SELECT code type OF
    CASE transparent: (* no operation *)
    CASE ascii:        change eumel print chars; ascii change
    CASE ascii german: change eumel print chars; ascii german change
    CASE atari st:     change eumel print chars; atari st change
    CASE ebcdic:       change eumel print chars; eumel to ebcdic with substitution (line)
  END SELECT;
  buffer CAT line;
  buffer CAT cr lf.

change eumel print chars:
  INT VAR char pos := pos (line, ""220"", ""223"", 1);
  WHILE char pos > 0 REP
    replace (line, char pos, std char);
    char pos := pos (line, ""220"", ""223"", char pos + 1)
  PER.

std char:
  SELECT code (line SUB char pos) OF
    CASE 220: "k"
    CASE 221: "-"
    CASE 222: "#"
    CASE 223: " "
    OTHERWISE ""
  END SELECT.

ascii change: 
  change all (line, ""251"", "#251#");
  char pos := pos (line, "Ä", "ü", 1);
  WHILE char pos > 0 REP
    line := subtext (line, 1, char pos - 1) + ersatzdarstellung + subtext (line, char pos + 1);
    char pos := pos (line, "Ä", "ü", char pos + 1)
  PER.

ascii german change: 
  char pos := pos (line, "[", "]", 1);
  WHILE char pos > 0 REP
    line := subtext (line, 1, char pos - 1) + ersatzdarstellung + subtext (line, char pos + 1);
    char pos := pos (line, "[", "]", char pos + 1)
  PER;
  char pos := pos (line, "{", "}", 1);
  WHILE char pos > 0 REP
    line := subtext (line, 1, char pos - 1) + ersatzdarstellung + subtext (line, char pos + 1);
    char pos := pos (line, "{", "}", char pos + 1)
  PER;
  change all (line, ""251"", "~");
  char pos := pos (line, "Ä", "ü", 1);
  WHILE char pos > 0 REP
    replace (line, char pos, umlaut in ascii german);
    char pos := pos (line, "Ä", "ü", char pos + 1)
  PER.

atari st change: 
  change all (line, "ß", ""158"");
  char pos := pos (line, "Ä", "ü", 1);
  WHILE char pos > 0 REP
    replace (line, char pos, umlaut in atari st);
    char pos := pos (line, "Ä", "ü", char pos + 1)
  PER.

ersatzdarstellung:
  TEXT VAR char code := text (code  (line SUB char pos));
  "#" + (3 - LENGTH char code) * "0" + char code + "#".

umlaut in ascii german:
  SELECT code (line SUB char pos) OF 
    CASE 214: "["
    CASE 215: "\"
    CASE 216: "]"
    CASE 217: "{"
    CASE 218: "|"
    CASE 219: "}"
    OTHERWISE ""
  END SELECT.

umlaut in atari st:
  SELECT code (line SUB char pos) OF 
    CASE 214: ""142""
    CASE 215: ""153""
    CASE 216: ""154""
    CASE 217: ""132""
    CASE 218: ""148""
    CASE 219: ""129""
    OTHERWISE ""
  END SELECT.

END PROC cat adapted line;

PROC save rowtextmode (DATASPACE CONST space,
                       TEXT CONST name):
  disable stop;
  cluster space := nilspace;
  cluster := cluster space;
  enable save rowtext mode (space, name);
  forget (cluster space).

END PROC save rowtextmode;

PROC enable save rowtextmode (DATASPACE CONST space,
                              TEXT CONST name):
  enable stop;
  open save (name);
  init save row textmode;
  WHILE line no < cluster struct.size REP
    fill buffer;
    copy buffer to cluster;
    write disk cluster (cluster space, first non dummy ds page, next save cluster no);
    remember rest
  PER;
  write rest;
  close save (storage).

init save rowtextmode:
  storage := 0.0;
  cluster struct  := space;
  INT VAR line no := 0;
  TEXT VAR buffer := "".

fill buffer:
  WHILE line no < cluster struct.size AND NOT buffer full REP
    line no INCR 1;
    buffer CAT cluster struct.cluster row [line no]
  PER.

buffer full:
  LENGTH buffer >= cluster size.

copy buffer to cluster:
  write text (cluster, buffer);
  storage INCR real (min (cluster size, LENGTH buffer)).

remember rest:
  buffer := subtext (buffer, cluster size + 1).

write rest:
  WHILE buffer <> ""
    REP copy buffer to cluster; 
        write disk cluster (cluster space, first non dummy ds page, next save cluster no);
        remember rest
  PER.

END PROC enable save rowtextmode;
 
PROC save ds mode (DATASPACE CONST ds,
                   TEXT CONST name):
  disable stop;
  enable save ds mode (ds, name).

END PROC save ds mode;

PROC enable save ds mode (DATASPACE CONST ds,
                          TEXT CONST name):
  enable stop;
  open save (name);
  INT VAR page no := first non dummy ds page;
  get last allocated ds page; 
  WHILE page no <= last allocated ds page REP
    write disk cluster (ds, page no, next save cluster no);
    page no INCR sectors per cluster
  PER;
  close save (size).

get last allocated ds page:
  INT VAR last allocated ds page := -1, 
          i;
  FOR i FROM 1 UPTO ds pages (ds) REP
    last allocated ds page := next ds page (ds, last allocated ds page) 
  PER.

size:
  real (last allocated ds page - first non dummy ds page + 1) * 512.0.

END PROC enable save ds mode;

END PACKET save;