;;; -*- Mode: Lisp; Package: CCL; Coding: utf-8; -*-

(chapter "File System Interface"
  (defsection "Pathnames"
    (defsection "Pathname Expansion"
      "Leading tilde (~) characters in physical pathname namestrings
        are expanded in the way that most shells do: “{code
        ~user/...}” can be used to refer to an absolute pathname
        rooted at the home directory of the user named “user”, and
        “{code ~/...}” can be used to refer to an absolute pathname
        rooted at the home directory of the current user.")

    (defsection "Predefined Logical Hosts"
      "{CCL} sets up logical pathname translations for two logical
      hosts: {code ccl} and {code home}.

      The {code ccl} logical host is meant to refer to the {system
      ccl} directory.  It is used for a variety of purposes by {CCL}
      including: locating {CCL} source code, {code require} and {code
      provide}, accessing foreign function information, and the {CCL}
      build process.  It is set to the value of the environment
      variable {system CCL_DEFAULT_DIRECTORY}, if that variable
      exists.  Otherwise, it is set to the directory containing the
      heap image file.

      The {code home} logical host refers to the user's home directory.")

    (defsection "Pathname Namestrings"
      "The syntax of namestrings is implementation-defined in Common Lisp.
	Portable programs cannot assume much of anything about
	them.  (See section 19.1.1 of the Common Lisp standard for
	more information.)

	When translating a namestring into a pathname object, most
	implementations seem to follow the convention that a dot
	character in the namestring separates the {code pathname-name}
	and the {code pathname-type}.  When there is more than one dot
	in involved, or when dots appear at the beginning or end of
	the namestrings, what to do is less clear: does “{code
	.emacs}” describe a pathname whose name is {code nil} and
	whose type is {code emacs} or something else?  Similarly,
	given “{code a.b.c}”, the question is which parts are parsed
	as the pathname name, and which are parsed as the pathname
	type?

	When generating a namestring from a pathname object (as
	happens, for example, when printing a pathname), {CCL} tries
	to avoid some potential ambiguity by escaping characters that
	might otherwise be used to separate pathname components.  The
	character used to quote or escape the separators is a backlash
	on Unix systems, and a {code #\\>} character on Windows.  So,
	for example, “{code a\\\\.b.c}” has name “a.b” and type “c”,
	whereas “a.b\\\\.c” has name “a” and type “b.c”.

	To get a native namestring suitable for passing to an
	operating system command, use the function {function
	native-translated-namestring}."

      (definition (:function native-translated-namestring) "native-translated-namestring pathname-designator" nil
	"This function returns a namestring that represents a
	  pathname using the native conventions of the operating
	  system.  Any quoting or escaping of special characters will
	  be removed.

	  For example, suppose that {param p} is a pathname made
	  by {code (make-pathname :name \"a.b\" :type \"c\")}.
	  Then, {code (native-translated-namestring p)} evaluates
	  to \"a.b.c\".  By contrast, {code (namestring p)} evaluates
	  to \"a\\\\.b.c\".")

      "Lisp strings are not interchangeable with C strings.  {CCL}
provides a reasonably straightforward way to translate a lisp native
namestring into a C-style string suitable for passing to a foreign
function."

      (definition (:macro with-filename-cstrs)
	"with-filename-cstrs ( {lbrace}(var value){rbrace}* ) {lbrace}form{rbrace}*" "Suitably encode strings to be used as filenames for foreign code."
	"Executes {param forms} in an environment in which each
	  {param var} is bound to a stack-allocated foreign
	  pointer which refers to a C-style string suitable for passing
	  to foreign code which expects a filename argument.

          For example, one might use this macro in the following way:"

	(code-block "(with-filename-cstrs ((s (native-translated-namestring pathname)))
  (#_unlink s))")

	"Various operating systems have different conventions
	  for how they expect native pathname strings to be encoded.
	  Darwin expects then to be decomposed UTF-8.  The Unicode
	  variants to Windows file-handling functions expect UTF-16.
	  Other systems just treat them as opaque byte sequences.
	  This macro ensures that the correct encoding is used,
	  whatever the host operating system.")

      "On non-Darwin and non-Windows systems, {macro with-filename-cstrs}
calls {function pathname-encoding-name} to determine the encoding to use."

      (definition (:function pathname-encoding-name) "pathname-encoding-name"
	nil
	"Returns the name of the encoding to be used in
{macro with-filename-cstrs}.  The default is {code nil}, which means
to use :iso-8859-1.  It may be changed with {code setf}.")))


  (definition (:function directory) "directory pathspec &key (directories t) (files t) (all t) (directory-pathnames t) (include-emacs-lockfiles nil) test (follow-links t)" nil

    "{CCL} extends the standard function {function directory} with a number of
keyword arguments:"
    (listing :definition
      (item "{code :files}" :=> "If true, includes
                                 regular (non-directory) files in the
                                 output.  Defaults to {code t}.")
      (item "{code :directories}" :=> "If true, includes directories
                                       in the output.  Defaults to
                                       {code t}.")
      (item "{code :all}" :=> "If true, includes files and directories
        whose names start with a dot character in the output.  (But
        note that entries named “{code .}” or “{code ..}” are never
        included.) Defaults to {code t}.")
      (item "{code :follow-links}" :=> "If true, includes the
        truenames of symbolic or hard links in the output; if false,
        includes the link filenames without attempting to resolve
        them. Defaults to {code t}.

        Note that legacy HFS alias files are treated as plain files.")
      (item "{code :test}" :=> "A function of one argument (a
        pathname) which should return true if the pathname should be
        included in the output.")
      (item "{code :include-emacs-lockfiles}" :=> "If true, include
        emacs-style lockfiles (symbolic links of the form {system
        .#something}) in the output. Defaults to {code nil}.")))


  ) ;chapter
