! 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  21/04/88   Takes screen width from SCREENCOLS rather than assuming 80.
!                 Note o/p to files will retain this width.

%option "-nocheck-nodiag"
@16_3FA0 %byte screenrows,screencols
%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=""
%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

%string(255)%fn standardise(%string(255) s)
%integer i, case = 0
%bytename k
  %result = "" %if s = ""
  %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 = ' '
      %result = s
    %else
      case = 0
    %finish
  %repeat
  %result = s
%end

%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
  %routine dofiles
  %recordformat f(%record(f)%name left,right,%string(255)s)
  %record(f)%name root, this
  %constinteger fieldwid=13
  %integer printed,maxperline

    %routine separate(%integer len)
      %if len<0 %start
        newline %unless printed=0; printed = 0
      %elseif printed=maxperline
        printed = 0; newline
      %else
        spaces(fieldwid-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

    printed=0
    maxperline = screencols//fieldwid
    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=""
  %if wildness(file)>0 %start
    printline(finfo(directory,0))
    %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
