mirror of
https://github.com/open-simh/simtools.git
synced 2026-01-27 04:31:45 +00:00
Too much to list all, but includes (in no particular order): - Cleanup for 64-bit builds, MSVC warnings. - Structured help - Help file compiler. - Supports volsets, writes/create work. - Support for I18n in messages, help. - Makefiles. - Initialize volume/volset - Command line editing/history Builds and works on Linux and Windows (VS). Not recently built or tested on other platforms, but not intentinonally broken.
800 lines
26 KiB
C
800 lines
26 KiB
C
/* This is part of ODS2 written by Paul Nankervis,
|
|
* email address: Paulnank@au1.ibm.com
|
|
*
|
|
* ODS2 is distributed freely for all members of the
|
|
* VMS community to use. However all derived works
|
|
* must maintain comments in their source to acknowledge
|
|
* the contributions of the original author and
|
|
* subsequent contributors. This is free software; no
|
|
* warranty is offered, and while we believe it to be useful,
|
|
* you use it at your own risk.
|
|
*/
|
|
|
|
#if !defined( DEBUG ) && defined( DEBUG_SHOWCMD )
|
|
#define DEBUG DEBUG_SHOWCMD
|
|
#else
|
|
#ifndef DEBUG
|
|
#define DEBUG 0
|
|
#endif
|
|
#endif
|
|
|
|
#include "cmddef.h"
|
|
|
|
#ifdef USE_LIBEDIT
|
|
#include <histedit.h>
|
|
#else
|
|
extern FILE *histfile;
|
|
#endif
|
|
|
|
#include "access.h"
|
|
#include "cache.h"
|
|
#include "direct.h"
|
|
#include "f11def.h"
|
|
#include "phyio.h"
|
|
#ifdef USE_VHD
|
|
#include "phyvhd.h"
|
|
#endif
|
|
#include "phyvirt.h"
|
|
#include "version.h"
|
|
|
|
extern defqualsp_t copy_defopt;
|
|
extern qual_t copyquals[];
|
|
|
|
extern defqualsp_t dir_defopt;
|
|
extern qual_t dirquals[];
|
|
|
|
extern defqualsp_t search_defopt;
|
|
extern qual_t searchquals[];
|
|
|
|
static unsigned show_defq( defqualsp_t defs,
|
|
qualp_t qualset, const char *name );
|
|
|
|
static unsigned show_stats( void );
|
|
|
|
static vmscond_t show_history( int qualc, char **qualv );
|
|
|
|
void show_version( int full );
|
|
|
|
static char *get_cwd( void );
|
|
|
|
|
|
/******************************************************************* doshow() */
|
|
|
|
#define hist_max OPT_SHARED_20
|
|
static uint32_t histmax;
|
|
static
|
|
qual_t histquals[] = { {"max-entries", hist_max, 0, DV(&histmax),
|
|
"commands history qual_maxent"},
|
|
{NULL, 0, 0, NV, NULL }
|
|
};
|
|
|
|
static
|
|
qual_t showkwds[] = { {"cwd", 0, ~0u, NV,
|
|
"commands show copy"},
|
|
{"default", 1, ~0u, NV,
|
|
"commands show default"},
|
|
{"devices", 2, ~0u, NV,
|
|
"commands show devices"},
|
|
{"qualifier_style", 3, ~0u, NV,
|
|
"commands show qstyle" },
|
|
{"statistics", 4, ~0u, NV,
|
|
"commands show statistics"},
|
|
{"terminal", 5, ~0u, NV,
|
|
"commands show terminal"},
|
|
{"time", 6, ~0u, NV,
|
|
"commands show time"},
|
|
{"verify", 7, ~0u, NV,
|
|
"commands show verify" },
|
|
{"version", 8, ~0u, NV,
|
|
"commands show version"},
|
|
{"volumes", 9, ~0u, NV,
|
|
"commands show volumes"},
|
|
{"directory_qualifiers",
|
|
10, ~0u, NV,
|
|
"commands show directory"},
|
|
{"copy_qualifiers",
|
|
11, ~0u, NV,
|
|
"commands show copy"},
|
|
{"message", 12, ~0u, NV,
|
|
"commands show message"},
|
|
{"search_qualifiers",
|
|
13, ~0u, NV,
|
|
"commands show search"},
|
|
{"history", 14, ~0u, NV,
|
|
"commands show history"},
|
|
{"help_file", 15, ~0u, NV,
|
|
"commands show helpfile"},
|
|
|
|
{NULL, 0, 0, NV, NULL }
|
|
};
|
|
param_t showpars[] = { {"item_name", REQ, KEYWD, PA(showkwds), "" },
|
|
{"selector", OPT|NOLIM, STRING, NOPA, NULL},
|
|
|
|
{NULL, 0, 0, NOPA, NULL }
|
|
};
|
|
|
|
/*********************************************************** doshow() */
|
|
|
|
DECL_CMD(show) {
|
|
options_t parnum;
|
|
vmscond_t sts;
|
|
|
|
UNUSED(qualc);
|
|
UNUSED(qualv);
|
|
|
|
if( $FAILS(sts = checkquals( &parnum, 0, showkwds, -1, argv+1 )) ) {
|
|
return sts;
|
|
}
|
|
|
|
switch( parnum ) {
|
|
default:
|
|
return SS$_BADPARAM;
|
|
case 0: {
|
|
char *cwd;
|
|
|
|
cwd = get_cwd();
|
|
if( cwd == NULL ) {
|
|
return SS$_BADPARAM;
|
|
}
|
|
printmsg( HELP_SHOWCWD, MSG_TEXT, cwd );
|
|
free( cwd );
|
|
return SS$_NORMAL;
|
|
}
|
|
case 1: {
|
|
unsigned short curlen;
|
|
char curdir[NAM$C_MAXRSS + 1] = { "" };
|
|
struct dsc_descriptor curdsc;
|
|
struct FAB fab;
|
|
struct NAM nam;
|
|
|
|
memset( &curdsc, 0, sizeof( curdsc ) );
|
|
curdsc.dsc_w_length = NAM$C_MAXRSS;
|
|
curdsc.dsc_a_pointer = curdir;
|
|
|
|
if( $FAILS(sts = sys_setddir( NULL, &curlen, &curdsc )) ) {
|
|
return printmsg( sts, 0 );
|
|
}
|
|
|
|
fab = cc$rms_fab;
|
|
nam = cc$rms_nam;
|
|
|
|
nam.nam$b_ess = sizeof(curdir) -1;
|
|
nam.nam$l_esa = curdir;
|
|
fab.fab$l_nam = &nam;
|
|
fab.fab$l_fna = curdir;
|
|
fab.fab$b_fns = (uint8_t)curlen;
|
|
|
|
if( $FAILS(sts = sys_parse(&fab)) ) {
|
|
curdir[curlen] = '\0';
|
|
sts = printmsg( ODS2_INVDEF, 0, curdir );
|
|
} else {
|
|
curdir[nam.nam$b_dev+nam.nam$b_dir] = '\0';
|
|
printf( "%s\n", curdir );
|
|
}
|
|
fab.fab$b_fns =
|
|
nam.nam$b_ess =
|
|
fab.fab$b_dns = 0;
|
|
nam.nam$b_nop = NAM$M_SYNCHK;
|
|
nam.nam$l_rlf = NULL;
|
|
(void) sys_parse( &fab ); /* Release context */
|
|
return sts;
|
|
}
|
|
case 2:
|
|
phyio_show( SHOW_DEVICES );
|
|
virt_show();
|
|
return SS$_NORMAL;
|
|
case 3:
|
|
return printmsg( HELP_SHOWQSTYLE, MSG_TEXT, (qstyle_c == '/')? "/DCL": "-unix" );
|
|
case 4:
|
|
return show_stats();
|
|
case 5: {
|
|
int twid, th;
|
|
termchar( &twid, &th );
|
|
return printmsg( HELP_TERMSIZE, MSG_TEXT, twid, th );
|
|
}
|
|
case 6: {
|
|
char timstr[24] = { "" };
|
|
unsigned short timlen;
|
|
struct dsc_descriptor timdsc;
|
|
|
|
memset( &timdsc, 0, sizeof( timdsc ) );
|
|
timdsc.dsc_w_length = 20;
|
|
timdsc.dsc_a_pointer = timstr;
|
|
if( $FAILS(sts = sys_asctim( &timlen, &timdsc, NULL, 0 )) ) {
|
|
printmsg(ODS2_VMSTIME, 0 );
|
|
return printmsg( sts, MSG_CONTINUE, ODS2_VMSTIME );
|
|
}
|
|
timstr[timlen] = '\0';
|
|
printf(" %s\n",timstr);
|
|
return SS$_NORMAL;
|
|
}
|
|
case 7:
|
|
return printmsg( verify_cmd? HELP_SHOWVERON: HELP_SHOWVEROFF, MSG_TEXT );
|
|
case 8:
|
|
show_version( 1 );
|
|
return SS$_NORMAL;
|
|
case 9:
|
|
show_volumes();
|
|
return SS$_NORMAL;
|
|
case 10:
|
|
return show_defq( dir_defopt, dirquals,
|
|
"directory" );
|
|
case 11:
|
|
return show_defq( copy_defopt, copyquals, "copy" );
|
|
case 12:
|
|
return show_message( argc, argv );
|
|
case 13:
|
|
return show_defq( search_defopt, searchquals, "search" );
|
|
case 14:
|
|
return show_history( qualc, qualv );
|
|
case 15:
|
|
return showhelpfile();
|
|
}
|
|
return SS$_NORMAL;
|
|
}
|
|
|
|
/************************************************************ show_defq() */
|
|
|
|
static unsigned show_defq( defqualsp_t defs,
|
|
qualp_t qualset, const char *name ) {
|
|
int i;
|
|
|
|
printmsg( HELP_SHOWDEFQ, MSG_TEXT, name );
|
|
|
|
if( defs == NULL || defs->qualc == 0 ) {
|
|
printmsg( HELP_SHOWNODEFQ, MSG_TEXT );
|
|
return SS$_NORMAL;
|
|
}
|
|
|
|
for( i = 0; i < defs->qualc; i++ ) {
|
|
qualp_t qp;
|
|
char *qk, *qv;
|
|
size_t len;
|
|
|
|
len = strlen( defs->qualv[i] ) +1;
|
|
if( (qk = malloc( len )) == NULL )
|
|
return SS$_INSFMEM;
|
|
memcpy( qk, defs->qualv[i], len );
|
|
if( (qv = strchr( qk, '=' )) == NULL )
|
|
qv = strchr( qk, ':');
|
|
if( qv != NULL )
|
|
*qv++ = '\0';
|
|
|
|
for( qp = qualset; qp->name != NULL; qp++ ) {
|
|
if( keycomp( qk, qp->name ) ) {
|
|
printf( " %c%s", qstyle_c, qp->name );
|
|
if( qp->qtype != NOVAL && qv != NULL && *qv )
|
|
printf( "=%s", qv );
|
|
putchar( '\n' );
|
|
break;
|
|
}
|
|
}
|
|
free( qk );
|
|
}
|
|
|
|
return SS$_NORMAL;
|
|
}
|
|
|
|
/****************************************************************** show_stats() */
|
|
|
|
/* dostats: print some simple statistics */
|
|
|
|
static unsigned show_stats( void ) {
|
|
printmsg( HELP_SHOWSTATS, MSG_TEXT );
|
|
direct_show();
|
|
cache_show();
|
|
phyio_show(SHOW_STATS);
|
|
|
|
return SS$_NORMAL;
|
|
}
|
|
|
|
/*********************************************************** show_history() */
|
|
static vmscond_t show_history( int qualc, char **qualv ) {
|
|
vmscond_t sts;
|
|
options_t options;
|
|
#ifdef USE_LIBEDIT
|
|
extern History *edithist;
|
|
HistEvent ev;
|
|
#else
|
|
extern uint32_t cmd_histsize;
|
|
uint32_t excess = 0;
|
|
char *buf = NULL;
|
|
size_t bufsize = 80;
|
|
#endif
|
|
int nent;
|
|
|
|
if( $FAILS(sts = checkquals( &options, 0, histquals, qualc, qualv )) ) {
|
|
return sts;
|
|
}
|
|
sts = SS$_NORMAL;
|
|
|
|
#ifdef USE_LIBEDIT
|
|
history( edithist, &ev, H_GETSIZE );
|
|
nent = ev.num;
|
|
if( nent < 0 ) {
|
|
fprintf( stderr, "GETSIZE error (%d) %s\n", ev.num, ev.str );
|
|
return sts;
|
|
}
|
|
if( !(options & hist_max) || histmax > (uint32_t)nent ) {
|
|
histmax = nent;
|
|
}
|
|
if( histmax == 0 )
|
|
return printmsg( HELP_SHOWNOCMDHIST, 0 );
|
|
if( history( edithist, &ev, H_FIRST ) < 0 ) { /* Most recent cmd */
|
|
fprintf( stderr, "FIRST error (%d) %s\n", ev.num, ev.str );
|
|
return sts;
|
|
}
|
|
for( nent = 1; (uint32_t)nent < histmax; nent++ ) { /* Find MAXth older cmd */
|
|
if( history( edithist, &ev, H_NEXT ) < 0 ) {
|
|
fprintf( stderr, "NEXT error (%d) %s\n", ev.num, ev.str );
|
|
return sts;
|
|
}
|
|
}
|
|
for( nent = 0; (uint32_t)nent < histmax; nent++ ) {
|
|
printmsg( HELP_SHOWCMDHISTLN, MSG_TEXT, ev.num, ev.str );
|
|
history( edithist, &ev, H_PREV );
|
|
}
|
|
return sts;
|
|
#else
|
|
if( histfile == NULL ) {
|
|
printmsg( HELP_SHOWNOCMDHIST, 0 );
|
|
return sts;
|
|
}
|
|
fseek( histfile, 0, SEEK_SET );
|
|
for( nent = 0; ; ) { /* Count history lines */
|
|
int c;
|
|
|
|
c = getc( histfile );
|
|
if( c == EOF ) break;
|
|
if( c == '\n' ) ++nent;
|
|
}
|
|
if( !(options & hist_max) || histmax > (uint32_t)nent ) {
|
|
histmax = nent;
|
|
}
|
|
if( histmax == 0 )
|
|
return printmsg( HELP_SHOWNOCMDHIST, 0 );
|
|
if( (uint32_t)nent > cmd_histsize ) /* Hide excess file lines if size reduced */
|
|
excess = nent - cmd_histsize;
|
|
if( histmax > (uint32_t)nent - excess )
|
|
histmax = (uint32_t)nent - excess; /* Reduce request to visible window */
|
|
histmax = nent - histmax;
|
|
fseek( histfile, 0, SEEK_SET );
|
|
for( nent = 0; (uint32_t)nent < histmax; ) { /* Skip old lines */
|
|
int c;
|
|
|
|
c = getc( histfile );
|
|
if( c == EOF ) break;
|
|
if( c == '\n' ) ++nent;
|
|
}
|
|
for( ; ; nent++ ) { /* Get full lines for display */
|
|
char *line;
|
|
|
|
if( (line = fgetline( histfile, FALSE, &buf, &bufsize )) == NULL )
|
|
break;
|
|
printmsg( HELP_SHOWCMDHISTLN, MSG_TEXT, nent + 1 - excess, line );
|
|
}
|
|
if( buf != NULL ) free( buf );
|
|
fseek( histfile, 0, SEEK_END );
|
|
return sts;
|
|
#endif
|
|
}
|
|
|
|
/*********************************************************** show_version() */
|
|
|
|
void show_version( int full ) {
|
|
char *detail, *version;
|
|
#ifdef DEBUG_BUILD
|
|
extern int vld_present;
|
|
#endif
|
|
|
|
#ifdef USE_LIBEDIT
|
|
printmsg( HELP_SHOWVERSRL, MSG_TEXT, MNAME(MODULE_NAME), MODULE_IDENT,
|
|
__DATE__, __TIME__, LIBEDIT_MAJOR, LIBEDIT_MINOR );
|
|
#else
|
|
printmsg( HELP_SHOWVERS, MSG_TEXT, MNAME(MODULE_NAME), MODULE_IDENT,
|
|
__DATE__, __TIME__ );
|
|
#endif
|
|
|
|
if( !full ) return;
|
|
|
|
/* Determine what platform and compiler were targeted for this image */
|
|
|
|
#ifdef _MSC_VER
|
|
#define strcat( _dst, _src ) strcat_s( (_dst), MAXSTRL, (_src) )
|
|
#endif
|
|
#define MAXSTRL 512
|
|
|
|
if( (detail = malloc( MAXSTRL * 2 )) == NULL ) {
|
|
return;
|
|
}
|
|
detail[0] = '\0';
|
|
version = detail + MAXSTRL;
|
|
version[0] = '\0';
|
|
|
|
/* N.B. The order of detection is intended to deal with ambiguities,
|
|
* and does not inidcate any particular preference or judgement.
|
|
*
|
|
* The detection scheme is an amalgam of tests from various sources.
|
|
* It has not been run in all these environments by the author,
|
|
* (or perhaps by anyone), so errors may exist and should be reported.
|
|
* Additions are also welcome.
|
|
*/
|
|
|
|
#if defined __ANDROID__
|
|
strcat( detail, "Android" );
|
|
#elif defined __linux__
|
|
strcat( detail, "Linux" );
|
|
#elif defined __APPLE__
|
|
#include "TargetConditionals.h"
|
|
#if TARGET_IPHONE_SIMULATOR
|
|
strcat( detail, "iOS Simulator" );
|
|
#elif TARGET_OS_IPHONE
|
|
strcat( detail, "iOS device" );
|
|
#elif TARGET_OS_MAC
|
|
strcat( detail, "OS X" );
|
|
#else
|
|
strcat( detail, "Unknown Apple platform" );
|
|
#endif
|
|
#elif defined __CYGWIN__ && !defined _WIN32
|
|
strcat( detail, "Cygwin" );
|
|
#elif defined _WIN64
|
|
strcat( detail, "Windows (64-bit)" );
|
|
#elif defined _WIN32
|
|
strcat( detail, "Windows (32-bit)" );
|
|
#elif defined VMS || defined __VMS
|
|
#if defined __ia64__ || defined __ia64 || defined _M_IA64
|
|
strcat( detail, "VMS (Itanium)" );
|
|
#elif defined __ALPHA || defined __ALPHA_AXP
|
|
strcat( detail, "VMS (Alpha)" );
|
|
#elif defined VAX || defined __VAX
|
|
strcat( detail, "VMS (VAX)" );
|
|
#else
|
|
strcat( detail, "VMS" );
|
|
#endif
|
|
#if defined __VMS_VER
|
|
snprintf( detail + strlen( detail ), MAXSTRL - strlen( detail ),
|
|
"%c%u.%u-%u%c",
|
|
(__VMS_VER % 100u),
|
|
(__VMS_VER / 10000000u),
|
|
(__VMS_VER / 100000u) % 100u,
|
|
(__VMS_VER / 10000u) % 10u,
|
|
(__VMS_VER / 100u) % 100u );
|
|
#endif
|
|
#elif defined __osf__
|
|
strcat( detail, "DEC OSF/1 (Tru64)" );
|
|
#elif defined ultrix || defined __ultrix || defined __ultrix__
|
|
strcat( detail, "Ultrix" );
|
|
#elif defined UNICOS
|
|
strcat( detail, "UNICOS" );
|
|
#elif defined _CRAY || defined __crayx1
|
|
strcat( detail, "UNICOSD/mp" );
|
|
#elif defined _AIX
|
|
#if defined __64BIT__
|
|
strcat( detail, "AIX (64-bit)" );
|
|
#else
|
|
strcat( detail, "AIX" );
|
|
#endif
|
|
#elif defined(__sun) && defined(__SVR4)
|
|
strcat( detail, "Solaris" );
|
|
#elif defined __hpux
|
|
strcat( detail, "HP-UX" );
|
|
#elif defined __NetBSD__
|
|
strcat( detail, "NetBSD" );
|
|
#elif defined __OpenBSD__
|
|
strcat( detail, "OpenBSD" );
|
|
|
|
/* Generic */
|
|
#elif defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
|
|
#include <sys/param.h>
|
|
#if defined(BSD)
|
|
strcat( detail, "BSD Unix" );
|
|
#endif
|
|
#elif defined_POSIX_VERSION
|
|
strcat( detail, "POSIX" );
|
|
#if( _POSIX_VERSION >= 200809L )
|
|
strcat( detail, ".1-2008" );
|
|
#elif( _POSIX_VERSION >= 200112L )
|
|
strcat( detail, ".1-2001" );
|
|
#elif( _POSIX_VERSION >= 199506L )
|
|
strcat( detail, ".1-1995" );
|
|
#elif( _POSIX_VERSION >= 199309L )
|
|
strcat( detail, ".1-1993" );
|
|
#elif( _POSIX_VERSION >= 199009L )
|
|
strcat( detail,".1-1990" );
|
|
#elif( _POSIX_VERSION >= 198808L )
|
|
strcat( detail,".1-1988" );
|
|
#endif
|
|
#else
|
|
strcat( detail, "Unknown platform" );
|
|
#endif
|
|
|
|
/* Hardware */
|
|
|
|
#if defined(__powerpc__) || defined(__ppc__) || defined(__PPC__)
|
|
#if defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) || \
|
|
defined(__64BIT__) || defined(_LP64) || defined(__LP64__)
|
|
strcat( detail, " PowerPC (64-bit)" );
|
|
#else
|
|
strcat( detail, " PowerPC (32-bit)" );
|
|
#endif
|
|
#elif defined(__ia64) || defined(__itanium__) || defined(_M_IA64)
|
|
#if !defined VMS && !defined __VMS
|
|
strcat( detail, " Itanium " );
|
|
#endif
|
|
#elif defined(__sparc)
|
|
strcat( detail, " SPARC" );
|
|
#elif defined(__x86_64__) || defined(_M_X64)
|
|
strcat( detail, " x86-64" );
|
|
#elif defined(__i386) || defined(_M_IX86)
|
|
strcat( detail, " x86-32" );
|
|
#elif defined __alpha || defined __alpha || defined _M_ALPHA
|
|
#if !defined VMS
|
|
strcat( detail, " Alpha" );
|
|
#endif
|
|
#elif defined VAX || defined __VAX
|
|
strcat( detail, " VAX" );
|
|
#elif defined __aarch64__
|
|
strcat( detail, " ARM64" );
|
|
#elif defined __thumb__
|
|
strcat( detail, " ARM (Thumb)" );
|
|
#elif defined __arm__
|
|
strcat( detail, " ARM " )
|
|
#elif defined __hppa__ || defined __HPPA__ || defined _hppa
|
|
strcat( detail, " HP/PA RISC" );
|
|
#elif defined __m68k__ || defined M68000 || defined __MC68K__
|
|
strcat( detail, " Motorola 68000" );
|
|
#elif defined __mips__ || defined __mips
|
|
strcat( detail, " MIPS" );
|
|
#elif defined __THW_RS6000__
|
|
strcat( detail, " RS6000" );
|
|
#elif defined __370__ || defined __THW_370__ || defined __s390__ || defined __s390x || \
|
|
defined __zarch__ || defined __SYSC_ZARCH__
|
|
strcat( detail, " System Z (370)" );
|
|
#endif
|
|
|
|
#if defined __STDC_VERSION__
|
|
#if( __STDC_VERSION__ >= 201112L )
|
|
strcat( detail, " C11" );
|
|
#elif( __STDC_VERSION__ >= 199901L )
|
|
strcat( detail, " C99" );
|
|
#elif( __STDC_VERSION__ >= 199409L )
|
|
strcat( detail, " C94" );
|
|
#else
|
|
strcat( detail, " C89/90" );
|
|
#endif
|
|
#elif defined __STDC__
|
|
strcat( detail, " C89/90" );
|
|
#else
|
|
strcat( detail, " C" );
|
|
#endif
|
|
|
|
#if defined __LSB_VERSION__
|
|
snprintf( detail + strlen( detail ), MAXSTRL - strlen( detail ),
|
|
" LSB V%u.%u",
|
|
(__LSB_VERSION__ / 10), (__LSB_VERSION__%10) );
|
|
#endif
|
|
|
|
#if ODS2_BIG_ENDIAN
|
|
strcat( detail, " Big-Endian" );
|
|
#endif
|
|
printmsg( HELP_SHOWVERPLATFM, MSG_TEXT, detail );
|
|
|
|
/* Compiler */
|
|
|
|
detail[0] = '\0';
|
|
#if defined __clang__
|
|
strcat( detail, "Clang/LLVM" );
|
|
snprintf( version, MAXSTRL, "%d.%d.%d",
|
|
__clang_major__, __clang_minor__, __clang_patchlevel__ );
|
|
#elif defined(__ICC) || defined(__INTEL_COMPILER)
|
|
strcat( detail, "ICC" );
|
|
#if defined __VERSION__
|
|
strcat( version, __VERSION__ );
|
|
#endif
|
|
#elif defined(__HP_cc) || defined(__HP_aCC)
|
|
strcat( detail, "HP C" );
|
|
#if defined __HP_aCC && __HP_aCC > 1
|
|
snprintf( version, MAXSTRL, "%02u.%02u.%02u",
|
|
(__HP_aCC / 10000u ),
|
|
(__HP_aCC / 100u ) % 100u,
|
|
(__HP_aCC % 100u ) % 100u );
|
|
#elif defined __HP_cc && __HP_cc > 1
|
|
snprintf( version, MAXSTRL, "%02u.%02u.%02u",
|
|
(__HP_cc / 10000u ),
|
|
(__HP_cc / 100u ) % 100u,
|
|
(__HP_cc % 100u ) % 100u );
|
|
#endif
|
|
#elif defined(__IBMC__) || defined(__IBMCPP__)
|
|
strcat( detail, "IBM XL C" );
|
|
#if defined __COMPILER_VER__
|
|
strcat( version, __COMPILER_VER__ );
|
|
#elif defined __xlxc__
|
|
strcat( version, __xlc__ );
|
|
#else
|
|
strcat( version, __IBMC__ );
|
|
#endif
|
|
#elif defined __LCC__
|
|
strcat( detail, "LCC" );
|
|
#elif defined ___llvm
|
|
strcat( detail, "LLVM" );
|
|
#elif defined __MINGW64__
|
|
strcat( detail, "MinGW-w64" );
|
|
#if defined __MINGW64_VERSION_MAJOR
|
|
snprintf( version, MAXSTRL, "%u.%u",
|
|
__MINGW64_VERSION_MAJOR, __MINGW64_VERSION_MINOR );
|
|
#endif
|
|
#elif defined __MINGW32__
|
|
strcat( detail, "MinGW" );
|
|
#if defined __MINGW32_MAJOR_VERSIONR
|
|
snprintf( version, MAXSTRL, "%u.%u",
|
|
__MINGW32_MAJOR_VERSION, __MINGW32_MINOR_VERSION );
|
|
#endif
|
|
#elif defined(__PGI)
|
|
strcat( detail, "PGCC" );
|
|
snprintf( version, MAXSTRL, "%u.%u.%u",
|
|
__PGIC__, __PGIC_MINOR, __PGIC_PATCHLEVEL__ );
|
|
#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
|
|
strcat( detail, "Solaris Studio" );
|
|
#if defined __SUNPRO_C
|
|
snprintf( version, MAXSTRL, "%u.%u.%u",
|
|
(__SUNPRO_C / 0x100 ),
|
|
(__SUNPRO_C / 0x10 ) % 0x100,
|
|
(__SUNPRO_C % 0x10 ) );
|
|
#elif defined __SUNPRO_CC
|
|
snprintf( version, MAXSTRL, "%u.%u.%u",
|
|
(__SUNPRO_CC / 0x100 ),
|
|
(__SUNPRO_CC / 0x10 ) % 0x100,
|
|
(__SUNPRO_CC % 0x10 ) );
|
|
#endif
|
|
#elif defined __sgi || defined sgi
|
|
strcat( detail, "MIPSpro" );
|
|
#if defined _SGI_COMPILER_VERSION
|
|
snprintf( version, MAXSTRL, "%u.%u.%u",
|
|
(_SGI_COMPILER_VERSION / 100u),
|
|
(_SGI_COMPILER_VERSION / 10u) % 10u,
|
|
(_SGI_COMPILER_VERSION % 10u) );
|
|
#elif defined _COMPILER_VERSION
|
|
snprintf( version, MAXSTRL, "%u.%u.%u",
|
|
(_COMPILER_VERSION / 100u),
|
|
(_COMPILER_VERSION / 10u) % 10u,
|
|
(_COMPILER_VERSION % 10u) );
|
|
#endif
|
|
#elif defined _MSC_FULL_VER
|
|
strcat( detail, "Visual C++" );
|
|
snprintf( version, MAXSTRL, "%d.%02d.%05d.%02d",
|
|
(_MSC_FULL_VER / 10000000u),
|
|
(_MSC_FULL_VER / 100000u ) % 100u,
|
|
(_MSC_FULL_VER % 100000u ),
|
|
_MSC_BUILD);
|
|
#ifdef _MSC_VER
|
|
{ /* https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros */
|
|
struct {
|
|
char *ide; unsigned ver; } ides[] = {
|
|
{"Visual Studio 6.0", 1200},
|
|
{"Visual Studio .NET 2002 (7.0)", 1300},
|
|
{"Visual Studio .NET 2003 (7.1)", 1310},
|
|
{"Visual Studio 2005 (8.0)", 1400},
|
|
{"Visual Studio 2008 (9.0)", 1500},
|
|
{"Visual Studio 2010 (10.0)", 1600},
|
|
{"Visual Studio 2012 (11.0)", 1700},
|
|
{"Visual Studio 2013 (12.0)", 1800},
|
|
{"Visual Studio 2015 (14.0)", 1900},
|
|
{"Visual Studio 2017 RTW (15.0)", 1910},
|
|
{"Visual Studio 2017 version 15.3", 1911},
|
|
{"Visual Studio 2017 version 15.5", 1912},
|
|
{"Visual Studio 2017 version 15.6", 1913},
|
|
{"Visual Studio 2017 version 15.7", 1914},
|
|
{"Visual Studio 2017 version 15.8", 1915},
|
|
{"Visual Studio 2017 version 15.9", 1916},
|
|
{"Visual Studio 2019 RTW (16.0)", 1920},
|
|
{"Visual Studio 2019 version 16.1", 1921},
|
|
{"Visual Studio 2019 version 16.2", 1922},
|
|
{"Visual Studio 2019 version 16.3", 1923},
|
|
{"Visual Studio 2019 version 16.4", 1924},
|
|
{"Visual Studio 2019 version 16.5", 1925},
|
|
{"Visual Studio 2019 version 16.6", 1926},
|
|
{"Visual Studio 2019 version 16.7", 1927},
|
|
{"Visual Studio 2019 version 16.8, 16.9", 1928},
|
|
{"Visual Studio 2019 version 16.10, 16.11", 1929},
|
|
{"Visual Studio 2022 RTW (17.0)", 1930},
|
|
{"Visual Studio 2022 version 17.1", 1931},
|
|
{"Visual Studio 2022 version 17.2", 1932},
|
|
{"Visual Studio 2022 version 17.3", 1933},
|
|
{"Visual Studio 2022+", 100000}, }, *ip;
|
|
for( ip = ides; ip->ver < _MSC_VER; ip++ )
|
|
;
|
|
strcat( version, ", " );
|
|
strcat( version, ip->ide );
|
|
}
|
|
#endif
|
|
#elif defined _MSC_VER
|
|
strcat( detail, "Visual Studio" );
|
|
snprintf( version, MAXSTRL, "%d", _MSC_VER );
|
|
#elif defined __CC_ARM
|
|
strcat( version, "ARM Compiler" );
|
|
snprintf( version, MAXSTRL, "%u.%u.%u build %u",
|
|
(__ARMCC_VERSION / 100000u ),
|
|
(__ARMCC_VERSION / 10000u ) % 10u,
|
|
(__ARMCC_VERSION / 1000u ) % 10u,
|
|
(__ARMCC_VERSION % 1000u ) );
|
|
#elif defined __GNUC__
|
|
strcat( detail, "gcc" );
|
|
#if defined __VERSION__
|
|
strcat( version, __VERSION__ );
|
|
#else
|
|
snprintf( version, MAXSTRL, "%d.%d", __GNUC__, __GNUC_MINOR__ );
|
|
#endif
|
|
#elif defined __DECC__ || defined _DECC
|
|
strcat( detail, "DEC C" );
|
|
{
|
|
char ct;
|
|
switch( (__DECC_VER / 10000u) % 10u ) {
|
|
case 6:
|
|
ct = 'T'; break;
|
|
case 8:
|
|
ct = 'S'; break;
|
|
case 9:
|
|
ct = 'V'; break;
|
|
default:
|
|
ct = 'X'; break;
|
|
}
|
|
snprintf( version, MAXSTRL, "%c%u.%u-%03u", ct,
|
|
(__DECC_VER / 10000000u),
|
|
(__DECC_VER / 100000u) % 100u,
|
|
(__DECC_VER % 10000u) );
|
|
}
|
|
#elif defined VAXC || defined VAX11C || defined __VAXC || defined __VAX11C
|
|
strcat( detail, "VAX C" );
|
|
#endif
|
|
if( !version[0] )
|
|
strcat( version, "unknown" );
|
|
#undef strcat
|
|
#undef MAXSTRL
|
|
|
|
printmsg( HELP_SHOWVERCOMPLR, MSG_TEXT, detail, version );
|
|
|
|
free( detail ); /* includes version */
|
|
detail = version = NULL;
|
|
|
|
#ifdef DEBUG_BUILD
|
|
if( vld_present )
|
|
printmsg( HELP_SHOWVLD, MSG_TEXT );
|
|
#endif
|
|
#ifdef USE_WNASPI32
|
|
printmsg( HELP_SHOWVERSCSI, MSG_TEXT );
|
|
#endif
|
|
putchar( ' ');
|
|
phyio_show( SHOW_FILE64 );
|
|
#ifdef USE_VHD
|
|
putchar( ' ');
|
|
(void) phyvhd_available( TRUE );
|
|
#else
|
|
printmsg( HELP_SHOWVERNOVHD, MSG_TEXT );
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
/*********************************************************** get_cwd() */
|
|
|
|
static char *get_cwd( void ) {
|
|
size_t size = 32;
|
|
char *buf = NULL;
|
|
while( 1 ) {
|
|
char *nbuf;
|
|
nbuf = (char *)realloc( buf, size );
|
|
if( nbuf == NULL ) {
|
|
free( buf );
|
|
return NULL;
|
|
}
|
|
buf = nbuf;
|
|
if( getcwd( buf, size ) != NULL )
|
|
break;
|
|
if( errno != ERANGE ) {
|
|
printmsg( ODS2_OSERROR, 0, strerror( errno ) );
|
|
return NULL;
|
|
}
|
|
size *= 2;
|
|
}
|
|
return buf;
|
|
}
|