% Function TRANSLATE-PATHNAME
Function TRANSLATE-PATHNAME
translate-pathname
source from-wildcard to-wildcard &key
=> translated-pathname
source - パス名指定子
from-wildcard - パス名指定子
to-wildcard - パス名指定子
translated-pathname - パス名
translate-pathname
はsource
(from-wildcardにマッチしたもの)を、
to-wildcardにマッチした対応したパス名に変換し、
その対応したパス名を返却します。
パス名の結果はto-wildcardの各ワイルドカードか欠落した要素が
sourceの部分に置き換えられたものになります。
「ワイルドカードの要素」とは、
パス名の要素の値が:wild
であるか、
ディレクトリの要素のリストの要素が:wild
であるか、
あるいは要素の実装定義の部分である
例えばいくつかの実装でサポートされている、
文字列"foo*bar"
のような複雑なワイルドカードである
"*"
のような文字のことです。
実装は例えば正規表現のようなその他のワイルドカードの機能を追加することができ、
そのような機能をどのようにしてtranslate-pathname
に拡張するのか
定義しなければなりません。
「欠落した要素」はパス名の要素がnil
のものです。
結果のパス名からコピーされたsourceの部分は実装定義です。 典型的にはそれはファイルシステムに関与する ユーザーインターフェイスの慣習によって決定されます。 通常それはsourceの部分が from-wildcardのワイルドカードの要素と to-wildcardのワイルドカードか欠落した要素の同じ部分が マッチした部分です。 もしfrom-wildcardのある位置がワイルドカードの要素ではなかったとき、 通常はそれは対応するsourceのパス名の要素全体であるか、 あるいはディレクトリ要素のリストの要素の場合であるか、 あるいは対応するリストの要素全体になります。
sourceの部分を結果のパス名へコピーするとき、 追加の実装定義の大文字小文字の変換や、 ファイル名の慣習の変換が生じるかもしれません。 とくにfrom-wildcardとto-wildcardが違うホストのときに生じます。
sourceがワイルドカードのパス名であることは正当であり、 一般的にこれはワイルドカードを含む結果が生成されるでしょう。 from-wildcardとto-wildcardの片方かあるいは両方に ワイルドカードを含まれないパス名であることは正当です。
translate-pathname
にはキーワード引数はありませんが、
しかし実装は追加のキーワード引数による拡張が許されます。
translate-pathname
は
sourceの慣習的な大文字小文字と
出力パス名の慣習的な大文字小文字を対応付けします。
;; 下記の5つのフォームの結果は、全て実装依存です。
;; とくに2つ目については一般的に生じるであろう多くのもののうち
;; 強調したものをいくつか示しています。
(pathname-name (translate-pathname "foobar" "foo*" "*baz")) => "barbaz"
(pathname-name (translate-pathname "foobar" "foo*" "*"))
=> "foobar"
OR=> "bar"
(pathname-name (translate-pathname "foobar" "*" "foo*")) => "foofoobar"
(pathname-name (translate-pathname "bar" "*" "foo*")) => "foobar"
(pathname-name (translate-pathname "foobar" "foo*" "baz*")) => "bazbar"
(defun translate-logical-pathname-1 (pathname rules)
(let ((rule (assoc pathname rules :test #'pathname-match-p)))
(unless rule (error "No translation rule for ~A" pathname))
(translate-pathname pathname (first rule) (second rule))))
(translate-logical-pathname-1 "FOO:CODE;BASIC.LISP"
'(("FOO:DOCUMENTATION;" "MY-UNIX:/doc/foo/")
("FOO:CODE;" "MY-UNIX:/lib/foo/")
("FOO:PATCHES;*;" "MY-UNIX:/lib/foo/patch/*/")))
=> #P"MY-UNIX:/lib/foo/basic.l"
;;; この例はワイルドカードを認識できることを仮定しています。
;;; 全てのファイルシステムがこの例のように正確に実行されません。
(defun rename-files (from to)
(dolist (file (directory from))
(rename-file file (translate-pathname file from to))))
(rename-files "/usr/me/*.lisp" "/dev/her/*.l")
;Renames /usr/me/init.lisp to /dev/her/init.l
(rename-files "/usr/me/pcl*/*" "/sys/pcl/*/")
;Renames /usr/me/pcl-5-may/low.lisp to /sys/pcl/pcl-5-may/low.lisp
;In some file systems the result might be /sys/pcl/5-may/low.lisp
(rename-files "/usr/me/pcl*/*" "/sys/library/*/")
;Renames /usr/me/pcl-5-may/low.lisp to /sys/library/pcl-5-may/low.lisp
;In some file systems the result might be /sys/library/5-may/low.lisp
(rename-files "/usr/me/foo.bar" "/usr/me2/")
;Renames /usr/me/foo.bar to /usr/me2/foo.bar
(rename-files "/usr/joe/*-recipes.text" "/usr/jim/cookbook/joe's-*-rec.text")
;Renames /usr/joe/lamb-recipes.text to /usr/jim/cookbook/joe's-lamb-rec.text
;Renames /usr/joe/pork-recipes.text to /usr/jim/cookbook/joe's-pork-rec.text
;Renames /usr/joe/veg-recipes.text to /usr/jim/cookbook/joe's-veg-rec.text
なし。
もしsourceかfrom-wildcardかto-wildcardのいずれかが、
パス名、文字列、ファイルに関連づいたストリームのどれでもない場合は、
型type-error
のエラーが発生します。
(pathname-match-p source from-wildcard)
はtrueでなければならず、
あるいは型type-error
のエラーが派生します。
namestring
,
pathname-host
,
pathname
,
logical-pathname
,
20.1. ファイルシステムの説明,
19.1.2. ファイル名としてのパス名
translate-pathname
の正確なふるまいは、
Common Lisp言語では決めることができず、
ファイルシステムの慣習に従ったユーザーインターフェイスに
依存するように変化できるようにする必要があります。
これ以降の文章は実装のガイドラインです。
あるファイルシステムでは、
この操作行うためにパス名の3つの各部分を順番に調べます。
ここで、各部分とはパス名のコンポーネントか、
または階層型ディレクトリのような構造化された要素を表すリストの要素です。
from-wildcardとto-wildcardの階層ディレクトリ要素は、
ディレクトリ階層内の深さではなく、
ワイルドカードであるかどうかでマッチされます。
もしto-wildcardに含まれる部分が存在し、
それがワイルドカードでないときは結果にコピーされます。
to-wildcardの部分が:wild
またはnil
のときは、
sourceの部分が結果にコピーされます。
それ以外のときは、to-wildcardの部分は
"foo*bar"
のような複雑なワイルドカードであり、
from-wildcardの部分はワイルドカードでなければなりません。
sourceの部分のうち、from-wildcardの部分のワイルドカードにマッチする部分は、
to-wildcardのワイルドカードの部分を置き換え、
その生成された値が結果として使われます。