This is unix.c in view mode; [Download] [Up]
//------------------------------------------------------------------------
// ^FILE: unix.c - implement the unix-specific portions of CmdLine
//
// ^DESCRIPTION:
// This file implements the public and private CmdLine library functions
// that are specific to the native command-line syntax of Unix.
//
// The following functions are implemented:
//
// CmdLine::parse_option() -- parse an option
// CmdLine::parse_keyword() -- parse a keyword
// CmdLine::parse_value() -- parse a value
// CmdLine::parse_arg() -- parse a single argument
// CmdLine::arg_error() -- format an argument for error messages
// CmdLine::fmt_arg() -- format an argument for usage messages
//
// ^HISTORY:
// 01/09/92 Brad Appleton <brad@ssd.csd.harris.com> Created
//
// 03/01/93 Brad Appleton <brad@ssd.csd.harris.com>
// - Added ALLOW_PLUS to list of CmdLine configuration flags
//-^^---------------------------------------------------------------------
#include <iostream.h>
#include <strstream.h>
#include <stdlib.h>
#include <string.h>
#include "exits.h"
#include "cmdline.h"
#include "states.h"
//
// Some Helper function for getting and recognizing prefixes
//
// Function to tell us if an argument looks like an option
inline static int
isOPTION(const char * s) {
return ((*(s) == '-') && ((*((s)+1) != '-')) && ((*((s)+1) != '\0'))) ;
}
// Function to return the option-prefix
inline static const char *
OptionPrefix(void) { return "-" ; }
// Function to tell us if an argument looks like a long-option.
//
// NOTE: allowing "+" does not preclude the use of "--"
//
inline static int
isKEYWORD(const char *s, int allow_plus) {
return (((*(s) == '-') && (*((s)+1) == '-') && (*((s)+2) != '\0')) ||
(allow_plus && (*(s) == '+') && ((*((s)+1) != '\0')))) ;
}
// Function to return the long-option prefix
inline static const char *
KeywordPrefix(int allow_plus) { return (allow_plus) ? "+" : "--" ; }
// Need to know when an argument means "end-of-options"
inline static int
isENDOPTIONS(const char *s) {
return ((*(s) == '-') && (*((s)+1) == '-') && (*((s)+2) == '\0')) ;
}
// Function to return the "end-of-options" string
inline static const char *
EndOptions(void) { return "--" ; }
//-------
// ^FUNCTION: CmdLine::parse_option - parse a Unix option
//
// ^SYNOPSIS:
// unsigned CmdLine::parse_option(arg);
//
// ^PARAMETERS:
// const char * arg;
// -- the command-line argument containing the prospective option
//
// ^DESCRIPTION:
// This routine will attempt to "handle" all options specified in
// the string "arg". For each option found, its compile-function
// is called and the corresponding state of both the command
// and of the matched option(s) is (are) updated.
//
// ^REQUIREMENTS:
// "arg" should point past any leading option prefix (such as "-").
//
// ^SIDE-EFFECTS:
// "cmd" is modified accordingly as each option is parsed (as are its
// constituent arguments). If there are syntax errors then error messages
// are printed if QUIET is NOT set.
//
// ^RETURN-VALUE:
// NO_ERROR is returned if no errors were encountered. Otherwise the
// return value is a combination of bitmasks of type CmdLine::CmdStatus
// (defined in <cmdline.h>) indicating all the problems that occurred.
//
// ^ALGORITHM:
// see if we left an option dangling without parsing its value.
// for each option bundled in "arg"
// try to match the option
// if no match issue a message (unless QUIET is set)
// else
// if the option takes NO argument than handle that
// else if the option takes an argument
// if the rest or arg is not empty then
// call the option's compile-function using the rest of
// arg as the value.
// skip past whatever portion of value was used
// else
// update the state of the command to show that we are expecting
// to see the value for this option as the next argument.
// endif
// endif
// update the state of the argument.
// endif
// endfor
//-^^----
unsigned
CmdLine::parse_option(const char * arg)
{
const char * save_arg = arg;
unsigned save_flags = 0, rc = 0 ;
CmdArg * cmdarg = NULL;
int bad_val;
// see if we left an argument dangling without a value
ck_need_val() ;
do { // loop over bundled options
cmdarg = opt_match(*arg);
if (cmdarg == NULL) {
// If we were in the middle of a guess - sorry no cigar, otherwise
// guess that maybe this is a keyword and not an keyword.
//
if (cmd_state & cmd_GUESSING) {
if (arg == save_arg) return BAD_OPTION;
} else {
if (! (cmd_flags & NO_GUESSING)) {
cmd_state |= cmd_GUESSING;
rc = parse_keyword(arg);
cmd_state &= ~cmd_GUESSING;
if (rc != BAD_KEYWORD) return rc;
}
}
if (! (cmd_flags & QUIET)) {
error() << "unknown option \"" << OptionPrefix() << char(*arg)
<< "\"." << endl ;
}
rc |= BAD_OPTION ;
++arg ; // skip bad option
continue ;
}
++arg ; // skip past option character
save_flags = cmdarg->flags() ;
cmdarg->clear();
cmdarg->set(CmdArg::OPTION) ;
if ((! *arg) && (cmdarg->syntax() & CmdArg::isVALTAKEN)) {
// End of string -- value must be in next arg
// Save this cmdarg-pointer for later and set the parse_state to
// indicate that we are expecting a value.
//
if (cmdarg->syntax() & CmdArg::isVALSTICKY) {
// If this argument is sticky we already missed our chance
// at seeing a value.
//
if (cmdarg->syntax() & CmdArg::isVALREQ) {
if (! (cmd_flags & QUIET)) {
error() << "value required in same argument for "
<< OptionPrefix() << char(cmdarg->char_name())
<< " option." << endl;
}
rc |= (VAL_MISSING | VAL_NOTSTICKY) ;
cmdarg->flags(save_flags);
} else {
// The value is optional - set the GIVEN flag and call
// handle_arg with NULL (and check the result).
//
const char * null_str = NULL;
cmdarg->set(CmdArg::GIVEN) ;
cmd_parse_state = cmd_START_STATE ;
bad_val = handle_arg(cmdarg, null_str);
if (bad_val) {
if (! (cmd_flags & QUIET)) {
arg_error("bad value for", cmdarg) << "." << endl ;
}
rc |= BAD_VALUE ;
cmdarg->flags(save_flags);
}
}
} else {
// Wait for the value to show up next time around
cmdarg->set(CmdArg::GIVEN) ;
cmd_matched_arg = cmdarg ;
cmd_parse_state = cmd_WANT_VAL ;
if (cmdarg->syntax() & CmdArg::isVALREQ) {
cmd_parse_state += cmd_TOK_REQUIRED ;
}
}
return rc ;
}
// If this option is an isVALSEP and "arg" is not-empty then we
// have an error.
//
if ((cmdarg->syntax() & CmdArg::isVALTAKEN) &&
(cmdarg->syntax() & CmdArg::isVALSEP)) {
if (! (cmd_flags & QUIET)) {
error() << "value required in separate argument for "
<< OptionPrefix() << char(cmdarg->char_name())
<< " option." << endl;
}
rc |= (VAL_MISSING | VAL_NOTSEP) ;
cmdarg->flags(save_flags);
return rc;
} else {
// handle the option
const char * save_arg = arg;
bad_val = handle_arg(cmdarg, arg);
if (bad_val) {
if (! (cmd_flags & QUIET)) {
arg_error("bad value for", cmdarg) << "." << endl ;
}
rc |= BAD_VALUE ;
cmdarg->flags(save_flags);
}
cmdarg->set(CmdArg::GIVEN);
if (arg != save_arg) cmdarg->set(CmdArg::VALGIVEN);
}
} while (arg && *arg) ;
return rc ;
}
//-------
// ^FUNCTION: CmdLine::parse_keyword - parse a Unix keyword
//
// ^SYNOPSIS:
// unsigned CmdLine::parse_keyword(arg);
//
// ^PARAMETERS:
// const char * arg;
// -- the command-line argument containing the prospective keyword
//
// ^DESCRIPTION:
// This routine will attempt to "handle" the keyword specified in
// the string "arg". For any keyword found, its compile-function
// is called and the corresponding state of both the command
// and of the matched keyword(s) is (are) updated.
//
// ^REQUIREMENTS:
// "arg" should point past any leading keyword prefix (such as "--").
//
// ^SIDE-EFFECTS:
// "cmd" is modified accordingly as the keyword is parsed (as are its
// constituent arguments). If there are syntax errors then error messages
// are printed if QUIET is NOT set.
//
// ^RETURN-VALUE:
// NO_ERROR is returned if no errors were encountered. Otherwise the
// return value is a combination of bitmasks of type CmdLine::CmdStatus
// (defined in <cmdline.h>) indicating all the problems that occurred.
//
// ^ALGORITHM:
// see if we left an option dangling without parsing its value.
// look for a possible value for this keyword denoted by ':' or '='
// try to match "arg" as a keyword
// if no match issue a message (unless QUIET is set)
// else
// if the keyword takes NO argument than handle that
// else if the keyword takes an argument
// if a value was found "arg"
// call the keyword's compile-function with the value found.
// else
// update the state of the command to show that we are expecting
// to see the value for this option as the next argument.
// endif
// endif
// update the state of the argument.
// endif
//-^^----
unsigned
CmdLine::parse_keyword(const char * arg)
{
unsigned save_flags = 0, rc = 0 ;
CmdArg * cmdarg = NULL ;
int ambiguous = 0, len = -1, bad_val;
const char * val = NULL ;
int plus = (cmd_flags & ALLOW_PLUS) ; // Can we use "+"?
// see if we left an argument dangling without a value
ck_need_val() ;
// If there is a value with this argument, get it now!
val = ::strpbrk(arg, ":=") ;
if (val) {
len = val - arg ;
++val ;
}
cmdarg = kwd_match(arg, len, ambiguous);
if (cmdarg == NULL) {
// If we were in the middle of a guess - sorry no cigar, otherwise
// guess that maybe this is an option and not a keyword.
//
if (cmd_state & cmd_GUESSING) {
return BAD_KEYWORD;
} else if ((! ambiguous) || (len == 1)) {
if (! (cmd_flags & NO_GUESSING)) {
cmd_state |= cmd_GUESSING;
rc = parse_option(arg);
cmd_state &= ~cmd_GUESSING;
if (rc != BAD_OPTION) return rc;
}
}
if (! (cmd_flags & QUIET)) {
error() << ((ambiguous) ? "ambiguous" : "unknown") << " option "
<< "\"" << ((cmd_flags & KWDS_ONLY) ? OptionPrefix()
: KeywordPrefix(plus))
<< arg << "\"." << endl ;
}
rc |= ((ambiguous) ? KWD_AMBIGUOUS : BAD_KEYWORD) ;
return rc ;
}
save_flags = cmdarg->flags() ;
cmdarg->clear();
cmdarg->set(CmdArg::KEYWORD) ;
if ((cmdarg->syntax() & CmdArg::isVALTAKEN) && (val == NULL)) {
// Value must be in the next argument.
// Save this cmdarg for later and indicate that we are
// expecting a value.
//
if (cmdarg->syntax() & CmdArg::isVALSTICKY) {
// If this argument is sticky we already missed our chance
// at seeing a value.
//
if (cmdarg->syntax() & CmdArg::isVALREQ) {
if (! (cmd_flags & QUIET)) {
error() << "value required in same argument for "
<< ((cmd_flags & KWDS_ONLY) ? OptionPrefix()
: KeywordPrefix(plus))
<< cmdarg->keyword_name() << " option." << endl;
}
rc |= (VAL_MISSING | VAL_NOTSTICKY) ;
cmdarg->flags(save_flags);
} else {
// The value is optional - set the GIVEN flag and call
// handle_arg with NULL (and check the result).
//
const char * null_str = NULL;
cmdarg->set(CmdArg::GIVEN) ;
cmd_parse_state = cmd_START_STATE ;
bad_val = handle_arg(cmdarg, null_str);
if (bad_val) {
if (! (cmd_flags & QUIET)) {
arg_error("bad value for", cmdarg) << "." << endl ;
}
rc |= BAD_VALUE ;
cmdarg->flags(save_flags);
}
}
} else {
// Wait for the value to show up next time around
cmdarg->set(CmdArg::GIVEN) ;
cmd_matched_arg = cmdarg ;
cmd_parse_state = cmd_WANT_VAL ;
if (cmdarg->syntax() & CmdArg::isVALREQ) {
cmd_parse_state += cmd_TOK_REQUIRED ;
}
}
return rc ;
}
// If this option is an isVALSEP and "val" is not-NULL then we
// have an error.
//
if (val && (cmdarg->syntax() & CmdArg::isVALTAKEN) &&
(cmdarg->syntax() & CmdArg::isVALSEP)) {
if (! (cmd_flags & QUIET)) {
error() << "value required in separate argument for "
<< ((cmd_flags & KWDS_ONLY) ? OptionPrefix()
: KeywordPrefix(plus))
<< cmdarg->keyword_name() << " option." << endl;
}
rc |= (VAL_MISSING | VAL_NOTSEP) ;
cmdarg->flags(save_flags);
return rc;
}
// handle the keyword
bad_val = handle_arg(cmdarg, val);
if (bad_val) {
if (! (cmd_flags & QUIET)) {
arg_error("bad value for", cmdarg) << "." << endl ;
}
rc |= BAD_VALUE ;
cmdarg->flags(save_flags);
}
return rc ;
}
//-------
// ^FUNCTION: CmdLine::parse_value - parse a Unix value
//
// ^SYNOPSIS:
// unsigned CmdLine::parse_value(arg);
//
// ^PARAMETERS:
// const char * arg;
// -- the command-line argument containing the prospective value
//
// ^DESCRIPTION:
// This routine will attempt to "handle" the value specified in
// the string "arg". The compile-function of the corresponding
// argument-value is called and the corresponding state of both
// the command and of the matched option(s) is (are) updated.
// If the value corresponds to a multi-valued argument, then that
// is handled here.
//
// ^REQUIREMENTS:
//
// ^SIDE-EFFECTS:
// "cmd" is modified accordingly for the value that is parsed (as are its
// constituent arguments). If there are syntax errors then error messages
// are printed if QUIET is NOT set.
//
// ^RETURN-VALUE:
// NO_ERROR is returned if no errors were encountered. Otherwise the
// return value is a combination of bitmasks of type CmdLine::CmdStatus
// (defined in <cmdline.h>) indicating all the problems that occurred.
//
// ^ALGORITHM:
// If the command-state says we are waiting for the value of an option
// find the option that we matched last
// else
// match the next positional parameter in "cmd"
// if there isnt one issue a "too many args" message
// (unless cmd_QUIETs is set) and return.
// endif
// handle the given value and update the argument and command states.
//-^^----
unsigned
CmdLine::parse_value(const char * arg)
{
unsigned save_flags = 0, rc = 0 ;
int bad_val;
CmdArg * cmdarg = NULL;
if (cmd_parse_state & cmd_WANT_VAL) {
if (cmd_matched_arg == NULL) {
cerr << "*** Internal error in class CmdLine.\n"
<< "\tparse-state is inconsistent with last-matched-arg."
<< endl ;
::exit(e_INTERNAL);
}
// get back the cmdarg that we saved for later
// - here is the value it was expecting
//
cmdarg = cmd_matched_arg ;
save_flags = cmdarg->flags() ;
} else {
// argument is positional - find out which one it is
cmdarg = pos_match() ;
if (cmdarg == NULL) {
if (! (cmd_flags & QUIET)) {
error() << "too many arguments given." << endl ;
}
rc |= TOO_MANY_ARGS ;
return rc ;
}
save_flags = cmdarg->flags() ;
cmdarg->clear();
cmdarg->set(CmdArg::POSITIONAL) ;
if (cmd_flags & OPTS_FIRST) {
cmd_state |= cmd_END_OF_OPTIONS ;
}
}
// handle this value
cmdarg->set(CmdArg::VALSEP) ;
bad_val = handle_arg(cmdarg, arg);
if (bad_val) {
if (! (cmd_flags & QUIET)) {
arg_error("bad value for", cmdarg) << "." << endl ;
}
rc |= BAD_VALUE ;
cmdarg->flags(save_flags);
if (! (cmdarg->syntax() & CmdArg::isLIST)) {
cmd_parse_state = cmd_START_STATE;
}
}
// If the value was okay and we were requiring a value, then
// a value is no longer required.
//
if ((! bad_val) && (cmdarg->syntax() & CmdArg::isLIST)) {
cmd_parse_state &= ~cmd_TOK_REQUIRED ;
}
return rc ;
}
//-------
// ^FUNCTION: CmdLine::parse_arg - parse an argv[] element unix-style
//
// ^SYNOPSIS:
// unsigned CmdLine::parse_arg(arg)
//
// ^PARAMETERS:
// const char * arg;
// -- an argument string (argv[] element) from the command-line
//
// ^DESCRIPTION:
// This routine will determine whether "arg" is an option, a long-option,
// or a value and call the appropriate parse_xxxx function defined above.
//
// ^REQUIREMENTS:
//
// ^SIDE-EFFECTS:
// "cmd" is modified accordingly for the string that is parsed (as are its
// constituent arguments). If there are syntax errors then error messages
// are printed if QUIET is NOT set.
//
// ^RETURN-VALUE:
// NO_ERROR is returned if no errors were encountered. Otherwise the
// return value is a combination of bitmasks of type CmdLine::CmdStatus
// (defined in <cmdline.h>) indicating all the problems that occurred.
//
// ^ALGORITHM:
// if we are expecting a required value
// call parse_value()
// else if "arg" is an option
// skip past the option prefix
// call parse_option()
// else if "arg" is a keyword
// skip past the kewyord prefix
// call parse_keyword()
// else if "arg" is "--" (meaning end of options)
// see that we didnt leave an option dangling without a value
// indicate end-of-options in the command-state
// else
// call parse_value()
// endif
//-^^----
unsigned
CmdLine::parse_arg(const char * arg)
{
if (arg == NULL) return cmd_status ;
int plus = (cmd_flags & ALLOW_PLUS) ; // Can we use "+"?
if (cmd_parse_state & cmd_TOK_REQUIRED) {
// If a required value is expected, then this argument MUST be
// the value (even if it looks like an option
//
cmd_status |= parse_value(arg) ;
} else if (isOPTION(arg) && (! (cmd_state & cmd_END_OF_OPTIONS))) {
++arg ; // skip '-' option character
if (cmd_flags & KWDS_ONLY) {
cmd_state |= cmd_KEYWORDS_USED ;
cmd_status |= parse_keyword(arg) ;
} else {
cmd_state |= cmd_OPTIONS_USED ;
cmd_status |= parse_option(arg) ;
}
} else if ((! (cmd_flags & OPTS_ONLY))
&& isKEYWORD(arg, plus) && (! (cmd_state & cmd_END_OF_OPTIONS))) {
cmd_state |= cmd_KEYWORDS_USED ;
if (*arg == '+') {
++arg ; // skip over '+' keyword prefix
} else {
arg += 2 ; // skip over '--' keyword prefix
}
cmd_status |= parse_keyword(arg) ;
} else if (isENDOPTIONS(arg) && (! (cmd_state & cmd_END_OF_OPTIONS))) {
cmd_state |= cmd_END_OF_OPTIONS ;
// see if we left an argument dangling without a value
ck_need_val() ;
} else {
cmd_status |= parse_value(arg) ;
}
return cmd_status ;
}
//-------
// ^FUNCTION: CmdLine::arg_error - format an argument for error messages
//
// ^SYNOPSIS:
// ostream & arg_error(error_str, cmdarg);
//
// ^PARAMETERS:
// const char * error_str;
// -- the problem with the argument
//
// const CmdArg * cmdarg;
// -- the argument to be formatted
//
// ^DESCRIPTION:
// This function will write to "os" the argument corresponding to
// "cmdarg" as we would like it to appear in error messages that pertain
// to this argument.
//
// ^REQUIREMENTS:
// None.
//
// ^SIDE-EFFECTS:
// writes to "os"
//
// ^RETURN-VALUE:
// A reference to os.
//
// ^ALGORITHM:
// Pretty straightforward, just print to os the way we
// want the argument to appear in usage messages.
//-^^----
ostream &
CmdLine::arg_error(const char * error_str, const CmdArg * cmdarg) const
{
int plus = (cmd_flags & ALLOW_PLUS) ; // Can we use "+"?
ostream & os = error() << error_str << char(' ') ;
if (cmdarg->flags() & CmdArg::GIVEN) {
if (cmdarg->flags() & CmdArg::KEYWORD) {
os << ((cmd_flags & KWDS_ONLY) ? OptionPrefix()
: KeywordPrefix(plus))
<< cmdarg->keyword_name() << " option" ;
} else if (cmdarg->flags() & CmdArg::OPTION) {
os << OptionPrefix() << (char)cmdarg->char_name() << " option" ;
} else {
os << cmdarg->value_name() << " argument" ;
}
} else {
if (cmdarg->syntax() & CmdArg::isPOS) {
os << cmdarg->value_name() << " argument" ;
} else {
if (cmd_flags & KWDS_ONLY) {
os << OptionPrefix() << cmdarg->keyword_name() << " option" ;
} else {
os << OptionPrefix() << (char)cmdarg->char_name() << " option" ;
}
}
}
return os;
}
//-------
// ^FUNCTION: CmdLine::fmt_arg - format an argument for usage messages
//
// ^SYNOPSIS:
// unsigned CmdLine::fmt_arg(cmdarg, buf, bufsize, syntax, level);
//
// ^PARAMETERS:
// const CmdArg * cmdarg;
// -- the argument to be formatted
//
// char * buf;
// -- where to print the formatted result
//
// unsigned bufsize;
// -- number of bytes allocated for buf.
//
// CmdLine::CmdLineSyntax syntax;
// -- the syntax to use (option, long-option, or both).
//
// CmdLine::CmdUsageLevel;
// -- the usage-level corresponding to this portion of the
// usage message.
//
// ^DESCRIPTION:
// This function will write into "buf" the argument corresponding to
// "cmdarg" as we would like it to appear in usage messages.
//
// ^REQUIREMENTS:
// "buf" must be large enough to hold the result.
//
// ^SIDE-EFFECTS:
// writes to "buf"
//
// ^RETURN-VALUE:
// the length of the formatted result.
//
// ^ALGORITHM:
// Its kind of tedious so follow along.
//-^^----
unsigned
CmdLine::fmt_arg(const CmdArg * cmdarg,
char * buf,
unsigned bufsize,
CmdLine::CmdLineSyntax syntax,
CmdLine::CmdUsageLevel level) const
{
ostrstream oss(buf, bufsize);
*buf = '\0';
int plus = (cmd_flags & ALLOW_PLUS) ; // Can we use "+"?
char optchar = cmdarg->char_name();
const char * keyword = cmdarg->keyword_name();
// Need to adjust the syntax if optchar or keyword is empty
if ((! (cmdarg->syntax() & CmdArg::isPOS)) &&
((! optchar) || (keyword == NULL))) {
if (keyword == NULL) {
if ((cmd_flags & KWDS_ONLY) && (cmd_flags & NO_GUESSING)) {
return 0;
} else {
syntax = cmd_OPTS_ONLY;
}
}
if (! optchar) {
if ((cmd_flags & OPTS_ONLY) && (cmd_flags & NO_GUESSING)) {
return 0;
} else {
syntax = cmd_KWDS_ONLY;
}
}
}
// If the argument is optional - print the leading '['
if ((level == VERBOSE_USAGE) && (! (cmdarg->syntax() & CmdArg::isREQ))) {
oss << char('[') ;
}
// If we have a sticky-argument and usage is cmd_BOTH then it gets
// really hairy so we just treat this as a special case right here
// and now.
//
if ((syntax == cmd_BOTH) &&
(! (cmdarg->syntax() & CmdArg::isPOS)) &&
(cmdarg->syntax() & CmdArg::isVALTAKEN) &&
(cmdarg->syntax() & CmdArg::isVALSTICKY))
{
if (cmdarg->syntax() & CmdArg::isVALOPT) {
oss << OptionPrefix() << char(optchar) << char('[')
<< cmdarg->value_name() << "]|" << KeywordPrefix(plus)
<< keyword << "[=" << cmdarg->value_name() << char(']') ;
} else {
oss << OptionPrefix() << optchar << cmdarg->value_name()
<< char('|') << KeywordPrefix(plus) << keyword << char('=')
<< cmdarg->value_name() ;
}
if ((level == VERBOSE_USAGE) && (cmdarg->syntax() & CmdArg::isLIST)) {
oss << " ..." ;
}
if ((level == VERBOSE_USAGE) && (! (cmdarg->syntax() & CmdArg::isREQ))) {
oss << char(']') ;
}
oss << ends ;
return (oss.pcount() - 1);
}
if (! (cmdarg->syntax() & CmdArg::isPOS)) {
switch(syntax) {
case cmd_OPTS_ONLY :
oss << OptionPrefix() << char(optchar) ;
break ;
case cmd_KWDS_ONLY :
oss << ((cmd_flags & KWDS_ONLY) ? OptionPrefix()
: KeywordPrefix(plus)) << keyword ;
break ;
case cmd_BOTH :
oss << OptionPrefix() << char(optchar) << char('|')
<< KeywordPrefix(plus) << keyword ;
break ;
default :
cerr << "*** Internal error in class CmdLine.\n"
<< "\tunknown CmdLineSyntax value (" << int(syntax) << ")."
<< endl ;
::exit(e_INTERNAL);
} //switch
if (cmdarg->syntax() & CmdArg::isVALTAKEN) {
if (! (cmdarg->syntax() & CmdArg::isVALSTICKY)) {
oss << char(' ') ;
}
}
}
// If the argument takes a value then print the value
if (cmdarg->syntax() & CmdArg::isVALTAKEN) {
if ((! (cmdarg->syntax() & CmdArg::isPOS)) &&
(cmdarg->syntax() & CmdArg::isVALOPT))
{
oss << char('[') ;
}
if (cmdarg->syntax() & CmdArg::isVALSTICKY) {
if (syntax == cmd_KWDS_ONLY) oss << char('=') ;
}
oss << cmdarg->value_name() ;
if ((level == VERBOSE_USAGE) && (cmdarg->syntax() & CmdArg::isLIST)) {
oss << " ..." ;
}
if ((! (cmdarg->syntax() & CmdArg::isPOS)) &&
(cmdarg->syntax() & CmdArg::isVALOPT))
{
oss << char(']') ;
}
}
if ((level == VERBOSE_USAGE) && (! (cmdarg->syntax() & CmdArg::isREQ))) {
oss << char(']') ;
}
oss << ends ;
return (oss.pcount() - 1) ;
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.