mirror of
https://github.com/open-simh/simtools.git
synced 2026-01-22 18:41:42 +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.
499 lines
15 KiB
C
499 lines
15 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_SETCMD )
|
|
#define DEBUG DEBUG_SETCMD
|
|
#else
|
|
#ifndef DEBUG
|
|
#define DEBUG 0
|
|
#endif
|
|
#endif
|
|
|
|
#include "cmddef.h"
|
|
|
|
#ifdef USE_LIBEDIT
|
|
#include <histedit.h>
|
|
extern EditLine *editline;
|
|
extern History *edithist;
|
|
#endif
|
|
|
|
static hlpfunc_t sethelp;
|
|
|
|
static vmscond_t setcwd( char *newdef );
|
|
static vmscond_t setdef( char *newdef );
|
|
|
|
static vmscond_t savequals( options_t defval, qual_t *qp,
|
|
int qualc, char **qualv,
|
|
defqualsp_t *saveloc );
|
|
static void set_exit( void );
|
|
|
|
|
|
/******************************************************************* doset() */
|
|
|
|
#define set_msgdef OPT_GENERIC_1
|
|
|
|
/* Indexes must match in doset() & sethelp() */
|
|
|
|
static uint32_t histmax;
|
|
|
|
static
|
|
qual_t setkwds[] = { {"cwd", 0, 0, NV,
|
|
"commands set item_name item_cwd"},
|
|
{"directory_qualifiers", 1, 0, NV,
|
|
"commands set item_name item_dirquals"},
|
|
{"copy_qualifiers", 2, 0, NV,
|
|
"commands set item_name item_copyquals" },
|
|
{"default", 3, 0, NV,
|
|
"commands set item_name item_setdef"},
|
|
{"error_exit", 4, 0, NV,
|
|
"-commands set item_name item_seterrxit"},
|
|
{"noerror_exit", 5, 0, NV, NULL },
|
|
{"message", 6, 0, NV,
|
|
"commands set item_name item_setmsg"},
|
|
{"qualifier_style", 7, 0, NV,
|
|
"commands set item_name item_qualstyle"},
|
|
{"search_qualifiers", 8, 0, NV,
|
|
"commands set item_name item_searchquals"},
|
|
{"verify", 9, 0, NV,
|
|
"-commands set item_name item_verify"},
|
|
{"noverify", 10, 0, NV, NULL },
|
|
#ifdef USE_LIBEDIT
|
|
{"key_bindings", 11, 0, NV,
|
|
"commands set item_name item_key_bindings"},
|
|
#endif
|
|
{"history_limit", 12, 0, DV(&histmax),
|
|
"commands set item_name item_history_limit"},
|
|
{"help_file", 13, 0, NV,
|
|
"commands set item_name item_helpfile"},
|
|
|
|
{NULL, 0, 0, NV, NULL }
|
|
};
|
|
|
|
static
|
|
qual_t setmsgkwdsp[] = {{"facility", MSG_FACILITY, 0, NV,
|
|
"commands set item_name item_msgfac"},
|
|
{"nofacility", 0, MSG_FACILITY, NV, NULL},
|
|
{"severity", MSG_SEVERITY, 0, NV,
|
|
"commands set item_name item_msgsev"},
|
|
{"noseverity", 0, MSG_SEVERITY, NV, NULL},
|
|
{"identification", MSG_NAME, 0, NV,
|
|
"commands set item_name item_msgid"},
|
|
{"noidentification", 0, MSG_NAME, NV, NULL},
|
|
{"text", MSG_TEXT, 0, NV,
|
|
"commands set item_name item_msgtext"},
|
|
{"notext", 0, MSG_TEXT, NV, NULL},
|
|
{"default", set_msgdef, 0, NV,
|
|
"commands set item_name item_default"},
|
|
|
|
{NULL, 0, 0, NV, NULL }
|
|
};
|
|
|
|
static
|
|
qual_t setqskwds[] = {{"unix", 1, 0, NV, "commands set value value_unix"},
|
|
{"dcl", 2, 0, NV, "commands set value value_dcl"},
|
|
{"vms", 2, 0, NV, NULL },
|
|
|
|
{NULL, 0, 0, NV, NULL }
|
|
};
|
|
param_t setpars[] = { {"item_name", REQ, KEYWD, PA(setkwds), "" },
|
|
{"value" , CND, KEYWD, sethelp, setqskwds, "" },
|
|
|
|
{NULL, 0, 0, NOPA, NULL },
|
|
};
|
|
|
|
/*********************************************************** doset() */
|
|
|
|
extern qual_t copyquals[];
|
|
extern const int copy_defaults;
|
|
extern defqualsp_t copy_defopt;
|
|
|
|
extern qual_t dirquals[];
|
|
extern const int dir_defaults;
|
|
extern defqualsp_t dir_defopt;
|
|
|
|
extern qual_t searchquals[];
|
|
extern const int search_defaults;
|
|
extern defqualsp_t search_defopt;
|
|
|
|
extern uint32_t cmd_histsize;
|
|
|
|
DECL_CMD(set) {
|
|
options_t parnum;
|
|
vmscond_t sts;
|
|
|
|
if( $FAILS(sts = checkquals( &parnum, 0, setkwds, -1, argv+1 )) ) {
|
|
return sts;
|
|
}
|
|
switch( parnum ) {
|
|
default:
|
|
return SS$_BADPARAM;
|
|
case 0: /* default */
|
|
case 3: /* current working directory */
|
|
if( qualc )
|
|
return printmsg( ODS2_NOQUALSOK, 0 );
|
|
return (parnum == 0)? setcwd( argv[2] ) : setdef( argv[2] );
|
|
case 1:{ /* directory_qualifiers */
|
|
if( qualc == 0 )
|
|
return printmsg( ODS2_NOQUALS, 0 );
|
|
return savequals( dir_defaults, dirquals,
|
|
qualc, qualv, &dir_defopt );
|
|
}
|
|
case 2:{ /* copy_qualifiers */
|
|
if( qualc == 0 )
|
|
return printmsg( ODS2_NOQUALS, 0 );
|
|
return savequals( copy_defaults, copyquals,
|
|
qualc, qualv, ©_defopt );
|
|
}
|
|
case 4:
|
|
if( qualc )
|
|
return printmsg( ODS2_NOQUALSOK, 0 );
|
|
error_exit = TRUE;
|
|
return SS$_NORMAL;
|
|
case 5:
|
|
if( qualc )
|
|
return printmsg( ODS2_NOQUALSOK, 0 );
|
|
error_exit = FALSE;
|
|
return SS$_NORMAL;
|
|
case 6: { /* message file */
|
|
options_t options;
|
|
|
|
if( qualc != 0 ) {
|
|
if( $FAILS(sts = checkquals( &options, get_message_format(),
|
|
setmsgkwdsp, qualc, qualv )) )
|
|
return sts;
|
|
if( argc > 2 )
|
|
return printmsg( ODS2_NOPAROK, 0 );
|
|
if( options & set_msgdef ) {
|
|
if( (options & ~set_msgdef) != get_message_format() )
|
|
return printmsg( ODS2_INCONQUAL, 0 );
|
|
return set_message_file( NULL );
|
|
}
|
|
if( $FAILS(sts = set_message_format( options )) )
|
|
return printmsg( sts, 0 );
|
|
return SS$_NORMAL;
|
|
}
|
|
if( argc > 3 )
|
|
return printmsg( ODS2_TOOMANY, 0, "parameters" );
|
|
if( argc < 3 )
|
|
return printmsg( ODS2_TOOFEW, 0, "parameters" );
|
|
if( $FAILS(sts = set_message_file( argv[2] )) )
|
|
return printmsg(sts, 0 );
|
|
return SS$_NORMAL;
|
|
}
|
|
case 7: { /* qualifier_style */
|
|
options_t par;
|
|
|
|
if( qualc )
|
|
return printmsg( ODS2_NOQUALSOK, 0 );
|
|
if( $FAILS(sts = checkquals( &par, 0, setqskwds, 1, argv+2 )) ) {
|
|
return sts;
|
|
}
|
|
switch(par) {
|
|
default:
|
|
abort();
|
|
case 2:
|
|
qstyle_s = "/";
|
|
break;
|
|
case 1:
|
|
qstyle_s = "-";
|
|
break;
|
|
}
|
|
return SS$_NORMAL;
|
|
}
|
|
case 8:{ /* search_qualifiers */
|
|
if( qualc == 0 )
|
|
return printmsg( ODS2_NOQUALS, 0 );
|
|
return savequals( search_defaults, searchquals,
|
|
qualc, qualv, &search_defopt );
|
|
}
|
|
case 9:
|
|
if( qualc )
|
|
return printmsg( ODS2_NOQUALSOK, 0 );
|
|
verify_cmd = TRUE;
|
|
return SS$_NORMAL;
|
|
case 10:
|
|
if( qualc )
|
|
return printmsg( ODS2_NOQUALSOK, 0 );
|
|
verify_cmd = FALSE;
|
|
return SS$_NORMAL;
|
|
#ifdef USE_LIBEDIT
|
|
case 11: {
|
|
char *av[20];
|
|
int i, ac;
|
|
|
|
ac = argc -2;
|
|
for( i = 0; i < 20; i++ ) {
|
|
if( i < ac )
|
|
av[i] = argv[i+2];
|
|
else
|
|
av[i] = NULL;
|
|
}
|
|
|
|
el_set( editline, EL_BIND,
|
|
av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7],
|
|
av[8], av[9], av[10], av[11], av[12], av[13], av[14], av[15],
|
|
av[16], av[17], av[18], NULL );
|
|
|
|
return SS$_NORMAL;
|
|
}
|
|
#endif
|
|
case 12: {
|
|
#ifdef USE_LIBEDIT
|
|
HistEvent ev;
|
|
|
|
if( qualc )
|
|
return printmsg( ODS2_NOQUALSOK, 0 );
|
|
if( histmax < 1 )
|
|
return printmsg( HELP_SETCMDHISTVAL, 0 );
|
|
if( history( edithist, &ev, H_SETSIZE, histmax ) >= 0 ) {
|
|
cmd_histsize = histmax;
|
|
}
|
|
#else
|
|
if( qualc )
|
|
return printmsg( ODS2_NOQUALSOK, 0 );
|
|
if( histmax < 1 )
|
|
return printmsg( HELP_SETCMDHISTVAL, 0 );
|
|
cmd_histsize = histmax;
|
|
#endif
|
|
return SS$_NORMAL;
|
|
}
|
|
case 13:
|
|
if( qualc )
|
|
return printmsg( ODS2_NOQUALSOK, 0 );
|
|
if( argc > 3 )
|
|
return printmsg( ODS2_TOOMANY, 0, "parameters" );
|
|
if( argc < 3 )
|
|
return printmsg( ODS2_TOOFEW, 0, "parameters" );
|
|
if( $FAILS(sts = sethelpfile( argv[2], NULL, NULL )) )
|
|
return printmsg( sts, 0 );
|
|
return sts;
|
|
} /* switch */
|
|
}
|
|
|
|
/************************************************************ sethelp() */
|
|
|
|
static const char *sethelp( CMDSETp_t cmd, paramp_t p,
|
|
int argc, char **argv ) {
|
|
options_t par;
|
|
vmscond_t sts;
|
|
|
|
UNUSED( cmd );
|
|
UNUSED( argc );
|
|
|
|
if( argc == 1 ) {
|
|
p->helpstr = "";
|
|
p->ptype = KEYWD;
|
|
p->arg = setkwds;
|
|
return getmsg( HELP_SETVALUE, MSG_TEXT );
|
|
}
|
|
|
|
if( $FAILS(sts = checkquals( &par, 0, setkwds, -1, argv+1 )) ) {
|
|
return NULL;
|
|
}
|
|
|
|
switch( par ) {
|
|
case 0:
|
|
p->helpstr = "commands set item_name type_cwd";
|
|
p->ptype = STRING;
|
|
break;
|
|
case 1:
|
|
p->helpstr = "commands set item_name type_dirquals";
|
|
p->ptype = QUALS;
|
|
p->arg = dirquals;
|
|
break;
|
|
case 2:
|
|
p->helpstr = "commands set item_name type_copyquals";
|
|
p->ptype = QUALS;
|
|
p->arg = copyquals;
|
|
break;
|
|
case 3:
|
|
p->helpstr = "commands set item_name type_setdef";
|
|
p->ptype = FSPEC;
|
|
break;
|
|
case 4:
|
|
case 5:
|
|
p->helpstr = "commands set item_name type_seterrxit";
|
|
p->ptype = NONE;
|
|
break;
|
|
case 6:
|
|
p->helpstr = "commands set item_name type_setmsg";
|
|
p->ptype = QUALS;
|
|
p->arg = setmsgkwdsp;
|
|
break;
|
|
case 7:
|
|
p->helpstr = "commands set item_name type_qualstyle";
|
|
p->ptype = KEYWD;
|
|
p->arg = setqskwds;
|
|
break;
|
|
case 8:
|
|
p->helpstr = "commands set item_name type_searchquals";
|
|
p->ptype = QUALS;
|
|
p->arg = searchquals;
|
|
break;
|
|
case 9:
|
|
case 10:
|
|
p->helpstr = "commands set item_name item_verify";
|
|
p->ptype = NONE;
|
|
break;
|
|
#ifdef USE_LIBEDIT
|
|
case 11:
|
|
p->helpstr = "commands set item_name item_key_bindings";
|
|
p->ptype = STRING;
|
|
break;
|
|
#endif
|
|
case 12:
|
|
p->helpstr = "commands set item_name item_history_limit";
|
|
p->ptype = STRING;
|
|
break;
|
|
case 13:
|
|
p->helpstr = "commands set item_name item_helpfile";
|
|
p->ptype = NONE;
|
|
break;
|
|
default:
|
|
fprintf( stderr, "Missing help key for param %d\n", par );
|
|
abort();
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/*********************************************************** setcwd() */
|
|
|
|
static vmscond_t setcwd( char *newdef ) {
|
|
if( chdir( newdef ) != 0 ) {
|
|
int err;
|
|
|
|
err = errno;
|
|
printmsg( ODS2_SETCWD, 0 );
|
|
return printmsg( ODS2_OSERROR, MSG_CONTINUE, ODS2_SETCWD,
|
|
strerror( err ) );
|
|
}
|
|
return SS$_NORMAL;
|
|
}
|
|
|
|
/*********************************************************** setdef() */
|
|
|
|
static int default_set = FALSE;
|
|
|
|
static vmscond_t setdef( char *newdef ) {
|
|
register vmscond_t sts;
|
|
struct dsc_descriptor defdsc = { 0, 0, 0, NULL };
|
|
|
|
defdsc.dsc_a_pointer = (char *) newdef;
|
|
defdsc.dsc_w_length = (unsigned short)strlen( defdsc.dsc_a_pointer );
|
|
if( $SUCCESSFUL(sts = sys_setddir( &defdsc, NULL, NULL )) ) {
|
|
default_set = TRUE;
|
|
} else {
|
|
sts = printmsg( sts, 0 );
|
|
}
|
|
return sts;
|
|
}
|
|
|
|
/*********************************************************** mountdef() */
|
|
|
|
vmscond_t mountdef( const char *devnam ) {
|
|
char *colon, *buf;
|
|
size_t len;
|
|
|
|
if( default_set )
|
|
return SS$_NORMAL;
|
|
|
|
len = strlen( devnam );
|
|
buf = (char *) malloc( len + sizeof( ":[000000]" ) );
|
|
if( buf == NULL ) {
|
|
return printmsg( ODS2_OSERROR, 0, strerror( errno ) );
|
|
}
|
|
|
|
colon = strchr( devnam, ':' );
|
|
if( colon != NULL )
|
|
len = (size_t)(colon - devnam);
|
|
memcpy( buf, devnam, len );
|
|
memcpy( buf+len, ":[000000]", sizeof( ":[000000]" ) );
|
|
setdef( buf );
|
|
free( buf );
|
|
|
|
return SS$_NORMAL;
|
|
}
|
|
|
|
/************************************************************ savequals() */
|
|
|
|
static defqualsp_t savedquals = NULL;
|
|
|
|
static vmscond_t savequals( options_t defval, qual_t *qp,
|
|
int qualc, char **qualv,
|
|
defqualsp_t *saveloc ) {
|
|
vmscond_t sts;
|
|
int i;
|
|
size_t len;
|
|
defqualsp_t newq, *old;
|
|
char *dp;
|
|
|
|
len = ( offsetof( defquals_t, data ) +
|
|
( sizeof( char** ) * ((size_t)qualc +1) ) );
|
|
|
|
for( i = 0; i < qualc; i++ )
|
|
len += strlen( qualv[i] ) + 1;
|
|
|
|
if( (newq = (defqualsp_t) malloc( len )) == NULL )
|
|
return SS$_INSFMEM;
|
|
|
|
newq->qualc = qualc;
|
|
newq->qualv = newq->data;
|
|
|
|
dp = (char *)(newq->data + qualc + 1);
|
|
|
|
for( i = 0; i < qualc; i++ ) {
|
|
newq->qualv[i] = dp;
|
|
len = strlen( qualv[i] ) +1;
|
|
memcpy( dp, qualv[i], len );
|
|
dp += len;
|
|
}
|
|
newq->qualv[i] = NULL;
|
|
|
|
if( $FAILS(sts = checkquals( &defval, defval, qp, qualc, qualv )) ) {
|
|
free( newq );
|
|
return sts;
|
|
}
|
|
|
|
for( old = &savedquals; *old != NULL; old = &(*old)->next ) {
|
|
defqualsp_t t;
|
|
|
|
if( (t = *old) == *saveloc ) {
|
|
*old = t->next;
|
|
free( t );
|
|
break;
|
|
}
|
|
}
|
|
|
|
newq->next = savedquals;
|
|
|
|
if( savedquals == NULL )
|
|
atexit( set_exit );
|
|
|
|
*saveloc =
|
|
savedquals = newq;
|
|
|
|
return SS$_NORMAL;
|
|
}
|
|
|
|
/************************************************************ set_exit() */
|
|
static void set_exit( void ) {
|
|
defqualsp_t sq;
|
|
|
|
while( (sq = savedquals) != NULL ) {
|
|
savedquals = sq->next;
|
|
free( sq );
|
|
}
|
|
|
|
return;
|
|
}
|
|
|