diff options
Diffstat (limited to 'src/boost/tools/build/src/engine/pathvms.cpp')
-rw-r--r-- | src/boost/tools/build/src/engine/pathvms.cpp | 254 |
1 files changed, 254 insertions, 0 deletions
diff --git a/src/boost/tools/build/src/engine/pathvms.cpp b/src/boost/tools/build/src/engine/pathvms.cpp new file mode 100644 index 000000000..76a1241ab --- /dev/null +++ b/src/boost/tools/build/src/engine/pathvms.cpp @@ -0,0 +1,254 @@ +/* + * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. + * + * This file is part of Jam - see jam.c for Copyright information. + */ + +/* This file is ALSO: + * Copyright 2001-2004 David Abrahams. + * Copyright 2005 Rene Rivera. + * Copyright 2015 Artur Shepilko. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE.txt or copy at + * https://www.bfgroup.xyz/b2/LICENSE.txt) + */ + + +/* + * pathvms.c - VMS-specific path manipulation support + * + * This implementation is based on POSIX-style path manipulation. + * + * VMS CTRL directly supports both POSIX- and native VMS-style path expressions, + * with the POSIX-to-VMS path translation performed internally by the same + * set of functions. For the most part such processing is transparent, with + * few differences mainly related to file-versions (in POSIX mode only the recent + * version is visible). + * + * This should allow us to some extent re-use pathunix.c implementation. + * + * Thus in jam-files the path references can also remain POSIX/UNIX-like on all + * levels EXCEPT in actions scope, where the path references must be translated + * to the native VMS-style. This approach is somewhat similar to jam CYGWIN + * handling. + * + * + * External routines: + * path_register_key() + * path_as_key() + * path_done() + * + * External routines called only via routines in pathsys.c: + * path_get_process_id_() + * path_get_temp_path_() + * path_translate_to_os_() + */ + + +#include "jam.h" + +#ifdef OS_VMS + +#include "pathsys.h" + +#include <assert.h> +#include <stdlib.h> +#include <unistd.h> /* needed for getpid() */ +#include <unixlib.h> /* needed for decc$to_vms() */ + + +/* + * path_get_process_id_() + */ + +unsigned long path_get_process_id_( void ) +{ + return getpid(); +} + + +/* + * path_get_temp_path_() + */ + +void path_get_temp_path_( string * buffer ) +{ + char const * t = getenv( "TMPDIR" ); + string_append( buffer, t ? t : "/tmp" ); +} + + +/* + * translate_path_posix2vms() + * + * POSIX-to-VMS file specification translation: + * + * Translation is performed with decc$to_vms() CTRL routine (default decc$features) + * Some limitations apply: + * -- ODS-2 compliant file specs only (no spaces, punctuation chars etc.) + * + * -- wild-cards are not allowed + * In general decc$to_vms() can expand the wildcard for existing files, + * yet it cannot retain wild-cards in translated spec. Use GLOB for this. + * + * -- rooted path must refer to an existing/defined device or root-dir + * (e.g. /defconcealed/dir/file.ext or /existingrootdir/dir/file.ext ) + * + * -- POSIX dir/no-type-file path ambiguity (e.g. dir/newsubdir vs. dir/newfile + * is handled as follows: + * + * 1) first try as directory: + * -- if translated (may be a dir): means the file-path has no .type/suffix + * -- if not translated, then it may be a file (has .type) OR invalid spec + * 2) then try as file: + * -- if translated and also is a dir -- check if such file exists (stat) + * -- if not translated, but is a dir -- return as dir + * + * NOTE: on VMS it's possible to have both a file and a dir of the same name + * appear in the same directory. In such case _directory_ intent is assumed. + * + * It's preferable to avoid such naming ambiguity in this context, so + * append an empty .type to specify a no-type file (eg. "filename.") + * + */ + + +static string * m_vmsfilespec = NULL; + +/* + * copy_vmsfilespec() - decc$to_vms action routine for matched filenames + */ + +static int copy_vmsfilespec( char * f, int type ) +{ + assert ( NULL != m_vmsfilespec && "Must be bound to a valid object" ); + + string_copy( m_vmsfilespec, f ); + + /* 0:Exit on first match (1:Process all) */ + return 0; +} + + +static int translate_path_posix2vms( string * path ) +{ + int translated = 0; + + string as_dir[ 1 ]; + string as_file[ 1 ]; + int dir_count; + int file_count; + + unsigned char is_dir; + unsigned char is_file; + unsigned char is_ambiguous; + + string_new( as_dir ); + string_new( as_file ); + + + m_vmsfilespec = as_dir; + + /* MATCH 0:do not allow wildcards, 0:allow directories (2:dir only) */ + dir_count = decc$to_vms( path->value, copy_vmsfilespec, 0, 2 ); + + + m_vmsfilespec = as_file; + + /* MATCH 0:do not allow wildcards, 0:allow directories (2:dir only) */ + file_count = decc$to_vms( path->value, copy_vmsfilespec, 0, 0 ); + + m_vmsfilespec = NULL; + + + translated = ( file_count || dir_count ); + + if ( file_count && dir_count ) + { + struct stat statbuf; + + /* use as_file only when exists AND as_dir does not exist + * otherwise use as_dir + */ + if ( stat(as_dir->value, &statbuf ) < 0 + && stat(as_file->value, &statbuf ) > 0 + && ( statbuf.st_mode & S_IFREG ) ) + { + string_truncate( path, 0 ); + string_append( path, as_file->value ); + } + else + { + string_truncate( path, 0 ); + string_append( path, as_dir->value ); + } + } + else if ( file_count ) + { + string_truncate( path, 0 ); + string_append( path, as_file->value ); + } + else if ( dir_count ) + { + string_truncate( path, 0 ); + string_append( path, as_dir->value ); + } + else + { + /* error: unable to translate path to native format */ + translated = 0; + } + + string_free( as_dir ); + string_free( as_file ); + + return translated; +} + + +/* + * path_translate_to_os_() + */ + +int path_translate_to_os_( char const * f, string * file ) +{ + int translated = 0; + + /* by default, pass on the original path */ + string_copy( file, f ); + + translated = translate_path_posix2vms( file ); + + return translated; +} + + +/* + * path_register_key() + */ + +void path_register_key( OBJECT * path ) +{ +} + + +/* + * path_as_key() + */ + +OBJECT * path_as_key( OBJECT * path ) +{ + return object_copy( path ); +} + + +/* + * path_done() + */ + +void path_done( void ) +{ +} + +#endif + |