!**********************************************************************
!**
!** A P M    C L E A N    -  An implementation of VAX Clean for the APMs
!**
!**  7/3/84 AJS - First Implementation - no cross directory ops
!**         MDP - Added Hexdump & Vecce
!** 20/4/84 AJS - Added IE properly & added wildcard filenames
!** 24/7/84 JGH - Fixed a bug were valid permissions were flagged as invalid!
!**
!**

%conststring(8) version = "24/07/84"

%include "inc:util.imp"
%include "inc:fs.imp"
%include "inc:fsutil.imp"
%include "ie:ie.inc"
%include "inc:ecce.imp"
%include "inc:vtlib.imp"

%Owninteger eod=0
%Ownstring(63) fsp
%Ownstring(6) user
%owninteger depth = 0

%Routine Skip Blanks (%string(*)%name it)

   %return %if length(it) = 0
   it = substring(it,2,length(it)) %while charno(it,1) = 32 %and it#""
%end

%Routine Truncate Blanks (%string(*)%name it)

   %return %if length(it) = 0
   length(it) = length(it)-1 %while charno(it,length(it)) =' ' %and length(it)#0
%End
   

%Routine Print Filename (%string(12) f)

   spaces (15-length(f))
   printstring (f)
   space
%end

%Routine Type File (%string(63) file,%Integer n)

   %integer sym,m=0

   %on 0,3,4,9 %start
      close input
      select input (0)
      %if event_event = 9 %and event_sub = 3 %start
         printline (event_message)
         %return
      %finish
      newline
      newline
      %return
   %Finish

   open input (2,file)
   %while m # n %cycle
      read symbol (sym)
      print symbol (sym)
      m = m + 1 %if sym = nl
   %repeat
   close input
   select input (0)
%end

!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
%routine Ecce (%string (255) Param Line)

  %integer i,same
   %string(255) heading

   %ownrecord(edfile) MAIN=0,SEC=0
   %ownstring(maxname) OUTNAME
   !
   %routine SET PARAMETERS(%string(255) ecce in)
   
      %if ecce in -> ecce in .("/"). out name %start
         main_name = ecce in
      %else
         main_name = ecce in
         main_name = "" %if main_name = ".N"
         outname = main_name
      %finish
      outname = "" %if outname = ".N"
   %end;  !SET PARAMETERS

   %on 0 %start
      select input (0)
      select output (0)
{}    pop frame; pop frame
{}    set mode(0)
!!    pop window; pop window
!!    set video mode (0)
      printsymbol (27) ; printsymbol ('>')
      newline
      %return
   %finish

   Set parameters (param line)
   same = 0;  same = 1 %if outname = main_name
   main_flag = 32768;  !plus extra
   connect edfile(main)
   -> stop %if main_flag # 0

   %if outname # "" %start
      %if main_name # "" %start 
        heading = "Editing  ".main_name
        heading = heading."  to  ".outname %if same = 0
      %finish %else %start
        heading = "Creating  ".outname
      %finish
   %finish %else %start
      main_change = -1
      heading = "Showing  ".main_name
   %finish

   main_lim1 = main_start1;  sec_lim1 = sec_start1
   main_fp = main_start2;  main_change = 16_7FFFFFFF
   edi(main,sec,heading)

