Google
 

Trailing-Edge - PDP-10 Archives - decuslib20-03 - decus/20-0078/libsim/dbmtxt.sim
There is 1 other file named dbmtxt.sim in the archive. Click here to see a list.
OPTIONS(/external);
EXTERNAL REF (Infile) PROCEDURE findinfile;
EXTERNAL REF (Outfile) PROCEDURE findoutfile;
EXTERNAL TEXT PROCEDURE conc,upcase,frontstrip,rest,checkextension;
EXTERNAL CHARACTER PROCEDURE fetchar,findtrigger;
EXTERNAL LONG REAL PROCEDURE scanreal;
EXTERNAL INTEGER PROCEDURE checkreal,checkint,scanint,ilog;
EXTERNAL BOOLEAN PROCEDURE menu;
EXTERNAL CLASS safeio;
safeio CLASS dbmtxt;
VIRTUAL: PROCEDURE dbadr;
BEGIN
  CHARACTER cdelim,nullc,split_char;
  TEXT delim,slash;
  BOOLEAN defined__f,array__in;
  INTEGER k__,rlength,next__pos;
  TEXT a__t,t_t,oldt_t;

  ! -------------------------------------------------------
  Classes for dynamic representation of arrays. They are created
  from the text a_t which should, when e g new int__arr(7) is
  executed contain all the elements (in this case seven integers
  separated with spaces) as required by the
  procedures NEXT*** ( ***=INT,REAL or TEXT) as specified below
  ________________________________________________________;

  CLASS int__arr(dim); INTEGER dim;
  BEGIN INTEGER ARRAY vekt(1:dim); oldt_t:-t_t; t_t:-a__t;
    FOR k__:=1 STEP 1 UNTIL dim DO vekt(k__):=nextint;
    t_t:-oldt_t;
  END of int__arr;

  CLASS real__arr(dim); INTEGER dim;
  BEGIN REAL ARRAY vekt(1:dim);oldt_t:-t_t; t_t:-a__t;
    FOR k__:=1 STEP 1 UNTIL dim DO vekt(k__):=nextreal;
    t_t:-oldt_t;
  END of real__arr;

  CLASS text__arr(dim); INTEGER dim;
  BEGIN TEXT ARRAY vekt(1:dim+1);oldt_t:-t_t; t_t:-a__t;
    FOR k__:=1 STEP 1 UNTIL dim DO vekt(k__):-nexttext;
    t_t:-oldt_t;
  END of text__arr;

  PROCEDURE stringrequest(prompt,default,variable,
  validity,errmessage,help);
  ! -----------------------------------------------------------
  Analoguous to the REQUEST procedure in SAFEIO, except that
  the input string may be several lines, is started with a
  special character (not contained in string) and terminated
  by the next occurence of that character.
  -------------------------------------------------------;
  NAME default,validity,errmessage,variable,prompt,help;
  TEXT prompt,default,variable,errmessage;   BOOLEAN validity;
  BOOLEAN help;
  BEGIN   CHARACTER c1,c2;   TEXT t;   BOOLEAN saveswitch;
    saveswitch:= displaydefault;
    start:
    request(prompt,default,textinput(variable,TRUE),NOTEXT,help);
    IF variable == NOTEXT THEN
    BEGIN
      IF validity THEN GO TO exit;
      error:
      outline(errmessage);   GO TO start
    END notext;
    c1:= variable.Getchar;
    IF variable.Length > 1 THEN
    c2:= variable.Sub(variable.Length,1).Getchar;
    displaydefault:= FALSE;
    WHILE c1 NE c2 DO
    BEGIN   t:- NOTEXT;
      WHILE t == NOTEXT DO
      request(NOTEXT,NOTEXT,textinput(t,TRUE),NOTEXT,help);
      variable:- conc(variable,t);
      c2:= t.Sub(t.Length,1).Getchar;
    END loop;
    IF NOT validity THEN GO TO error;
    exit:
    displaydefault:= saveswitch;
    IF variable.Length > 2 THEN
    variable:-variable.Sub(2,variable.Length-2);
  END of stringrequest;

  REF (Directfile) PROCEDURE opendf;
  ! -------------------------------------------------------
  Prompt the user to give name and imagesize for direct file
  Check if the first record of the file is nonempty, if so
  it is assumed to be an existent SIMDBM data base, and the
  varaible DEFINED__F is set true
  ___________________________________________________________;
  BEGIN TEXT t,u; REF (Directfile) d;
    request("Give name of data base file: ",
    "x.tmp",textinput(t,TRUE),"?",
    help("Name of an existent SIMDBM data base"));
    request("image size:","72",textinput(u,checkint(u) > 0),
    "Must be integer",
    help("Optimal choice: multiple of five - 2"));
    d:-NEW Directfile(conc(t,conc(Copy("/imagesize:"),u)));
    rlength:=u.Getint;
    d.Open(Blanks(rlength));
    opendf:-d;
    INSPECT d DO
    BEGIN ! check if it is an initialized DBMSIM file;
      Locate(1); IF \Endfile THEN
      BEGIN
	Inimage; IF Image.Strip \= "/*" THEN
	defined__f:=TRUE;
    END;END;
  END of opendf;

  INTEGER PROCEDURE loc(t,seekc,stopc); NAME t;
  ! -----------------------------------------------------
  Return as value POS for the character following the
  next occurence (after POS) of the character SEEKC in T.
  Return LOC=0 if SEEKC isn't found or if STOPC is found
  before SEEKC.
  ---------------------------------------------------------;
  TEXT t; CHARACTER seekc,stopc;
  BEGIN CHARACTER c;
    l1: IF t.More THEN c:=t.Getchar ELSE
    BEGIN loc:=0; GOTO fin; END; IF c = seekc THEN
    BEGIN loc := t.Pos; GOTO fin; END;
    IF c = stopc THEN BEGIN loc := 0; GOTO fin; END;
    GOTO l1;
    fin:
  END of loc;

  TEXT PROCEDURE locfield(t,n); TEXT t; INTEGER n;
  ! ----------------------------------------------------------
  Locate nth string in text t.  A string is either a number with
  spaces around it, or a text starting and ending with the same
  special character.
  The global variable NEXT__POS points after the located string
  on exit from LOCFIELD.
  ___________________________________________________________;
  BEGIN CHARACTER c,cc; INTEGER i; BOOLEAN error;

    BOOLEAN PROCEDURE digsign(c); CHARACTER c;
    digsign:=Digit(c) OR
    c = '.' OR c = '+' OR c = '-';

    CHARACTER PROCEDURE getch;
    IF t.More THEN getch:=t.Getchar ELSE
    BEGIN error:=TRUE; GOTO fin; END;

    c := ' ';
    next:
    WHILE c = ' ' DO c := getch;
    i := i + 1; IF i < n THEN
    BEGIN COMMENT bypass one more field;
      cc := nullc;
      IF digsign(c) THEN
      BEGIN WHILE c \= ' ' DO  c := getch; END ELSE
      BEGIN COMMENT bypass non-numeric string;
	WHILE cc \= c DO cc := getch; c := ' ';
      END;
      GOTO next;
    END;
    COMMENT pick up next string and return as value;
    i := t.Pos - 1;
    IF digsign(c) THEN BEGIN WHILE c \= ' ' DO
    c := getch; END ELSE
    BEGIN i := i+1; cc := nullc;
    WHILE cc \= c DO cc := getch; END;
    fin: IF NOT error THEN
    locfield :- Copy(t.Sub(i,t.Pos-i-1));
    next__pos:=t.Pos;
  END of locfield;

  CHARACTER PROCEDURE leftchar;
  BEGIN CHARACTER c;
    c:=' ';
    WHILE c = ' ' AND t_t.More DO c:=t_t.Getchar;
    t_t.Setpos(t_t.Pos-1);
    leftchar:=c;
  END of leftchar;

  !------------------------------------------------------
  The following six procedures are used to pick one
  element from a text, either
  A number
  A text surrounded with quotes
  An array surrounded with slashes.
  The variable array__in is used to capture the end
  of an array.
  -------------------------------------------------------;

  INTEGER PROCEDURE nextint;
  IF leftchar = '/' THEN array__in:=FALSE ELSE
  BEGIN
    t_t:-rest(t_t);
    IF checkint(t_t) > 0 THEN nextint:=t_t.Getint ELSE
    BEGIN
      outline("Nextint:  Illegal integer item in line:");
      outline(t_t);
    END;
  END of nextint;

  REAL PROCEDURE nextreal;
  IF leftchar = '/' THEN array__in:=FALSE ELSE
  BEGIN
    t_t:- rest(t_t);
    IF checkreal(t_t) > 0 THEN nextreal:=t_t.Getreal ELSE
    BEGIN
      outline("Nextreal:  Illegal real item in record:");
      outline(t_t);
    END;
  END of nextreal
  ;
  REF (int__arr) PROCEDURE nextiarr;
  BEGIN
    array__in:=TRUE; IF leftchar = '/' THEN
    BEGIN
      t_t.Setpos(t_t.Pos+1); k__:=0;
      a__t:-rest(t_t); nextint;    WHILE array__in DO
      BEGIN k__:=k__+1; nextint; END;
      t_t.Setpos(t_t.Pos+1);
      IF k__ > 0 THEN nextiarr:-NEW int__arr(k__);
    END;
  END of nextiarr;


  REF (real__arr) PROCEDURE nextrarr;
  BEGIN
    array__in:=TRUE; IF leftchar = '/' THEN
    BEGIN
      t_t.Setpos(t_t.Pos+1); k__:=0;
      a__t:-rest(t_t); nextreal;
      WHILE array__in DO
      BEGIN k__:=k__+1; nextreal; END;
      t_t.Setpos(t_t.Pos+1);
      IF k__ > 0 THEN nextrarr:-NEW real__arr(k__);
    END;
  END of nextrarr;

  REF (text__arr) PROCEDURE nexttarr;
  BEGIN
    array__in:=TRUE; IF leftchar = '/' THEN
    BEGIN
      t_t.Setpos(t_t.Pos+1); k__:=0;
      a__t:-rest(t_t); nexttext;        WHILE array__in DO
      BEGIN k__:=k__+1; nexttext; END;
      t_t.Setpos(t_t.Pos+1);
      IF k__ > 0 THEN nexttarr:-NEW text__arr(k__);
    END;
  END of nexttarr;

  TEXT PROCEDURE nexttext;
  IF leftchar = '/' THEN array__in:=FALSE ELSE
  BEGIN CHARACTER c; INTEGER n;

    WHILE t_t.More DO
    BEGIN
      c := t_t.Getchar; IF c = cdelim THEN
      BEGIN
	n := t_t.Pos; WHILE t_t.More DO
	BEGIN
	  c := t_t.Getchar; IF c = cdelim THEN
	  BEGIN nexttext:-Copy(t_t.Sub(n,t_t.Pos-n-1)); GOTO fin; END;
	END;
      END;
    END;
    outline("Nexttext:  missing text delimiter in record:");
    outline(t_t);
    nexttext:-Copy("???");
  fin:  END of nexttext;

  !------------------------------------------------------
  Procedures to store an item in a text,from pos
  and upwards, and adjusting pos of that text.
  Numbers are surrounded with spaces, texts with quotes
  and arrays with slashes. These procedures are reverses
  of the six above procedures.
  If there is not room after pos then the text
  will be expanded with blanks.
  (ROOMCHECK is used to check this)
  -------------------------------------------------------;

  PROCEDURE puti(i,t); NAME t; INTEGER i; TEXT t;
  putnumber(intput(i),t); !END of puti;

  PROCEDURE putr(r,t); NAME t; REAL r; TEXT t;
  putnumber(realput(r),t); ! END of putr;

  PROCEDURE putiarr(a,t); NAME t;
  REF (int__arr) a; TEXT t;
  BEGIN INTEGER n;
    n:=a.dim; putnumber(slash,t);
    FOR k__:=1 STEP 1 UNTIL n DO puti(a.vekt(k__),t);
    putnumber(slash,t);
  END of putiarr;

  PROCEDURE putrarr(a,t); NAME t;
  REF (real__arr) a; TEXT t;
  BEGIN INTEGER n;
    n:=a.dim; putnumber(slash,t);
    FOR k__:=1 STEP 1 UNTIL n DO putr(a.vekt(k__),t);
    putnumber(slash,t);
  END of putrarr;

  PROCEDURE puttarr(a,t); NAME t;
  REF (text__arr) a; TEXT t;
  BEGIN INTEGER n;
    n:=a.dim; putnumber(slash,t);
    FOR k__:=1 STEP 1 UNTIL n DO putt(a.vekt(k__),t);
    putnumber(slash,t);
  END of puttarr;

  PROCEDURE roomcheck(u,t); NAME t; TEXT u,t;
  BEGIN INTEGER n;
    IF t.Length-t.Pos < u.Length+3 THEN
    BEGIN ! replace t with a longer text;
      n:=t.Pos;
      t:-conc(t,Blanks(u.Length+4)); t.Setpos(n);
    END;
  END of roomcheck;

  PROCEDURE putnumber(u,t); NAME t; TEXT u,t;
  BEGIN ! output text without quotes;
    roomcheck(u,t);
    t.Sub(t.Pos,u.Length) := u; t.Setpos(t.Pos+1+u.Length);
  END of putnumber;

  PROCEDURE putt(u,t); NAME t; TEXT u,t;
  BEGIN
    IF u.Length = 0 THEN u:-Copy("notext");
    roomcheck(u,t);
    t.Sub(t.Pos,1) := delim; t.Sub(t.Pos+1,u.Length) := u;
    t.Sub(t.Pos+1+u.Length,1) := delim;
    t.Setpos(t.Pos+3+u.Length);
  END of putt;

  INTEGER PROCEDURE dbadr(t,bsize,base); TEXT t;
  INTEGER bsize,base;
  !---------------------------------------------------------
  Computing of a pseudo-adres within a database-area.
  ---------------------------------------------------------;
  BEGIN INTEGER n;
    t.Setpos(1); IF checkint(t) > 0 THEN n:=t.Getint ELSE
    WHILE t.More DO n := n + Rank(t.Getchar);
    dbadr := Mod(n,bsize) + base;
  END of dbadr;

  INTEGER PROCEDURE loctext(t,a); TEXT t; TEXT ARRAY a;
  !---------------------------------------------------------
  Locate text t in array a, if present return index
  for it otherwise return zero. a should be logically
  ended with an element=NOTEXT.
  ---------------------------------------------------------;
  BEGIN INTEGER n;
    FOR n:= n+1 WHILE a(n) =/= NOTEXT DO
    IF t=a(n) THEN BEGIN loctext:=n; GOTO fin; END;
  fin:  END of loctext;


  INTEGER PROCEDURE split(t,txarr);
  TEXT t; TEXT ARRAY txarr;
  !---------------------------------------------------------
  Text t contains characters separated into groups with a
  delimiter SPLIT_CHAR. SPLIT separates t into parts and
  delivers each part as one element in TXARR.
  Number of elements is returned as value.
  TXARR should be at least 1 longer than the number of
  elements.
  The element after the last is set=NOTEXT.
  To facilitate:
  Example:

  if SPLIT_CHAR =',' and
  t = "A,B,CCC,DD,FGH"
  then the call  n:=split(t,txarr)
  will give n=5 and
  txarr(1)="A"
  txarr(2)="B"
  .......
  txarr(6)=notext
  ---------------------------------------------------------;
  BEGIN CHARACTER c; INTEGER n,k;
    n:=1; k:=0; t.Setpos(1);
    WHILE t.More DO
    BEGIN
      c:=t.Getchar; IF c = split_char THEN
      BEGIN
	k:=k+1; txarr(k):-Copy(t.Sub(n,t.Pos-n-1)); n:=t.Pos;
      END;
    END;
    IF t.Length > 0 THEN
    BEGIN  k:=k+1; txarr(k):-Copy(t.Sub(n,t.Length-n+1)); END;
    txarr(k+1):-NOTEXT;
    split:=k;
  END of split;


END of class dbmtxt;