blob: a7a2fa399e4347a0a898cef8965bcb1d2b8433c0 [file] [log] [blame]
/** \file consoleui.hpp .
-----------------------------------------------------------------------------
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
-----------------------------------------------------------------------------
\brief A Console User Interface class
-------------------------------------------------------------------------- */
#ifndef __UIMA_CONSOLEUI_HPP
#define __UIMA_CONSOLEUI_HPP
/* ----------------------------------------------------------------------- */
/* Interface dependencies */
/* ----------------------------------------------------------------------- */
#include "uima/types.h" // Has UIMA_LINK_IMPORTSPEC macro
#include <iostream>
#include "apr_pools.h"
#include "apr_getopt.h"
#include "uima/filename.hpp"
/* ----------------------------------------------------------------------- */
/* Implementation dependencies */
/* ----------------------------------------------------------------------- */
namespace uima {
namespace util {
typedef struct found_opt_t {
int index; // Index of arg in array of possible options (1-based)
const char * value; // Value of arg or NULL
}
found_opt_t;
}
}
/* ----------------------------------------------------------------------- */
/* Constants */
/* ----------------------------------------------------------------------- */
#define BEEP '\a' /* beep character */
/* Filler betwen formatted field and value .. always print last two characters
field...............................: value
*/
static const char * gs_cpszFiller = "....................................: ";
static int gi_maxlen = strlen(gs_cpszFiller) - 2;
static const char * gs_cpszLine = "--------------------------------------------------------------------------\n";
static const char * gs_progressChars[4] = { "\r | ",
"\r / ",
"\r - ",
"\r \\ "
};
/* ----------------------------------------------------------------------- */
/* Types / Classes */
/* ----------------------------------------------------------------------- */
namespace uima {
namespace util {
/**
* The class <tt> util::ConsoleUI</tt> displays msgs on the "console"
* \code
???
\endcode
*/
class UIMA_LINK_IMPORTSPEC ConsoleUI {
public:
/** @name Constructors */
/*@{*/
/** Instantiate a console user interface object.
<tt> argc</tt> and <tt> argv</tt> must be passed to the <tt> ConsoleUI</tt> object. */
ConsoleUI(int argc, char * argv[],
const char * cpszTitle = 0, const char * cpszCopyright = 0);
/** destructor */
~ConsoleUI(void);
/*@}*/
void setQuietMode(bool bQuiet) {
iv_bQuiet = bQuiet;
}
ostream & getOutputStream(void) const {
return cout;
}
/** display a field and a value with padding so value starts at col 40
First column is <tt> field</tt>, second column is <tt> value</tt> */
void format(const char * cpszField, const char * cpszValue) const;
void format(const char * cpszField, long lValue) const;
void format(const char * cpszField, unsigned long ulValue) const;
void formatBool(const char * cpszField, bool bValue) const;
void format(const char * cpszField, bool bValue) const {
formatBool(cpszField, bValue);
}
void format(const char * cpszField, int iValue) const {
format(cpszField, (long)iValue);
}
// void format(const char * cpszField, size_t szValue) const
// { format(cpszField, (unsigned long)szValue); }
/** display a header */
void formatHeader(const char * cpszMsg) const;
/** display a header */
void header(const char * cpszMsg) const;
/** display a line of dashes */
void horizontalBar(void) const;
/** display a new-line */
void newline(void) const;
/** display an informational msg */
void info(const char * cpszMsg) const;
/** display a warning msg on stderr */
void warning(const char * cpszMsg1, const char * cpszMsg2 = NULL) const;
/** display an error msg on stderr */
void error(const char * cpszMsg) const;
/** display an error msg on stderr and exit */
void fatal(int iErrcode, const char * cpszMsg1, const char * cpszMsg2 = NULL) const;
/*@}*/
/** @name Usage and Help methods */
/** process usage msg and check command-line arguments */
void handleUsageHelp(const char * cpszUsage, const char * cpszHelp,
const char * cpszHelpFlags = NULL);
/** display usage or help and then exit! */
void displayUsage(void) const;
void displayHelp(void) const;
/*@}*/
/** @name Process optional arguments */
bool hasArgString(const char * cpszArgument, const char *& cpszrValue) const;
bool hasArgNumval(const char * cpszArgument, long & rlValue) const;
bool hasArgSwitch(const char * cpszArgument) const;
/*@}*/
/** @name Process positional arguments */
/** set cursor to the first command line argument and return TRUE if there is one */
bool setToFirst(void);
/** set cursor to the next command line argument and return TRUE if there is one */
bool setToNext(void);
/** return TRUE if the current command line argument is valid */
bool isValid(void) const;
/** return current command line argument as C string pointer */
operator const char* (void) const {
return(getAsCString());
}
/** return current command line argument as C string pointer */
const char * getAsCString(void) const;
/*@}*/
/** @name Display progress indication */
void progressStart(void) {
iv_uiProgressInd = 0;
}
void progressStep(void);
void progressStop(void) const;
/*@}*/
protected:
/* --- functions --- */
void format(const char * cpszMag) const;
bool hasOption(const char * cpszArgument, const char *& cpszrValue) const;
void debugDisplayOptions(int numOpts);
private:
apr_pool_t * consPool;
int iv_argc;
const char ** iv_argv;
const char * iv_cpszHelp;
const char * iv_cpszUsage[2];
char * iv_szProcessName;
bool iv_bQuiet;
apr_getopt_option_t * iv_pOpts; // Array of possible options
int iv_maxOptIndex;
apr_getopt_t * iv_hGetopt; // Handle for apr_getopt...
found_opt_t * iv_pFoundOpts;
int iv_nFoundOpts;
int iv_currentArg;
int iv_uiProgressInd;
}
; /* ConsoleUI */
/* ----------------------------------------------------------------------- */
/* Implementation */
/* ----------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
inline void ConsoleUI::formatHeader(const char * cpszMsg) const {
if (iv_bQuiet) return;
cout << endl << " " << cpszMsg << "\n " << gs_cpszLine+2;
}
/* ----------------------------------------------------------------------- */
inline void ConsoleUI::header(const char * cpszMsg) const {
if (iv_bQuiet) return;
cout << endl << " " << gs_cpszLine+2 << iv_szProcessName << ": " << cpszMsg << endl;
}
/* ----------------------------------------------------------------------- */
inline void ConsoleUI::format(const char * cpszMsg) const {
if (iv_bQuiet) return;
int len = strlen(cpszMsg);
if ( len > gi_maxlen ) len = gi_maxlen;
cout << " " << cpszMsg << gs_cpszFiller+len; // Pad out to col 40
}
/* ----------------------------------------------------------------------- */
inline void ConsoleUI::format(const char * cpszField, const char * cpszValue) const {
if (iv_bQuiet) return;
format(cpszField);
cout << cpszValue << endl;
}
/* ----------------------------------------------------------------------- */
inline void ConsoleUI::format(const char * cpszField, long lValue) const {
if (iv_bQuiet) return;
format(cpszField);
cout << lValue << endl;
}
/* ----------------------------------------------------------------------- */
inline void ConsoleUI::format(const char * cpszField, unsigned long ulValue) const {
if (iv_bQuiet) return;
format(cpszField);
cout << ulValue << endl;
}
/* ----------------------------------------------------------------------- */
inline void ConsoleUI::formatBool(const char * cpszField, bool bValue) const {
if (iv_bQuiet) return;
format(cpszField);
cout << (bValue ? "YES" : "NO") << endl;
}
/* ----------------------------------------------------------------------- */
inline void ConsoleUI::horizontalBar(void) const {
if (iv_bQuiet) return;
cout << gs_cpszLine << endl;
}
/* ----------------------------------------------------------------------- */
inline void ConsoleUI::newline(void) const {
if (iv_bQuiet) return;
cout << endl;
}
/* ----------------------------------------------------------------------- */
inline void ConsoleUI::displayUsage(void) const {
cout << endl << "Usage: " << iv_szProcessName << endl
<< iv_cpszUsage[0] << iv_cpszUsage[1] << BEEP;
::exit(1);
}
/* ----------------------------------------------------------------------- */
inline void ConsoleUI::displayHelp(void) const {
cout << endl << "Help: " << iv_cpszHelp;
::exit(1);
}
/* ----------------------------------------------------------------------- */
inline void ConsoleUI::info(const char * cpszMsg) const {
if (iv_bQuiet) return;
cout << endl << gs_cpszLine << iv_szProcessName << ": " << cpszMsg << endl;
}
/* ----------------------------------------------------------------------- */
inline void ConsoleUI::warning(const char * cpszMsg1, const char * cpszMsg2) const {
cerr << "WARNING: " << cpszMsg1;
if ( cpszMsg2 != NULL )
cerr << cpszMsg2;
cerr << endl;
}
/* ----------------------------------------------------------------------- */
inline void ConsoleUI::error(const char * cpszMsg) const {
cerr << "ERROR: " << cpszMsg << endl;
}
/* ----------------------------------------------------------------------- */
inline void ConsoleUI::fatal(int iErrcode, const char * cpszMsg1 , const char * cpszMsg2) const {
cerr << "FATAL ERROR: " << iErrcode << " " << cpszMsg1;
if ( cpszMsg2 != NULL )
cerr << cpszMsg2;
cerr << endl;
::exit((int) iErrcode);
}
/* ----------------------------------------------------------------------- */
inline bool ConsoleUI::hasArgString(const char * cpszArgument, const char *& cpszrValue) const {
// Check if have this option and it does have a value
return hasOption( cpszArgument,cpszrValue ) && (cpszrValue != NULL);
}
/* ----------------------------------------------------------------------- */
inline bool ConsoleUI::hasArgNumval(const char * cpszArgument, long & rlValue) const {
// Check if have this option and that it has a value
const char* value;
if ( !hasOption( cpszArgument,value ) || (value == NULL) )
return false;
if (*value == '\'')
++value;
if ( isdigit(*value) || (*value == '-') ) {
rlValue = atol(value);
return true;
}
// Type mismatch .. should display warning?
return false;
}
/* ----------------------------------------------------------------------- */
inline bool ConsoleUI::hasArgSwitch(const char * cpszArgument) const {
// Check if have this option and that it doesn't have a value
const char* value;
return hasOption( cpszArgument,value ) && (value == NULL);
}
/* ----------------------------------------------------------------------- */
inline bool ConsoleUI::setToFirst(void) {
iv_currentArg = iv_hGetopt->skip_start;
return iv_currentArg < iv_hGetopt->skip_end;
}
/* ----------------------------------------------------------------------- */
inline bool ConsoleUI::setToNext(void) {
return ++iv_currentArg < iv_hGetopt->skip_end;
}
/* ----------------------------------------------------------------------- */
inline bool ConsoleUI::isValid(void) const {
return iv_currentArg < iv_hGetopt->skip_end;
}
/* ----------------------------------------------------------------------- */
inline const char * ConsoleUI::getAsCString(void) const {
if (iv_currentArg < iv_hGetopt->skip_end)
return iv_hGetopt->argv[iv_currentArg];
else
return NULL;
}
/* ----------------------------------------------------------------------- */
inline void ConsoleUI::progressStep(void) {
if (iv_bQuiet) return;
cout << gs_progressChars[iv_uiProgressInd++ % 4];
}
/* ----------------------------------------------------------------------- */
inline void ConsoleUI::progressStop(void) const {
if (iv_bQuiet) return;
cout << "\r \r";
}
} // namespace util
} // namespace uima
#endif /* __UIMA_CONSOLEUI_HPP */
/* <EOF> */