!MAIN_FLAG is negative if edit abandoned
!MAIN_CHANGE is untouched (neg or zero) if no changes

   %if main_flag < 0 %or (main_change = 16_7FFFFFFF %and same # 0) %start
     print string(" File unchanged")
     main_change = -1
   %finish
 
   %if main_change >= 0 %start;  !file to be written
     sec_name = main_name;  main_name = outname
     disconnect edfile(main)
     printstring(sec_name."  edited to  ".main_name)
   %finish
   newline
stop:
%end

%routine Call IE (%string (80) fname)
   %string (255) Profile = ""
   %integer sl, sc

   %on 0, 3, 4, 9, abort %start
      Reset Terminal
      select input (0); select output (0)
      printline("IE fails ".event_message)
      %return
   %finish

   terminal serial number = default terminal
   journal file = default journal
   Set Up Terminal
   sl = 1
   sc = 1
   IE Editor (fname, fname, 0, 23, sl, sc, default profile, %c
              default keyboard, reset heap ! confirm)
!!   *move heapnow,d6
   Reset Terminal
   select input (0) ; select output (0)
   New Line
%end

%routine Count Lines (%string(63) file)

   %integer sym,m=0

   %on 0,3,4,9 %Start
      close input 
      select input (0)
      %if event_event=9 %and event_sub=3 %start
         printline (event_message)
         %return
      %finish
      %unless event_event = 0 %Start
          Printstring ("File is ")
          Write (m,0)
          printline (" lines long")
      %Finish
      %return
   %Finish
      
   open input (2,file)
   %cycle
      read symbol (sym)
      m = m + 1 %if sym = nl
   %repeat
%End

%routine Dump file (%string (255) File, %integer Lines)

   %byte %array Line (0:1023)
   %integer Line Length, Line Number = 0
   %integer Sym, Offset = 0

   %routine Dump Line
      
      %integer Start, T Start, T End
      %integer I, Sym

      Line Number = Line Number + 1
      Print String ("Line ")
      Write (Line Number, 0)
      New Line
      Start = 0

      %cycle
         T Start = Start
         %if Line Length > 16 %start
            T End = T Start + 15
            Start = Start + 16
            Line Length = Line Length - 16
         %else
            T End = Start + Line Length - 1
            Line Length = 0
         %finish

         Phex (Offset)
         Print String (": ")
         Offset = Offset + (T End - T Start + 1)

         %for I = T Start, 1, T End %cycle
            P Hex2 (Line (I))
            Space
         %repeat
 
         Spaces (48 - 3 * (T End - T Start + 1))
         Print String ("| ")

         %for I = T Start, 1, T End %cycle
            Sym = Line (I)
            Sym = Sym & 16_7f
            %if Sym < ' ' %or Sym = 16_7f %then Sym = '_'
            Print Symbol (Sym)
         %repeat
         New Line
      %repeat %until Line Length = 0
   %end

   %on 0,3,4,9 %start
      %if event_event=9 %and event_sub = 3 %start
         printstring (event_message)
         newline
      %else %if event_event = 0
         newline
      %Finish
      -> End Dump
   %finish

   Open Input (2, File)
   Select Input (2)

   %while Lines # 0 %cycle
      Line Length = 0
      %cycle
         Read Symbol (Sym)
         Line (Line Length) = Sym
         Line Length = Line Length + 1
         %if Line Length = 1024 %start
            Read symbol (Sym) %until Sym = 'Nl'
         %finish
      %repeat %until Sym = Nl

      Dump Line
      Lines = Lines - 1
   %repeat

End Dump:
   Close Input
   Select Input (0)
   Print String ("File ".File." Dumped, ".I to S(Line Number,0)." Lines")
   New Line
%end

%Routine Print Help
!   printline ("A <file> to append the file to another file")
   printline ("C <file> to copy the file into another file")
   printline ("D to delete the file")
   printline ("E to quit the program")
   printline ("F <filespec> to change temporarily to a new filespec")
   printline ("H to type this information")
   printline ("I to display file details")
   printline ("IE to edit the current file using IE")
   printline ("K to count the number of lines in the file")
!   printline ("L to list the remaining files in the current directory")
   printline ("N <newfile> to rename the file to newfile")
   printline ("P to change the file protection")
   printline ("Q to quit the program")
   printline ("R to restart from the top")
   printline ("T <n> to type out the first n lines of the file")
   printline ("V to edit the current file using VECCE")
   printline ("X <n> to hexdump the first n records of the file")
   printline ("<cr> to go on to the next file")
%End

%Routine Open Directory

   %on 3,4,9 %start
      eod = 1
      select input (0)
      %return
   %finish

   Open Input (1,user.":directory")
%end

%Routine Get Next File

   %on 3,4,9 %start
      eod = 1
      select input (0)
      %return
   %finish

   Select Input (1)
   Read Line (fsp)
   Select Input (0)
%End
   
%routine parm Complain
   printstring ("Missing parameter");newline
%End

%Integerfn toint (%String(80) s)

   %on 3 %start
      %result = -1
   %finish

  %result = Stoi (s)
%end

%Routine Do A File (%String(63) thisfile)

   %string (255) Fcomms
   %string(80) line,com
   %string(63) fname1,fname2
   %byte c,fp
   %integer n1
   %switch sw ('A':'Z')

   %Integerfn Get Integer
      %integer i
      %if fp = 0 %start
         %if length (line) > 1 %start
            i = toint(substring(line,2,length(line)))
         %else
            i = 999999
         %finish
      %else
         i = toint (fname1)
      %finish
      %result = i
   %end

   %on 3,4,9 %start
      %if event_sub = 3 %Start
         printline (event_message)
         -> again
      %finish
      newline
      %stop
   %finish

again:
   %Cycle
      to Lower(thisfile)
      prompt("")
      print filename (thisfile)
      Read Line (line)
      Skip Blanks (line)
      to Upper(line)
      %return %if line = ""
      %if line -> line.(" ").fname1 %start
         skipblanks (fname1)
         truncateblanks (fname1)
         %if fname1 -> fname1.(" ").fname2 %start ; %finish
         fp = 1
      %Else
         fp = 0 
      %Finish
      fp = 0 %if fname1=""
      c=charno(line,1)
      -> sw (c) %if 'A'<=c<='Z'

sw(*): Printstring ("Unrecognised command ")
       printsymbol (c)
       Newline
       Newline
       -> Help

sw('C'):
       Parm Complain %and %Continue %if fp = 0
       to lower(fname1)
       copy (thisfile,fname1)
       printline ("Copied ".thisfile." to ".fname1)
       %return

sw('D'):
       %if charno (line,length(line)) = '!' %Start
          Delete (thisfile)
          printline ("Deleted ".thisfile)
       %Else
          printline  ("Use D!")
          %continue
       %Finish
       %return

sw('E'):
       -> sw ('Q')

sw('F'):
       Parm Complain %and %Continue %if fp = 0
       %if exists (fname1) %start
          depth = depth + 1
          Do a File (fname1)
          depth = depth - 1
          %Continue
       %Else
          printline ("File ".fname1." does not exist")
       %Finish
       %Continue
 
sw('H'):
Help:
       Print Help
       %Continue

sw('I'):
       %if Length (Line) = 2 %and Charno (Line, 2) = 'E' %start
          Call IE (this file)
       %else %if length (Line) = 1
          length (FComms) = fcommr ('N'<<8, This File, Charno (FComms, 1), 255)
          Print Line (FComms)
       %else
          printline ("Not Implemented.")
       %finish
       %continue

sw('K'):
       Count Lines (thisfile)
       %Continue

sw('N'): 
       Parm Complain %and %continue %if fp = 0 
       to lower(fname1)
       rename (thisfile,fname1)
       printline ("Renamed ".thisfile." to ".fname1)
       %return

sw('P'):
       Parm Complain %and %Continue %if fp = 0
       to Upper(Fname1)
       %unless 1 <= length(fname1) <= 3 %start
           printline ("Faulty permission")
           %Continue
       %Finish
       permit (thisfile,fname1)
       %Continue

sw('Q'): 
       eod = 1
       %Return

sw('R'):
       %If depth = 0 %start
          printline ("Restarting from top")
          Open Directory
          %return
       %else
          printline ("Can't restart within recursive call")
       %finish
       %Continue

sw('T'):
       n1 = get integer
       %if n1 < 0 %start
          printline ("Invalid integer specified")
       %Else
          n1 = 999999 %if n1=0
          type file (thisfile,n1)
       %finish
       %continue

sw('V'):
       Ecce (thisfile)
       %continue

sw('X'):
       n1 = get integer
       %if n1 <0 %start
          printline ("Invalid integer specified")
       %else
          n1=999999 %if n1=0
          dump file (thisfile,n1)
       %Finish
       %continue
   %Repeat
%end

%routine welcome

   printline ("APM Clean   Version ".version."   Current directory :".current directory)
%end

%routine begin
   %string (63) wild,home
   %integer m = 0

   %on 0,1,2,3,4,5,6,7,8,9,10,11 %start
      set directory (home) %unless event_event=9 %and event_sub=3
      %stop
   %finish

   wild = Cli Param
   home = current directory

   to Upper(wild)
   Skip Blanks (wild)

   %if Wild -> user .(":"). wild %start
      open directory
      Printstring ("No such user ".user) %and newline %and %stop %if eod = 1
      set directory (user)
   %else
      user = home
      open directory
   %finish

   wild = "**" %if wild = ""
   Get Next File

   %While Eod = 0 %Cycle
      Do a file (fsp) %and m = 1 %if matches (fsp,wild)
      Get Next File
   %repeat
   printstring ("No files matched") %and newline %if m=0
   set directory (home)
%end

%Begin
   begin
%Endofprogram
 
