#include <stdexcept>
#include <sstream>
#include <stdarg.h>
#include "UserInterface.h"
#include "StkStream.h"
#include "Features.h"
namespace TNet
{
//***************************************************************************
//***************************************************************************
int
npercents(const char *str)
{
int ret = 0;
while (*str) if (*str++ == '%') ret++;
return ret;
}
//***************************************************************************
//***************************************************************************
void
UserInterface::
ReadConfig(const char *file_name)
{
std::string line_buf;
std::string::iterator chptr;
std::string key;
std::string value;
std::ostringstream ss;
int line_no = 0;
IStkStream i_stream;
i_stream.open(file_name, std::ios::binary);
if (!i_stream.good()) {
throw std::runtime_error(std::string("Cannot open input config file ")
+ file_name);
}
i_stream >> std::ws;
while (!i_stream.eof()) {
size_t i_pos;
// read line
std::getline(i_stream, line_buf);
i_stream >> std::ws;
if (i_stream.fail()) {
throw std::runtime_error(std::string("Error reading (")
+ file_name + ":" + (ss << line_no,ss).str() + ")");
}
// increase line counter
line_no++;
// cut comments
if (std::string::npos != (i_pos = line_buf.find('#'))) {
line_buf.erase(i_pos);
}
// cut leading and trailing spaces
Trim(line_buf);
// if empty line, then skip it
if (0 == line_buf.length()) {
continue;
}
// line = line_buf.c_str();
// chptr = parptr;
chptr = line_buf.begin();
for (;;) {
// Replace speces by '_', which is removed in InsertConfigParam
while (isalnum(*chptr) || *chptr == '_' || *chptr == '-') {
chptr++;
}
while (std::isspace(*chptr)) {
*chptr = '_';
chptr++;
}
if (*chptr != ':') {
break;
}
chptr++;
while (std::isspace(*chptr)) {
*chptr = '_';
chptr++;
}
}
if (*chptr != '=') {
throw std::runtime_error(std::string("Character '=' expected (")
+ file_name + ":" + (ss.str(""),ss<<line_no,ss).str() + ")");
}
key.assign(line_buf.begin(), chptr);
chptr++;
value.assign(chptr, line_buf.end());
ParseHTKString(value, value);
InsertConfigParam(key.c_str(), value.c_str(), 'C');
}
i_stream.close();
}
//***************************************************************************
//***************************************************************************
void
UserInterface::
InsertConfigParam(const char *pParamName, const char *value, int optionChar)
{
std::string key(pParamName);
std::string::iterator i_key = key.begin();
while (i_key != key.end()) {
if (*i_key == '-' || *i_key == '_') {
i_key = key.erase(i_key);
}
else {
*i_key = toupper(*i_key);
i_key ++;
}
}
mMap[key].mValue = value;
mMap[key].mRead = false;
mMap[key].mOption = optionChar;
}
//***************************************************************************
//***************************************************************************
int
UserInterface::
ParseOptions(
int argc,
char* argv[],
const char* pOptionMapping,
const char* pToolName)
{
int i;
int opt = '?';
int optind;
bool option_must_follow = false;
char param[1024];
char* value;
const char* optfmt;
const char* optarg;
char* chptr;
char* bptr;
char tstr[4] = " -?";
unsigned long long option_mask = 0;
std::ostringstream ss;
#define MARK_OPTION(ch) {if (isalpha(ch)) option_mask |= 1ULL << ((ch) - 'A');}
#define OPTION_MARK(ch) (isalpha(ch) && ((1ULL << ((ch) - 'A')) & option_mask))
#define IS_OPTION(str) ((str)[0] == '-' && (isalpha((str)[1]) || (str)[1] == '-'))
//search for the -A param
for (optind = 1; optind < argc; optind++) {
// we found "--", no -A
if (!strcmp(argv[optind], "--")) {
break;
}
//repeat till we find -A
if (argv[optind][0] != '-' || argv[optind][1] != 'A') {
continue;
}
// just "-A" form
if (argv[optind][2] != '\0') {
throw std::runtime_error(std::string("Unexpected argument '")
+ (argv[optind] + 2) + "' after option '-A'");
}
for (i=0; i < argc; i++) {
// display all params
if(strchr(argv[i], ' ') || strchr(argv[i], '*'))
std::cout << '\'' << argv[i] << '\'' << " ";
else std::cout << argv[i] << " ";
}
std::cout << std::endl;
break;
}
for (optind = 1; optind < argc; optind++) {
// find the '-C?' parameter (possible two configs)
if (!strcmp(argv[optind], "--")) break;
if (argv[optind][0] != '-' || argv[optind][1] != 'C')