summaryrefslogtreecommitdiffstats
path: root/src/boost/tools/build/src/engine/filevms.cpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:54:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:54:28 +0000
commite6918187568dbd01842d8d1d2c808ce16a894239 (patch)
tree64f88b554b444a49f656b6c656111a145cbbaa28 /src/boost/tools/build/src/engine/filevms.cpp
parentInitial commit. (diff)
downloadceph-e6918187568dbd01842d8d1d2c808ce16a894239.tar.xz
ceph-e6918187568dbd01842d8d1d2c808ce16a894239.zip
Adding upstream version 18.2.2.upstream/18.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/tools/build/src/engine/filevms.cpp')
-rw-r--r--src/boost/tools/build/src/engine/filevms.cpp440
1 files changed, 440 insertions, 0 deletions
diff --git a/src/boost/tools/build/src/engine/filevms.cpp b/src/boost/tools/build/src/engine/filevms.cpp
new file mode 100644
index 000000000..6dc84ae63
--- /dev/null
+++ b/src/boost/tools/build/src/engine/filevms.cpp
@@ -0,0 +1,440 @@
+/*
+ * 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 https://www.bfgroup.xyz/b2/LICENSE.txt)
+ */
+
+
+#include "jam.h"
+#include "filesys.h"
+
+#include "object.h"
+#include "pathsys.h"
+#include "jam_strings.h"
+
+
+#ifdef OS_VMS
+
+/*
+ * filevms.c - manipulate file names and scan directories on VMS.
+ *
+ * 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 re-use fileunix.c implementation,
+ * excluding archive/library member processing.
+ *
+ * Thus in jam-files the path references can also remain POSIX/UNIX-style on all
+ * levels EXCEPT in actions scope, where these must be translated to the native
+ * VMS-style. This approach is somewhat similar to jam CYGWIN handling.
+ *
+ *
+ * External routines:
+ * file_archscan() - scan an archive for files
+ * file_mkdir() - create a directory
+ * file_supported_fmt_resolution() - file modification timestamp resolution
+ *
+ * External routines called only via routines in filesys.c:
+ * file_collect_dir_content_() - collects directory content information
+ * file_dirscan_() - OS specific file_dirscan() implementation
+ * file_query_() - query information about a path from the OS
+ * file_collect_archive_content_() - collects information about archive members
+ * file_archivescan_() - OS specific file_archivescan() implementation
+ */
+
+#include <assert.h>
+#include <stdio.h>
+
+#include <sys/stat.h> /* needed for mkdir() */
+#include <unistd.h> /* needed for read and close prototype */
+
+#include <dirent.h>
+#define STRUCT_DIRENT struct dirent
+
+
+void path_translate_to_os_( char const * f, string * file );
+
+/*
+ * file_collect_dir_content_() - collects directory content information
+ */
+
+int file_collect_dir_content_( file_info_t * const d )
+{
+ LIST * files = L0;
+ PATHNAME f;
+ DIR * dd;
+ STRUCT_DIRENT * dirent;
+ string path[ 1 ];
+ char const * dirstr;
+
+ assert( d );
+ assert( d->is_dir );
+ assert( list_empty( d->files ) );
+
+ dirstr = object_str( d->name );
+
+ memset( (char *)&f, '\0', sizeof( f ) );
+ f.f_dir.ptr = dirstr;
+ f.f_dir.len = strlen( dirstr );
+
+ if ( !*dirstr ) dirstr = ".";
+
+ if ( !( dd = opendir( dirstr ) ) )
+ return -1;
+
+ string_new( path );
+ while ( ( dirent = readdir( dd ) ) )
+ {
+ OBJECT * name;
+ f.f_base.ptr = dirent->d_name
+ #ifdef old_sinix
+ - 2 /* Broken structure definition on sinix. */
+ #endif
+ ;
+ f.f_base.len = strlen( f.f_base.ptr );
+
+ string_truncate( path, 0 );
+ path_build( &f, path );
+ name = object_new( path->value );
+ /* Immediately stat the file to preserve invariants. */
+ if ( file_query( name ) )
+ files = list_push_back( files, name );
+ else
+ object_free( name );
+ }
+ string_free( path );
+
+ closedir( dd );
+
+ d->files = files;
+ return 0;
+}
+
+
+/*
+ * file_dirscan_() - OS specific file_dirscan() implementation
+ */
+
+void file_dirscan_( file_info_t * const d, scanback func, void * closure )
+{
+ assert( d );
+ assert( d->is_dir );
+
+ /* Special case / : enter it */
+ if ( !strcmp( object_str( d->name ), "/" ) )
+ (*func)( closure, d->name, 1 /* stat()'ed */, &d->time );
+}
+
+
+/*
+ * file_mkdir() - create a directory
+ */
+
+int file_mkdir( char const * const path )
+{
+ /* Explicit cast to remove const modifiers and avoid related compiler
+ * warnings displayed when using the intel compiler.
+ */
+ return mkdir( (char *)path, 0777 );
+}
+
+
+/*
+ * file_query_() - query information about a path from the OS
+ */
+
+void file_query_( file_info_t * const info )
+{
+ file_query_posix_( info );
+}
+
+
+/*------------------------------------------------------------------------------
+* VMS-specific processing:
+*
+*/
+
+#include <descrip.h>
+#include <lbrdef.h>
+#include <credef.h>
+#include <mhddef.h>
+#include <lhidef.h>
+#include <lib$routines.h>
+#include <starlet.h>
+
+/* Supply missing prototypes for lbr$-routines*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+int lbr$set_module(
+ void **,
+ unsigned long *,
+ struct dsc$descriptor_s *,
+ unsigned short *,
+ void * );
+
+int lbr$open( void **,
+ struct dsc$descriptor_s *,
+ void *,
+ void *,
+ void *,
+ void *,
+ void * );
+
+int lbr$ini_control(
+ void **,
+ unsigned long *,
+ unsigned long *,
+ void * );
+
+int lbr$get_index(
+ void **,
+ unsigned long * const,
+ int (*func)( struct dsc$descriptor_s *, unsigned long *),
+ void * );
+
+int lbr$search(
+ void **,
+ unsigned long * const,
+ unsigned short *,
+ int (*func)( struct dsc$descriptor_s *, unsigned long *),
+ unsigned long *);
+
+int lbr$close(
+ void ** );
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+
+static void
+file_cvttime(
+ unsigned int *curtime,
+ time_t *unixtime )
+{
+ static const int32_t divisor = 10000000;
+ static unsigned int bastim[2] = { 0x4BEB4000, 0x007C9567 }; /* 1/1/1970 */
+ int delta[2], remainder;
+
+ lib$subx( curtime, bastim, delta );
+ lib$ediv( &divisor, delta, unixtime, &remainder );
+}
+
+
+static void downcase_inplace( char * p )
+{
+ for ( ; *p; ++p )
+ *p = tolower( *p );
+}
+
+
+static file_archive_info_t * m_archive = NULL;
+static file_info_t * m_member_found = NULL;
+static void * m_lbr_context = NULL;
+static unsigned short * m_rfa_found = NULL;
+static const unsigned long LBR_MODINDEX_NUM = 1,
+ LBR_SYMINDEX_NUM = 2; /* GST:global symbol table */
+
+
+static unsigned int set_archive_symbol( struct dsc$descriptor_s *symbol,
+ unsigned long *rfa )
+{
+ file_info_t * member = m_member_found;
+ char buf[ MAXJPATH ] = { 0 };
+
+ strncpy(buf, symbol->dsc$a_pointer, symbol->dsc$w_length);
+ buf[ symbol->dsc$w_length ] = 0;
+
+ member->files = list_push_back( member->files, object_new( buf ) );
+
+ return ( 1 ); /* continue */
+}
+
+
+static unsigned int set_archive_member( struct dsc$descriptor_s *module,
+ unsigned long *rfa )
+{
+ file_archive_info_t * archive = m_archive;
+
+ static struct dsc$descriptor_s bufdsc =
+ {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL};
+
+ struct mhddef *mhd;
+ char filename[128] = { 0 };
+ char buf[ MAXJPATH ] = { 0 };
+
+ int status;
+ time_t library_date;
+
+ register int i;
+ register char *p;
+
+ bufdsc.dsc$a_pointer = filename;
+ bufdsc.dsc$w_length = sizeof( filename );
+ status = lbr$set_module( &m_lbr_context, rfa, &bufdsc,
+ &bufdsc.dsc$w_length, NULL );
+
+ if ( !(status & 1) )
+ return ( 1 ); /* continue */
+
+ mhd = (struct mhddef *)filename;
+
+ file_cvttime( &mhd->mhd$l_datim, &library_date );
+
+ /* strncpy( filename, module->dsc$a_pointer, module->dsc$w_length );
+ */
+ for ( i = 0, p = module->dsc$a_pointer; i < module->dsc$w_length; ++i, ++p )
+ filename[ i ] = *p;
+
+ filename[ i ] = '\0';
+
+ if ( strcmp( filename, "" ) != 0 )
+ {
+ file_info_t * member = 0;
+
+ /* Construct member's filename as lowercase "module.obj" */
+ sprintf( buf, "%s.obj", filename );
+ downcase_inplace( buf );
+ archive->members = filelist_push_back( archive->members, object_new( buf ) );
+
+ member = filelist_back( archive->members );
+ member->is_file = 1;
+ member->is_dir = 0;
+ member->exists = 0;
+ timestamp_init( &member->time, (time_t)library_date, 0 );
+
+ m_member_found = member;
+ m_rfa_found = rfa;
+ status = lbr$search(&m_lbr_context, &LBR_SYMINDEX_NUM, m_rfa_found, set_archive_symbol, NULL);
+ }
+
+ return ( 1 ); /* continue */
+}
+
+
+
+void file_archscan( char const * arch, scanback func, void * closure )
+{
+ OBJECT * path = object_new( arch );
+ file_archive_info_t * archive = file_archive_query( path );
+
+ object_free( path );
+
+ if ( filelist_empty( archive->members ) )
+ {
+ if ( DEBUG_BINDSCAN )
+ out_printf( "scan archive %s\n", object_str( archive->file->name ) );
+
+ if ( file_collect_archive_content_( archive ) < 0 )
+ return;
+ }
+
+ /* Report the collected archive content. */
+ {
+ FILELISTITER iter = filelist_begin( archive->members );
+ FILELISTITER const end = filelist_end( archive->members );
+ char buf[ MAXJPATH ];
+
+ for ( ; iter != end ; iter = filelist_next( iter ) )
+ {
+ file_info_t * member_file = filelist_item( iter );
+ LIST * symbols = member_file->files;
+
+ /* Construct member path: 'archive-path(member-name)'
+ */
+ sprintf( buf, "%s(%s)",
+ object_str( archive->file->name ),
+ object_str( member_file->name ) );
+ {
+ OBJECT * const member = object_new( buf );
+ (*func)( closure, member, 1 /* time valid */, &member_file->time );
+ object_free( member );
+ }
+ }
+ }
+}
+
+
+/*
+ * file_archivescan_() - OS specific file_archivescan() implementation
+ */
+void file_archivescan_( file_archive_info_t * const archive, archive_scanback func,
+ void * closure )
+{
+}
+
+
+/*
+ * file_collect_archive_content_() - collects information about archive members
+ */
+
+int file_collect_archive_content_( file_archive_info_t * const archive )
+{
+ unsigned short rfa[3];
+
+ static struct dsc$descriptor_s library =
+ {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL};
+
+ unsigned long lfunc = LBR$C_READ;
+ unsigned long typ = LBR$C_TYP_UNK;
+
+ register int status;
+ string buf[ 1 ];
+ char vmspath[ MAXJPATH ] = { 0 };
+
+ m_archive = archive;
+
+ if ( ! filelist_empty( archive->members ) ) filelist_free( archive->members );
+
+ /* Translate path to VMS
+ */
+ string_new( buf );
+ path_translate_to_os_( object_str( archive->file->name ), buf );
+ strcpy( vmspath, buf->value );
+ string_free( buf );
+
+
+ status = lbr$ini_control( &m_lbr_context, &lfunc, &typ, NULL );
+ if ( !( status & 1 ) )
+ return -1;
+
+ library.dsc$a_pointer = vmspath;
+ library.dsc$w_length = strlen( vmspath );
+
+ status = lbr$open( &m_lbr_context, &library, NULL, NULL, NULL, NULL, NULL );
+ if ( !( status & 1 ) )
+ return -1;
+
+ /* Scan main index for modules.
+ * For each module search symbol-index to collect module's symbols.
+ */
+ status = lbr$get_index( &m_lbr_context, &LBR_MODINDEX_NUM, set_archive_member, NULL );
+
+ if ( !( status & 1 ) )
+ return -1;
+
+
+ (void) lbr$close( &m_lbr_context );
+
+ return 0;
+}
+
+#endif /* OS_VMS */
+