!  File  MOUSE:FILES

! FILES utility

%option "-nocheck-nodiag"
@16_3FA0 %byte screenrows,screencols
%include "inc:util.imp"
%begin


%integerfn wildness(%string(*)%name s)
%integer k,i,w=0
  %for i=1,1,length(s) %cycle
    k = charno(s,i); w = w+1 %if k='*' %or k='%'
  %repeat
  %result = w
%end

%predicate Matches(%string (*) %name s, p)
! S=Subject, P=Pattern. Pattern is the one with the stars in it.
   %integer slen = 0, plen = 0

   %predicate m (%integer spos,ppos)
      %integer psym = 0,ssym = 0

      %cycle
         %if ppos=plen %start
            %true %if spos=slen
            %false
         %finish
         ppos = ppos+1; psym = charno(p,ppos)
         %exitif psym='*'
         %falseif spos=slen
         spos = spos+1; ssym = charno(s,spos)
         psym = ssym %if ssym!32=psym!32 %and 'a'<=psym!32<='z'
         %unless ssym=psym %start
            %falseunless psym='%'
         %finish
      %repeat

      %cycle
         %trueif m(spos,ppos)
         %exitif spos=slen
         spos = spos+1; ssym = charno(s,spos)
      %repeat
      %false
   %end

   slen = length(s)
   plen = length(p)
   %true %if m(0,0)
   %false
%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) %unless before==nil
      after = sub string(what, pos + 1, length(what)) %unless after==nil
      %true
%end

%string(255)%fn info(%string(255)filename)
%string(255)fore,aft
   %on 3 %start
      %result = filename . "    " . event_message
   %finish
   filename = ninfo(filename)
   %result = filename %unless filename -> fore.(" ").aft
   %result = filename %unless split at last colon(fore,nil,fore)
   %result = fore." ".aft
%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


%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(info(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(info(full name)))
          %finish
        %finish
      %finish
    %repeat
  %end

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

  file = target %and directory = "." %unless %c
    split at last colon(target, directory, file)
  file = "*" %if file=""
  %if wildness(file)>0 %start
    printline(ninfo(directory.":"))
    %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(info(full name)))
  %finish
%end

%endofprogram
