! APM FILES utility.     R Thonnes et al 6/84
! Parameters:
! Target is file name or names. Wild cards accepted in filename but not directory
! Default is all files for current directory.
! Output is output file name (default = console)
! Full   specifies that size and date info should be displayed for each file
! Order  may be by date or alphabetic
! Hide   specifies whether "hidden" files (beginning with '.') are to be
!        suppressed (default = yes)
! One line of total files and blocks in the directory is displayed when wild
! cards are used.
! If Totals is specified only this line is displayed.
!
! GDMR 02/02/87   Fixed to recognise hierarchic directories properly.
!                 Case-mangling "improved" slightly
! GDMR 09/02/87   NInfo removed from Util.Imp to here, with addition of
!                 event-3 trap
! JHB  25/06/87   STANDARDISE modded to cope with new-style FILES info
!                 DIRINFO created and used to resolve path off filenames.

%include "inc:util.imp"
%include "inc:fs.imp"
%include "inc:fsutil.imp"

%begin

%externalstring(255)%fnspec FINFO(%string(255)directory,%integer number)


%string(255)%fn Ninfo(%string(255) filename)
   %string(255) response = "Dummy"
      %on 3 %start
         %result = filename . "    " . event_message
      %finish
      length(response) = fcommr('N' << 8, filename, charno(response, 1), 255)
      %result = response
%end


%routinespec files(%string(255)target)

! PAM interface

%constinteger dateorder=1,alphaorder=2
%string(255)target="",output="", s="", dirinfo="", dirname=""
%integer full=0,hide=16_80000000
%byte order=dateorder,tots=0

defineparam("Target",target,0)
defineparam("Output",output,pamnewgroup)
definebooleanparams("Full",full,0)
definebooleanparams("Hide",hide,0)
defineenumparam("Order,Date,Alpha",order,0)
define enum param("ALL,TOtals",tots,0) ;!JHB mod to display totals only.
processparameters(cliparam)

! Main program

openoutput(1,output) %and selectoutput(1) %unless output=""
files(target)

! End of main program

%predicate split at last colon(%string(255) what,
                               %string(*)%name before, after)
   %integer i, pos = 0
      %false %if what = ""
      ! Look for the last colon
      %for i = 1, 1, length(what) %cycle
         pos = i %if charno(what, i) = ':'
      %repeat
      %false %if pos = 0;  ! None found
      before = sub string(what, 1, pos - 1)
      after = sub string(what, pos + 1, length(what))
      %true
%end


%routine files(%string(255)target)
%string(255)directory,file,thisfile, full name

!Generic form of record coming back:
!New-style filestores:
!<filename>"  "<UIC>[","<UIC>]":"<ownerpermissions+backup>";"
!  [<UIC>":"<grouppermissions>";"]<worldpermissions>"  "<timestamp>"  "<size>
!<permissions> ::= Read Modify Append Xchange Link Control *none*
!<backup> ::= $backup &archive #improperlyclosed ?overlapping

%string(255)%fn standardise(%string(255) s)
%integer i, case
%string (255) a, b, c, d, rest
%bytename k

%routine strip(%string (255) %name a, %string (255) dir)
  !strip DIR off the front of A if A starts with DIR.
  !(Why didn't I use string resolution?)
  %integer i
  %for i=1,1,length(a) %cycle
     %exit %if charno(a,i)&16_5f # charno(dir,i)&16_5f
  %repeat
  a = substring(a, i, length(a))
%end

  %result = "" %if s = ""
  case = 0
  %for i = 1,1,length(s) %cycle
    k == charno(s,i)
    %if 'A'<=k&95<='Z' %start
      k = k&95+case; case = 32
    %else %if k = ' '
      %exit
    %else
      case = 0
    %finish
  %repeat

  %if s -> a.("  ").rest %and rest -> b.("  ").rest %and %c
  a -> c.(":").d %start
    strip(a, directory.":")
    a=a." " %while length(a)<20; a=a." "
    b=b." " %while length(b)<23; b=b." "
    s=a.b.rest
  %finish

  %result = s
%end

  %routine dofiles
  %recordformat f(%record(f)%name left,right,%string(13)s)
  %record(f)%name root, this
  %integer printed=0

    %routine separate(%integer len)
      %if len<0 %start
        newline %unless printed=0; printed = 0
      %elseif printed=6
        printed = 0; newline
      %else
        spaces(13-len)
      %finish
    %end

    %record(f)%map add(%record(f)%name cell,tree)
      %result == cell %if tree==nil
      %if cell_s<tree_s %then tree_left == add(cell,tree_left) %c
      %else                  tree_right == add(cell,tree_right)
      %result == tree
    %end

    %routine print(%record(f)%name tree)
      %returnif tree==nil
      print(tree_left)
      %if full=0 %start
        printstring(tree_s); printed = printed+1
        separate(length(tree_s))
      %else
        full name = directory . ":" . tree_s
        length(full name) = length(full name) - 1 %c
          %if charno(full name, length(full name)) = '?'
        printline(standardise(ninfo(full name)))
      %finish
      print(tree_right)
    %end

    %predicate hidden(%string(*)%name s)
      %falseif hide=0 %or charno(file,1)='.'
      %trueif length(s)=0
      %trueif charno(s,1)='.'
      %false
    %end

    %onevent 3,9 %start
      print(root)
      separate(-1)
      %return
    %finish

    root == nil
    %cycle
      readline(thisfile)
      thisfile = standardise(thisfile)
      %unless hidden(thisfile) %start
        %if matches(thisfile,file) %start
          %if order=alphaorder %start
            this == new(this)
            this_left == nil; this_right == nil; this_s = thisfile
            root == add(this,root)
          %elseif full=0
            printstring(thisfile); printed = printed+1
            separate(length(thisfile))
          %else
            full name = directory . ":" . this file
            length(full name) = length(full name) - 1 %c
              %if charno(full name, length(full name)) = '?'
            printline(standardise(ninfo(full name)))
          %finish
        %finish
      %finish
    %repeat
  %end

  %onevent 3,4,9 %start
    printline(event_message)
    %stop
  %finish

  file = target %and directory = current directory %unless %c
    split at last colon(target, directory, file)
  file = "*" %if file=""
  dirinfo = finfo(directory, 0); dirname = directory
  %if wildness(file)>0 %start
    printline(dirinfo)
    %if tots = 0 %start
       openinput(1, directory.":Directory")
       select input(1)
       dofiles
    %finish
  %else
    full name = directory . ":" . file
    length(full name) = length(full name) - 1 %c
      %if charno(full name, length(full name)) = '?'
    printline(standardise(ninfo(full name)))
  %finish
%end

%endofprogram
