! Steering program: Set parameters, open files, call EDI, close files
!ECCExx:    Implementation of ECCE for 2900/EMAS, VAX/VMS and APM
!  Revised specification (1981/82) including video support.
!  Hamish Dewar   Edinburgh University Computer Science Department
!
constinteger  MAXNAME=127
!
recordformat  EDFILE(integer  START1,LIM1, {part 1}
                              START2,LIM2, {part 2}
                              LIM, {VMLIM}
                              LBEG,FP,CHANGE,FLAG,
                              LINE  {line number of current pos},
                              DIFF  {diff between LINE and ROW},
                              SHIFT {Amount of right shift of file window},
                     byte     TOP  {top row of sub_window},
                              WIN  {floating top},
                              BOT  {bottom row of sub_window},
                              MIN  {minimum window size},
                              ROW  {last row position},
                              COL  {last col position},
             string (maxname) NAME)
!
external routine spec  EDI(record (edfile)name  main,sec,
                         string (255) message)
external routine spec  CONNECT EDFILE(record (edfile)name  f)
external routine spec  DISCONNECT EDFILE(record (edfile)name  f)
externalroutinespec  SET PARAMETERS(string (maxname)name  in,sec,out,
                                    string (255) parm)
!$IF APM
{%externalstring(255)%fnspec CLIPARAM
{!
!$IF VAX or AMDAHL
!IMP syntax checking routine:
externalroutinespec  ECCECI(record (edfile)name  main)
!$FINISH

!
!$IF AMDAHL
externalroutinespec  SETLINE alias  "S#SETLINE"(string (255)s)
externalroutinespec  LINE alias  "S#LINE"(stringname  parm)
externalroutinespec  UCTRANSLATE alias  "S#UCTRANSLATE" (integer  addr, len)
externalroutinespec  SET RETURN CODE alias  "S#SETRETURNCODE"(integer  flag)
externalstringfnspec  FAILUREMESSAGE alias  "S#FAILUREMESSAGE" (integer  i)
externalroutinespec  PROMPT alias  "S#PROMPT"(string (255) p)
externalstring (127)fnspec  ITOS alias  "S#ITOS" (integer  i)
externalintegerfnspec  CHECK OUTPUT FILE (string (255)s,integer  default)
external  routine  spec  MAKE OUTPUT FILE(record (edfile)name  f)
external  routine  spec  BACKUP EDFILE(record (edfile)name  f)
external  integer  function  spec  EXISTTYPE alias  "S#EXISTTYPE"(string (255)f)
! The next two specs added to allow vecce to be called from within a command
! macro on emas-a - as per request of Tony Gibbons - I have no idea what they
! do - Graham Rule 23/03/87
externalintegerfnspec  INDEFAULT alias  "S#INDEFAULT"
externalroutinespec  SETIODEFAULT alias  "S#SETIODEFAULT"(integer  d,c,b)
external  integer  spec  tempid 
integer  function  set trap(integer  name  id, class, subclass)
   external  routine  spec  proc alias  "EMAS3SETTRAP"(integer  name  id,
      class, subclass, flag)
   integer  flag
   proc(id, class, subclass, flag)
   result  = flag
end ;                              ! Of %integer %function set trap.
integer  function  discard trap(integer  name  id)
   external  routine  spec  proc alias  "EMAS3DISCARDTRAP"(integer  name  id,
      flag)
   integer  flag
   proc(id, flag)
   result  = flag
end ;                              ! Of %integer %function discard trap.
external  routine  spec  reset context alias  "EMAS3RESETCONTEXT" C 
                               (integername  trap,flag)
external  routine  spec  set message control alias  "S#SETMESSAGECONTROL" C 
                                     (integer  type)
external  routine  spec  trap alias  "EMAS3TRAP"(integer  name  id, prot, flag)
external  routine  spec  give event alias  "EMAS3GIVEEVENT"(integer  c 
   name  class, subclass)
external  routine  spec  signal alias  "EMAS3SIGNAL"(integer  name  c 
   class, subclass)
external  routine  spec  allow interrupts alias  "S#ALLOWINTERRUPTS"
externalintegerfnspec  c 
     dmessage(stringname  user, integername  len, act, invoc, fsys, adr)
external  string  function  spec  UINFS alias  "s#uinfs"(integer  N)
externalroutinespec  tojournal alias  "S#TOJOURNAL" (integer  from, len)

include  "VTINC"

integerfn  vecce inner
integer  f,i,j,same,written,flag,class,subclass,trapno
string (255) heading,backmess
record (edfile) MAIN,SEC
string (maxname) OUTNAME,MAINNAME

  main = 0;  sec = 0
  set parameters(mainname,sec_name,outname,"")
  if  existtype(mainname)=0 and  (outname = "" or  outname = mainname) start 
     outname = mainname
     mainname = ""
  finish  
  main_name = mainname
  main_name = "" if  main_name = ".N" or  main_name = ".NULL"
  outname = main_name if  outname = ""
  outname = "" if  outname = ".N" or  outname = ".NULL"
  same = 0;  same = 1 if  outname = main_name
  if  outname # "" start 
    f = checkoutputfile(outname,same)
    if  f=219 or  f=287 start 
      printstring(" There already is a file ".outname)
      printstring(".  Are you happy to overwrite it?")
      newline
      prompt(" Y(es or N(o:")
      readsymbol(i) until  i > ' '
      readsymbol(j) until  j < ' '
      -> errstop unless  i&95 = 'Y'
      f=0
    finish 
    -> errstop if  f # 0
  finish 
  connect edfile(main)
  f = main_flag
  -> errstop if  f # 0
  connect edfile(sec)
  f = sec_flag
  -> errstop if  f # 0
!     Needed even for SHOW
!  %if outname # "" %start
    main_flag=main_lim2-main_start2+sec_lim2-sec_start2
    make output file(main)
    f = main_flag; -> errstop if  f#0
!!!!!!!Trap Handling!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  trap(trapno, 1, flag)
  if  flag # 0 start 
  ! This code is (somehow) branched to by the Subsystem when a
  ! trapped event (in this case an interrupt) occurs.
    ! Now write to :VECCE#SAVEn file.
    ! save current edit as if a %b had been done
    reset context(trapno,0)
    give event(class, subclass)
    i = discard trap(trapno)
    if  main_change=16_7FFFFFFF start ;      ! File Unchanged
      tempid = tempid - 1
    finishelseif  main_change # -1 start 
      main_name = ":VECCE#SAVE".itos(tempid)
      disconnect edfile(main)
      backmess = "Edit of ".mainname." saved in file ".main_name
      if  class = 69 or  ( class = 65 and  'V' <= subclass <= 'Y' ) start 
        set message control(1)
        i = dmessage(uinfs(1),length(backmess), 1, 0, -1, 1+addr(backmess))
      finish 
      backmess = tostring(nl).backmess.tostring(nl).tostring(nl)
      tojournal(1+addr(backmess),length(backmess))
      if  class # 65 or  subclass # 'Y' start 
        pop window;  win = vdu
        vt at(vdu_rows-1,0)
        printstring(backmess)
        set video mode(0)
      finish 
    finish 
    allow interrupts
    signal(class, subclass);        ! Propagate int back to Subsys - does not return.
  finish 
  i = set trap(trapno, 65, 'C')   ; !  Escape
  i = set trap(trapno, 65, 'A')   ; !  Escape
  i = set trap(trapno, 65, 'Q')   ; !  %monitor
  i = set trap(trapno, 65, 'V')   ; !  Terminal Booking
  i = set trap(trapno, 65, 'W')   ; !  Inactivity
  i = set trap(trapno, 65, 'X')   ; !  Operator log-off
  i = set trap(trapno, 65, 'Y')   ; !  Terminal Disconnected
  i = set trap(trapno, 69, 1)     ; !  Stop, Quit
  i = set trap(trapno, 69, 2)     ; !  Logoff
  i = set trap(trapno, 17, -1)    ; !  CPU time exceeded
!$IF VAX
{%externalintegerfnspec SET FILE DEFAULT (%string(127) DEF, %integername exists)
{! Alias for lattice imp
{! %externalstring(72)%fnspec SYSMESS %alias "IMP_GET_MESSAGE"(%integer i)
{%externalstring(72)%fnspec SYSMESS (%integer i)
{%begin
{%integer f,i,same,written, exists
{%string(255) heading
{%record(edfile) MAIN,SEC
{%string(maxname) OUTNAME,MAINNAME
{  main = 0; sec = 0
{  set parameters(mainname,sec_name,outname,"")
{  main_name=mainname
{  main_name = "" %if main_name = ".N" %or main_name = "NL:"
{  i = set file default(main_name,exists)
{  printstring(sysmess(i)) %and -> stop %if i # 0
{  %if exists = 0 %and Out Name = "" %start
{    Out Name = main_name;  main_name = "" 
{  %finish
{  same = 0;  same = 1 %if main_name = outname
{  %if outname = "" %start
{    same = 1
{    outname = main_name %unless main_name -> outname.(";"); ! No version number neede in outname
{  %finish
{  outname = "" %if outname = ".N"
{  %if sec_name # "" %start
{    connect edfile(sec)
{    -> stop %if sec_flag # 0
{    main_flag = sec_lim2-sec_start2; !size of sec file
{  %finish
{  main_flag = main_flag+16384;           !extra space
{  connect edfile(main)
{  -> stop %if main_flag # 0
!$IF APM
{%begin
{%integer i,same,written
{%string(255) heading
{%record(edfile) MAIN,SEC
{%string(maxname) OUTNAME,MAINNAME
{  main = 0; sec = 0
{  set parameters(main_name,sec_name,outname,cliparam)
{  main_name = "" %if main_name = ".N"
{  outname = main_name %if outname = ""
{  outname = "" %if outname = ".N"
{  same = 0;  same = 1 %if outname = main_name
{  main_flag = 32768;  !plus extra
{  connect edfile(main)
{  -> stop %if main_flag # 0
{  %if sec_name # "" %start
{    connect edfile(sec)
{    -> stop %if sec_flag # 0
{  %finish
!$FINISH
  if  outname # "" start 
    if  main_name # "" start  
      heading = " Editing  ".main_name
      heading = heading." with ".sec_name if  sec_name # ""
      heading = heading."  to  ".outname if  same = 0
    finish  else  start 
      heading = " Creating  ".outname
    finish 
    main_change = 16_7FFFFFFF
  finish  else  start 
    heading = " Showing  ".main_name
    main_change = -1
  finish 
!
  written=0
  main_lim1 = main_start1;  sec_lim1 = sec_start1
  main_fp = main_start2
again:
  main_name = outname
  main_flag=0
!  CALL editor
  edi(main,sec,heading)
!$IF AMDAHL
  uctranslate(addr(main_name)+1,length(main_name))
  same=0; same=1 if  main_name=mainname 
  if  outname # "" and  same=0 start ; ! If new output file was specified
    f = checkoutputfile(main_name,1);  ! Check for name and existence
    if  f#0 start 
      heading=failuremessage(f)
      -> again
    finish 
  finish 
!$IF VAX
{  same=0; same=1 %if main_name=mainname 
!$IF AMDAHL or VAX
  if  main_flag!32='b' start ;   !Backup file
    if  outname="" or  (main_change=16_7FFFFFFF and  same # 0 and  written=0) start 
      Heading= " File unchanged - not backed up"
      -> again
    finish 
    heading=""
!$IF AMDAHL
    backup edfile(main);              ! Create backup file
    if  main_flag#0 start 
      heading=failuremessage(main_flag)." - "
      main_name=":VECCE#SAVE"
    finish 
!$IF VAX
{    disconnect edfile(main)
{    main_change=16_7FFFFFFF 
!$IF VAX OR AMDAHL
    heading=heading." Backed up to ".main_name
    written=0
    written=1 if  main_name#outname;       ! Flag for default output file backup
    -> again
  finish 
  ecceci(main) if  main_flag!32 = 'i'
!$FINISH
!
!MAIN_FLAG is negative if edit abandoned
!MAIN_CHANGE is untouched (neg or inf) if no changes
  if  (main_flag < 0 and  outname # "") or  (main_change = 16_7FFFFFFF and  same # 0 and  written=0) start 
    print string(" File unchanged")
    main_change = -1
!$IF VAX OR APM
{  %finish
!$IF AMDAHL
  if  trapno>=0 then  i = discard trap(trapno)
  finish 
  if  main_change >= 0 start ;  !file to be written
    disconnect edfile(main)
    f = main_flag
    if  f # 0 start 
      printstring(failuremessage(f)." - Edited file left in :VECCE#SAVE") 
    finishelse  printstring(mainname."  edited to  ".main_name)
  else 
    tempid = tempid - 1;                       ! Discard current temporary file.
  finish 
  f=0
errstop:
  newline
  result  = f
end ;                                   !OF VECCE

external  routine  vecce alias  "C#VECCE"
integer  save in default, flag
  save in default = indefault
  flag = vecce inner
  set io default(0, save in default, 0)
  set return code(flag)
end 

externalroutine  VSHOW alias  "C#VSHOW"
string (255)parm
integer  flag
integer  save in default
  save in default = indefault
  line(parm)
  setline(parm.",OUTPUT=.NULL")
  flag = vecce inner
  set io default(0, save in default, 0)
  set return code(flag)
end 

externalroutine  VRECAP alias  "C#VRECAP"
externalroutinespec  emas3getjournal (stringname  file,integername  flag)
string (255)file, parm
integer  flag, save in default
   line(parm)
   emas3 get journal(file,flag)
   if  flag=0 thenstart 
      if  parm="" then  setline(file) c 
      elseif  charno(parm,1)=',' then  setline(file.parm) c 
      else  setline(file.",".parm)
      flag = vecce inner
      set return code(flag)
   finishelse  set return code(flag)
end 

!$IF VAX or APM
{  disconnect edfile(main)
{  %if main_change >= 0 %start;  !file written
{    printstring(mainname."  edited to ")
{    newline %if length(mainname) > 30
{    printstring(main_name)
{  %finish
{  %if sec_start1 # 0 %start
{    sec_change = -1
{    disconnect edfile(sec)
{  %finish
{stop:
{  newline
{%ENDOFPROGRAM
!$FINISH
ENDOFFILE