;;; dirfuns.mhtml: -*- Meta-HTML -*-  Directory manipulation functions.
;;;
;;;  Copyright (c) 1996 Brian J. Fox
;;;  Author: Brian J. Fox (bfox@ai.mit.edu) Wed Mar 27 07:59:07 1996.
;;;

<defun dir::canonicalize-pathname path>
  <defvar path <get-var mhtml::include-prefix mhtml::relative-prefix>>
  <if <not <string-eq <substring <get-var path> 0 1> "/">>
      <set-var path =
	<get-var mhtml::include-prefix
	  mhtml::relative-prefix>/<get-var path>>>
  <get-var path>
</defun>

<defun make-directories path>
  ;;; Split the path.
  <subst-in-var path "/" "\n">
  <set-var list[]=<get-var path> i=0 dir="">
  <while <get-var list[i]>>
    <set-var dir=<get-var dir>/<get-var list[i]>>
    <set-var finfo=<get-file-properties <get-var dir>>>
    <when <not <get-var finfo>>>
      <cgi-exec mkdir '<get-var dir>'>
    </when>
    <increment i>
  </while>
</defun>

<defsubst directory-p whitespace=delete>
  <string-eq <plist-get-prop "%0" TYPE> "DIRECTORY">
</defsubst>

<defsubst file-prop whitespace=delete>
  <plist-get-prop "%0" %1>
</defsubst>

<defsubst directory-sorter whitespace=delete>
  <set-var ds::t=<prog %body>>
  <subst-in-var ds::t "^ +" "">
  <file-prop "<get-var ds::t>" TYPE><file-prop "<get-var ds::t>" NAME>
</defsubst>

<defun touch-file file>
  <with-open-stream stream <get-var file> mode=write-create>
    true
  </with-open-stream>
</defun>

<defun directories-in-dir dir matching>
  <package-delete dirs>
  <if <not <get-var matching>> <set-var matching=".*">>
  <directory-contents <get-var dir> dirs matching=<get-var matching>>
  <set-var i=0 j=0 dirs[]="" vars[]=<package-vars dirs>>
  <sort vars>
  <while <get-var vars[i]>>
    <if <directory-p <get-var vars[i]>>
	<prog
	  <set-var dirs[j] = <get-var <get-var vars[i]>>>
	  <increment j>>>
    <increment i>
  </while>
  <get-var dirs[]>
</defun>

<defun file-newer? file1 file2>
  <cgi-exec if [ <get-var file1> -nt <get-var file2> ]; then echo true; fi>
</defun>

<defun path::find-executable basename>
  <set-var paths[]=<subst-in-string <get-var mhtml::exec-path> ":" "\n">>
  <set-var i=0 result="">
  <while <and <get-var paths[i]> <not <get-var result>>>>
    <set-var info-alist =
      <get-file-properties <get-var paths[i]>/<get-var basename>>>
    <if <string-eq <plist-get-prop info-alist TYPE> EXECUTABLE>
	<set-var result=<plist-get-prop info-alist FULL-NAME>>
      <increment i>>
  </while>
  <get-var result>
</defun>


<defun dir::names-in-dir dir type matching>
  <set-var dir = <dir::canonicalize-pathname <get-var dir>>>
  <package-delete _names>
  <defvar matching ".*">
  <directory-contents <get-var dir> _names matching=<get-var matching>>
  <set-var names[]=<package-vars _names>>
  <sort names>
  <array-shift -2 names>
  <foreach name names>
    <if <string-eq <plist-get-prop <get-var name> TYPE> <get-var type>
		   caseless=true>
	<array-append <plist-get-prop <get-var name> FULL-NAME> results>>
  </foreach>
  <get-var results[]>
</defun>

<defun dir::dirnames-in-dir dir matching>
  <dir::names-in-dir <get-var dir> DIRECTORY <get-var matching>>
</defun>

<defun dir::filenames-in-dir dir matching>
  <dir::names-in-dir <get-var dir> FILE <get-var matching>>
</defun>

<defun directory? pathname>
  <set-var pathname = <dir::canonicalize-pathname <get-var pathname>>>
  <set-var alist=<get-file-properties <get-var pathname>>>
  <string-eq <plist-get-prop alist TYPE> DIRECTORY>
</defun>

<defun dir::basename pathname>
  <subst-in-string <get-var pathname> "(.*)(/)([^/]*$)" "\\3">
</defun>
