    ! 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