From 22a67d8185bd289fe88ef4b32d9b6d3df4d1fcec Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Tue, 26 Oct 2004 11:43:19 +0000 Subject: [PATCH] Support for VMS paths. Patch from Johan Nilsson. [SVN r25872] --- v2/util/path.jam | 224 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 223 insertions(+), 1 deletion(-) diff --git a/v2/util/path.jam b/v2/util/path.jam index 579b3c156..fddda362f 100644 --- a/v2/util/path.jam +++ b/v2/util/path.jam @@ -402,8 +402,171 @@ rule native-CYGWIN ( path ) return [ native-UNIX $(result) ] ; } -rule __test__ ( ) { +# +# split-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 ftom 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 ; @@ -500,6 +663,65 @@ rule __test__ ( ) { 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) ; }