========== file primitives for scratch file editor ==========
define(PREV,0)
define(NEXT,1)
define(MARK,2)
define(SEEKADR,3)
define(LENG,4)
define(BUFENT,5)
define(MAXBUF,1000)
define(LINE0,1)
common /cbuf/ buf(MAXBUF), lastbf
   character buf   # structure of pointers for all lines:
   # buf(k+0)   PREV      previous line
   # buf(k+1)   NEXT      next line
   # buf(k+2)   MARK      mark for global commands
   # buf(k+3)   SEEKADR   where line is on scratch file
   # buf(k+4)   LENG      length on scratch
   integer lastbf   # last pointer used in buf
common /cscrat/ scr, scrend
   integer scr      # scratch file id
   integer scrend   # end of info on scratch file
# clrbuf  (scratch file) - dispose of scratch file
   subroutine clrbuf
   include cscrat
#   string scrfil "scratch"
   integer scrfil(8)
   data scrfil(1)/LETS/
   data scrfil(2)/LETC/
   data scrfil(3)/LETR/
   data scrfil(4)/LETA/
   data scrfil(5)/LETT/
   data scrfil(6)/LETC/
   data scrfil(7)/LETH/
   data scrfil(8)/EOS/
   call close(scr)
   call remove(scrfil)
   return
   end
# gettxt (scratch file) - locate text for line, copy to txt
   integer function gettxt(line)
   integer getbuf, getind
   integer j, k, line
   include cbuf
   include cscrat
   include ctxt
   k = getind(line)
   call seek(buf(k + SEEKADR), scr)
   call readf(txt, buf(k + LENG), scr)
   j = buf(k + LENG) + 1
   txt(j) = EOS
   gettxt = k
   return
   end
# inject  (scratch file) - insert lin after curln, write scratch
   integer function inject(lin)
   character lin(MAXLINE)
   integer getind, maklin, nextln
   integer i, k1, k2, k3
   include clines
   for (i = 1; lin(i) ~= EOS; ) {
      i = maklin(lin, i, k3)
      if (i == ERR) {
         inject = ERR
         break
         $@$
      k1 = getind(curln)
      k2 = getind(nextln(curln))
      call relink(k1, k3, k3, k2)
      call relink(k3, k2, k1, k3)
      curln = curln + 1
      lastln = lastln + 1
      inject = OK
      $@$
   return
   end
# maklin (scratch file) - make new line entry, copy text to scratch
   integer function maklin(lin, i, newind)
   character lin(MAXLINE)
   integer addset, length
   integer i, j, junk, newind, txtend
   include cbuf
   include cscrat
   include ctxt
   maklin = ERR
   if (lastbf + BUFENT > MAXBUF)
      return         # no room for new line entry
   txtend = 1
   for (j = i; lin(j) ~= EOS; ) {
      junk = addset(lin(j), txt, txtend, MAXLINE)
      j = j + 1
      if (lin(j - 1) == NEWLINE)
         break
      $@$
   if (addset(EOS, txt, txtend, MAXLINE) == NO)
      return
   call seek(scrend, scr)   # add line to end of scratch file
   buf(lastbf + SEEKADR) = scrend
   buf(lastbf + LENG) = length(txt)
   call putlin(txt, scr)
   scrend = scrend + buf(lastbf + LENG)
   buf(lastbf + MARK) = NO
   newind = lastbf
   lastbf = lastbf + BUFENT
   maklin = j         # next character to be examined in lin
   return
   end
# setbuf (scratch file) - create scratch file, set up line 0
   subroutine setbuf
   integer create
   integer k
   include cbuf
   include clines
   include cscrat
#   string scrfil "scratch"
   integer scrfil(8)
#   string null ""
   integer null(1)
   data scrfil(1)/LETS/
   data scrfil(2)/LETC/
   data scrfil(3)/LETR/
   data scrfil(4)/LETA/
   data scrfil(5)/LETT/
   data scrfil(6)/LETC/
   data scrfil(7)/LETH/
   data scrfil(8)/EOS/
   data null(1) /EOS/
   scr = create(scrfil, READWRITE)
   if (scr == ERR)
      call cant(scrfil)
   scrend = 0
   lastbf = LINE0
   call maklin(null, 1, k)   # create empty line 0
   call relink(k, k, k, k)      # establish initial linked list
   curln = 0
   lastln = 0
   return
   end
