📄 path.jam
字号:
# Converts native Windows paths into our internal canonic path representation.# Supports 'invalid' paths containing multiple successive path separator# characters.## TODO: Check and if needed add support for Windows 'X:file' path format where# the file is located in the current folder on drive X.#rule make-NT ( native ){ local result ; if [ version.check-jam-version 3 1 17 ] { result = [ NORMALIZE_PATH $(native) ] ; } else { # This old implementation is really fragile due to a not so clear way # NORMALIZE_PATH rule worked in Boost.Jam versions prior to 3.1.17. E.g. # path.join would mostly ignore empty path elements but would root the # joined path in case the initial two path elements were empty or some # similar accidental wierdness. result = [ path.join [ regex.split $(native) "[/\\]" ] ] ; } # We need to add an extra '/' in front in case this is a rooted Windows path # starting with a drive letter and not a path separator character since the # builtin NORMALIZE_PATH rule has no knowledge of this leading drive letter # and treats it as a regular folder name. if [ regex.match "(^.:)" : $(native) ] { result = /$(result) ; } return $(result) ;}rule native-NT ( path ){ local result ; if [ is-rooted $(path) ] && ! [ regex.match "^/(.:)" : $(path) ] { result = $(path) ; } else { result = [ MATCH "^/?(.*)" : $(path) ] ; } result = [ sequence.join [ regex.split $(result) "/" ] : "\\" ] ; return $(result) ;}rule make-UNIX ( native ){ # VP: I have no idea now 'native' can be empty here! But it can! if ! $(native) { errors.error "Empty path passed to 'make-UNIX'" ; } else { return [ NORMALIZE_PATH $(native:T) ] ; }}rule native-UNIX ( path ){ return $(path) ;}rule make-CYGWIN ( path ){ return [ make-NT $(path) ] ;}rule native-CYGWIN ( path ){ local result = $(path) ; if [ regex.match "(^/.:)" : $(path) ] # Windows absolute path. { result = [ MATCH "^/?(.*)" : $(path) ] ; # Remove leading '/'. } return [ native-UNIX $(result) ] ;}# split-path-VMS: splits input native path into device dir file (each part is# optional).## example:## dev:[dir]file.c => dev: [dir] file.c#rule split-path-VMS ( native ){ local matches = [ MATCH ([a-zA-Z0-9_-]+:)?(\\[[^\]]*\\])?(.*)?$ : $(native) ] ; local device = $(matches[1]) ; local dir = $(matches[2]) ; local file = $(matches[3]) ; return $(device) $(dir) $(file) ;}# Converts a native VMS path into a portable path spec.## Does not handle current-device absolute paths such as "[dir]File.c" as it is# not clear how to represent them in the portable path notation.## Adds a trailing dot (".") to the file part if no extension is present (helps# when converting it back into native path).#rule make-VMS ( native ){ if [ MATCH ^(\\[[a-zA-Z0-9]) : $(native) ] { errors.error "Can't handle default-device absolute paths: " $(native) ; } local parts = [ split-path-VMS $(native) ] ; local device = $(parts[1]) ; local dir = $(parts[2]) ; local file = $(parts[3]) ; local elems ; if $(device) { # # rooted # elems = /$(device) ; } if $(dir) = "[]" { # # Special case: current directory # elems = $(elems) "." ; } else if $(dir) { dir = [ regex.replace $(dir) "\\[|\\]" "" ] ; local dir_parts = [ regex.split $(dir) \\. ] ; if $(dir_parts[1]) = "" { # # Relative path # dir_parts = $(dir_parts[2--1]) ; } # # replace "parent-directory" parts (- => ..) # dir_parts = [ regex.replace-list $(dir_parts) : - : .. ] ; elems = $(elems) $(dir_parts) ; } if $(file) { if ! [ MATCH (\\.) : $(file) ] { # # Always add "." to end of non-extension file. # file = $(file). ; } elems = $(elems) $(file) ; } local portable = [ path.join $(elems) ] ; return $(portable) ;}# Converts a portable path spec into a native VMS path.## Relies on having at least one dot (".") included in the file name to be able# to differentiate it from the directory part.#rule native-VMS ( path ){ local device = "" ; local dir = $(path) ; local file = "" ; local native ; local split ; # # Has device ? # if [ is-rooted $(dir) ] { split = [ MATCH ^/([^:]+:)/?(.*) : $(dir) ] ; device = $(split[1]) ; dir = $(split[2]) ; } # # Has file ? # # This is no exact science, just guess work: # # If the last part of the current path spec # includes some chars, followed by a dot, # optionally followed by more chars - # then it is a file (keep your fingers crossed). # split = [ regex.split $(dir) / ] ; local maybe_file = $(split[-1]) ; if [ MATCH ^([^.]+\\..*) : $(maybe_file) ] { file = $(maybe_file) ; dir = [ sequence.join $(split[1--2]) : / ] ; } # # Has dir spec ? # if $(dir) = "." { dir = "[]" ; } else if $(dir) { dir = [ regex.replace $(dir) \\.\\. - ] ; dir = [ regex.replace $(dir) / . ] ; if $(device) = "" { # # Relative directory # dir = "."$(dir) ; } dir = "["$(dir)"]" ; } native = [ sequence.join $(device) $(dir) $(file) ] ; return $(native) ;}rule __test__ ( ){ import assert ; import errors : try catch ; assert.true is-rooted "/" ; assert.true is-rooted "/foo" ; assert.true is-rooted "/foo/bar" ; assert.result : is-rooted "." ; assert.result : is-rooted "foo" ; assert.result : is-rooted "foo/bar" ; assert.true has-parent "foo" ; assert.true has-parent "foo/bar" ; assert.true has-parent "." ; assert.result : has-parent "/" ; assert.result "." : basename "." ; assert.result ".." : basename ".." ; assert.result "foo" : basename "foo" ; assert.result "foo" : basename "bar/foo" ; assert.result "foo" : basename "gaz/bar/foo" ; assert.result "foo" : basename "/gaz/bar/foo" ; assert.result "." : parent "foo" ; assert.result "/" : parent "/foo" ; assert.result "foo/bar" : parent "foo/bar/giz" ; assert.result ".." : parent "." ; assert.result ".." : parent "../foo" ; assert.result "../../foo" : parent "../../foo/bar" ; assert.result "." : reverse "." ; assert.result ".." : reverse "foo" ; assert.result "../../.." : reverse "foo/bar/giz" ; assert.result "foo" : join "foo" ; assert.result "/foo" : join "/" "foo" ; assert.result "foo/bar" : join "foo" "bar" ; assert.result "foo/bar" : join "foo/giz" "../bar" ; assert.result "foo/giz" : join "foo/bar/baz" "../../giz" ; assert.result ".." : join "." ".." ; assert.result ".." : join "foo" "../.." ; assert.result "../.." : join "../foo" "../.." ; assert.result "/foo" : join "/bar" "../foo" ; assert.result "foo/giz" : join "foo/giz" "." ; assert.result "." : join lib2 ".." ; assert.result "/" : join "/a" ".." ; assert.result /a/b : join /a/b/c .. ; assert.result "foo/bar/giz" : join "foo" "bar" "giz" ; assert.result "giz" : join "foo" ".." "giz" ; assert.result "foo/giz" : join "foo" "." "giz" ; try ; { join "a" "/b" ; } catch only first element may be rooted ; local CWD = "/home/ghost/build" ; assert.result : all-parents . : . : $(CWD) ; assert.result . .. ../.. ../../.. : all-parents "Jamfile" : "" : $(CWD) ; assert.result foo . .. ../.. ../../.. : all-parents "foo/Jamfile" : "" : $(CWD) ; assert.result ../Work .. ../.. ../../.. : all-parents "../Work/Jamfile" : "" : $(CWD) ; local CWD = "/home/ghost" ; assert.result . .. : all-parents "Jamfile" : "/home" : $(CWD) ; assert.result . : all-parents "Jamfile" : "/home/ghost" : $(CWD) ; assert.result "c/d" : relative "a/b/c/d" "a/b" ; assert.result "foo" : relative "foo" "." ; local save-os = [ modules.peek path : os ] ; modules.poke path : os : NT ; assert.result "foo/bar/giz" : make "foo/bar/giz" ; assert.result "foo/bar/giz" : make "foo\\bar\\giz" ; assert.result "foo" : make "foo/" ; assert.result "foo" : make "foo\\" ; assert.result "foo" : make "foo/." ; assert.result "foo" : make "foo/bar/.." ; assert.result "foo" : make "foo/bar/../" ; assert.result "foo" : make "foo/bar/..\\" ; assert.result "foo/bar" : make "foo/././././bar" ; assert.result "/foo" : make "\\foo" ; assert.result "/D:/My Documents" : make "D:\\My Documents" ; assert.result "/c:/boost/tools/build/new/project.jam" : make "c:\\boost\\tools\\build\\test\\..\\new\\project.jam" ; # Test processing 'invalid' paths containing multiple successive path # separators. assert.result "foo" : make "foo//" ; assert.result "foo" : make "foo///" ; assert.result "foo" : make "foo\\\\" ; assert.result "foo" : make "foo\\\\\\" ; assert.result "/foo" : make "//foo" ; assert.result "/foo" : make "///foo" ; assert.result "/foo" : make "\\\\foo" ; assert.result "/foo" : make "\\\\\\foo" ; assert.result "/foo" : make "\\/\\/foo" ; assert.result "foo/bar" : make "foo//\\//\\\\bar//\\//\\\\\\//\\//\\\\" ; assert.result "foo" : make "foo/bar//.." ; assert.result "foo/bar" : make "foo/bar/giz//.." ; assert.result "foo/giz" : make "foo//\\//\\\\bar///\\\\//\\\\////\\/..///giz\\//\\\\\\//\\//\\\\" ; assert.result "../../../foo" : make "..///.//..///.//..////foo///" ; # Test processing 'invalid' rooted paths with too many '..' path elements # that would place them before the root. assert.result : make "/.." ; assert.result : make "/../" ; assert.result : make "/../." ; assert.result : make "/.././" ; assert.result : make "/foo/../bar/giz/.././././../../." ; assert.result : make "/foo/../bar/giz/.././././../.././" ; assert.result : make "//foo/../bar/giz/.././././../../." ; assert.result : make "//foo/../bar/giz/.././././../.././" ; assert.result : make "\\\\foo/../bar/giz/.././././../../." ; assert.result : make "\\\\foo/../bar/giz/.././././../.././" ; assert.result : make "/..///.//..///.//..////foo///" ; assert.result "foo\\bar\\giz" : native "foo/bar/giz" ; assert.result "foo" : native "foo" ; assert.result "\\foo" : native "/foo" ; assert.result "D:\\My Documents\\Work" : native "/D:/My Documents/Work" ; modules.poke path : os : UNIX ; assert.result "foo/bar/giz" : make "foo/bar/giz" ; assert.result "/sub1" : make "/sub1/." ; assert.result "/sub1" : make "/sub1/sub2/.." ; assert.result "sub1" : make "sub1/." ; assert.result "sub1" : make "sub1/sub2/.." ; assert.result "/foo/bar" : native "/foo/bar" ; modules.poke path : os : VMS ; # # Don't really need to poke os before these # assert.result "disk:" "[dir]" "file" : split-path-VMS "disk:[dir]file" ; assert.result "disk:" "[dir]" "" : split-path-VMS "disk:[dir]" ; assert.result "disk:" "" "" : split-path-VMS "disk:" ; assert.result "disk:" "" "file" : split-path-VMS "disk:file" ; assert.result "" "[dir]" "file" : split-path-VMS "[dir]file" ; assert.result "" "[dir]" "" : split-path-VMS "[dir]" ; assert.result "" "" "file" : split-path-VMS "file" ; assert.result "" "" "" : split-path-VMS "" ; # # Special case: current directory # assert.result "" "[]" "" : split-path-VMS "[]" ; assert.result "disk:" "[]" "" : split-path-VMS "disk:[]" ; assert.result "" "[]" "file" : split-path-VMS "[]file" ; assert.result "disk:" "[]" "file" : split-path-VMS "disk:[]file" ; # # Make portable paths # assert.result "/disk:" : make "disk:" ; assert.result "foo/bar/giz" : make "[.foo.bar.giz]" ; assert.result "foo" : make "[.foo]" ; assert.result "foo" : make "[.foo.bar.-]" ; assert.result ".." : make "[.-]" ; assert.result ".." : make "[-]" ; assert.result "." : make "[]" ; assert.result "giz.h" : make "giz.h" ; assert.result "foo/bar/giz.h" : make "[.foo.bar]giz.h" ; assert.result "/disk:/my_docs" : make "disk:[my_docs]" ; assert.result "/disk:/boost/tools/build/new/project.jam" : make "disk:[boost.tools.build.test.-.new]project.jam" ; # # Special case (adds '.' to end of file w/o extension to # disambiguate from directory in portable path spec). # assert.result "Jamfile." : make "Jamfile" ; assert.result "dir/Jamfile." : make "[.dir]Jamfile" ; assert.result "/disk:/dir/Jamfile." : make "disk:[dir]Jamfile" ; # # Make native paths # assert.result "disk:" : native "/disk:" ; assert.result "[.foo.bar.giz]" : native "foo/bar/giz" ; assert.result "[.foo]" : native "foo" ; assert.result "[.-]" : native ".." ; assert.result "[.foo.-]" : native "foo/.." ; assert.result "[]" : native "." ; assert.result "disk:[my_docs.work]" : native "/disk:/my_docs/work" ; assert.result "giz.h" : native "giz.h" ; assert.result "disk:Jamfile." : native "/disk:Jamfile." ; assert.result "disk:[my_docs.work]Jamfile." : native "/disk:/my_docs/work/Jamfile." ; modules.poke path : os : $(save-os) ;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -