Пример #1
0
/**
 * @brief Adds function to the control list.
 * @param f Name of the function to be added.
 * @throws ConfigurationException if function is not valid (if the string is not found in
 * Call::functionsMap)
 */
void InitialMsg::addControlFunction(std::string f) {
   if (Call::functionExists(f)){
      if (Call::isControlFunction(f))
         controlList.push_back(f);
      else
         throw ConfigurationException("Control list contains function that cannot be controlled");
   }
   else
      throw ConfigurationException("Invalid control list");
}
Пример #2
0
void
SchemaTypeTuple::checkRule(
	const SchemaValidator *		sv,
	const Configuration *		cfg,
	const char *				typeName,
	const StringVector &		typeArgs,
	const char *				rule) const throw(ConfigurationException)
{
    (void) cfg;
    
	StringBuffer				msg;
	int							i;
	int							len;
	const char *				elemType;
	SchemaType *				typeDef;

	//--------
	// Check there is at least one pair of type and name arguments.
	//--------
	len = typeArgs.length();
	if ((len == 0) || (len % 2 != 0)) {
		msg << "the '" << typeName << "' type requires pairs of type and "
			<< "name arguments in rule '" << rule << "'";
		throw ConfigurationException(msg.c_str());
	}

	//--------
	// Check that all the type arguments are valid types.
	//--------
	for (i = 0; i < len; i+=2) {
		elemType = typeArgs[i+0];
		typeDef = findType(sv, elemType);
		if (typeDef == 0) {
			msg << "unknown type '" << elemType << "' in rule '" << rule << "'";
			throw ConfigurationException(msg.c_str());
		}
		switch (typeDef->cfgType()) {
		case Configuration::CFG_STRING:
			break;
		case Configuration::CFG_LIST:
			msg << "you cannot embed a list type ('" << elemType
				<< "') inside a " << "tuple in rule '" << rule << "'";
			throw ConfigurationException(msg.c_str());
		case Configuration::CFG_SCOPE:
			msg << "you cannot embed a scope type ('" << elemType
				<< "') inside a " << "tuple in rule '" << rule << "'";
			throw ConfigurationException(msg.c_str());
		default:
			assert(0); // Bug!
		}
	}
}
Пример #3
0
LexBase::LexBase(
	Configuration::SourceType	sourceType,
	const char *				source,
	UidIdentifierProcessor *	uidIdentifierProcessor)
												throw(ConfigurationException)
{
	StringBuffer				msg;

	//--------
	// Initialize state for the multi-byte functions in the C library.
	//--------
	memset(&m_mbtowcState, 0, sizeof(mbstate_t));

	m_keywordInfoArray     = 0;
	m_keywordInfoArraySize = 0;
	m_funcInfoArray        = 0;
	m_funcInfoArraySize    = 0;

	m_uidIdentifierProcessor = uidIdentifierProcessor;
	m_amOwnerOfUidIdentifierProcessor = false;
	m_sourceType = sourceType;
	m_source = source;
	m_lineNum = 1;
	m_ptr = 0;
	m_atEOF = false;
	switch (sourceType) {
	case Configuration::INPUT_FILE:
		if (!m_file.open(source)) {
			msg << "cannot open " << source << ": " << strerror(errno);
			throw ConfigurationException(msg.c_str());
		}
		break;
	case Configuration::INPUT_STRING:
		m_ptr = m_source;
		break;
	case Configuration::INPUT_EXEC:
		if (!execCmd(source, m_execOutput)) {
			msg << "cannot parse 'exec#" << source << "': "
				<< m_execOutput.c_str();
			throw ConfigurationException(msg.c_str());
		}
		m_ptr = m_execOutput.c_str();
		break;
	default:
		assert(0); // Bug!
		break;
	}

	nextChar(); // initialize m_ch
}
Пример #4
0
T Configuration::GetValue(LPCTSTR Name)
{
  if (m_ConfigValues.Contains(Name))
    return Parse<T>(m_ConfigValues.Get(Name));

  throw ConfigurationException(String::Format("The configuration field '%s' doesn't have a value", Name));
}
Пример #5
0
void StateGenerator::addOperation(
	Float weight,
	const std::string &type,
	const Parameters &params
) {
	if(type == "change-phrase-translation")
		operations_.push_back(new ChangePhraseTranslationOperation(params));
	else if(type == "permute-phrases")
		operations_.push_back(new PermutePhrasesOperation(params));
	else if(type == "linearise-phrases")
		operations_.push_back(new LinearisePhrasesOperation(params));
	else if(type == "swap-phrases")
		operations_.push_back(new SwapPhrasesOperation(params));
	else if(type == "move-phrases")
		operations_.push_back(new MovePhrasesOperation(params));
	else if(type == "resegment")
		operations_.push_back(new ResegmentOperation(params));
	else {
		LOG(logger_, error, "Unknown operation: " << type);
		BOOST_THROW_EXCEPTION(ConfigurationException());
	}

	if(!cumulativeOperationDistribution_.empty())
		weight += cumulativeOperationDistribution_.back();
	cumulativeOperationDistribution_.push_back(weight);
}
Пример #6
0
void
SchemaTypeInt::checkRule(
	const SchemaValidator *		sv,
	const Configuration *		cfg,
	const char *				typeName,
	const StringVector &		typeArgs,
	const char *				rule) const throw(ConfigurationException)
{
	StringBuffer				msg;
	int							len;
	int							min;
	int							max;

	len = typeArgs.length();
	if (len == 0) {
		return;
	}
	if (len != 2) {
		msg << "the '" << typeName << "' type should take either no "
			<< "arguments or 2 arguments (denoting min and max values) "
			<< "in rule '" << rule << "'";
		throw ConfigurationException(msg.c_str());
	}
	try {
		min = cfg->stringToInt("", "", typeArgs[0]);
	} catch (const ConfigurationException & ex) {
		msg << "non-integer value for the first ('min') argument in rule '"
			<< rule << "'";
		throw ConfigurationException(msg.c_str());
	}
	try {
		max = cfg->stringToInt("", "", typeArgs[1]);
	} catch (const ConfigurationException & ex) {
		msg << "non-integer value for the second ('max') argument in rule '"
			<< rule << "'";
		throw ConfigurationException(msg.c_str());
	}
	if (min > max) {
		msg << "the first ('min') value is larger than the second ('max') "
			<< "argument " << "in rule '" << rule << "'";
		throw ConfigurationException(msg.c_str());
	}
}
Пример #7
0
void
LexBase::nextChar() throw(ConfigurationException)
{
	char				ch;
	int					status;
	wchar_t				wChar;

	m_ch.reset();
	status = -1;
	while (status == -1) {
		ch = nextByte();
		if (m_atEOF && !m_ch.isEmpty()) {
			StringBuffer			msg;
			msg << "Invalid multi-byte character on line " << m_lineNum;
			throw ConfigurationException(msg.c_str());
		}
		if (m_atEOF) {
			//--------
			// At EOF. Our work is done.
			//--------
			break;
		}
		if (!m_ch.add(ch)) {
			StringBuffer			msg;
			msg << "Invalid multi-byte character on line " << m_lineNum;
			throw ConfigurationException(msg.c_str());
		}

		status = mbrtowc(&wChar, m_ch.c_str(), m_ch.length(), &m_mbtowcState);
		if (status == -1 && m_ch.isFull()) {
			StringBuffer			msg;
			msg << "Invalid multi-byte character on line " << m_lineNum;
			throw ConfigurationException(msg.c_str());
		}
		m_ch.setWChar(wChar);
	}

	if (m_ch == '\n') {
		m_lineNum ++;
	}
}
Пример #8
0
Variable* Configuration::find(const std::string& variable) const
{
    std::map<std::string, Variable*>::const_iterator it = configuration->find (variable);
    if (it == configuration->end()) {
        // variable not found, create exception message
        std::string message = "[Configuration] Cannot find variable " + variable;
        
	// if we get here, variable was not found in the configuration,
	// hence we have a right to complain
	throw ConfigurationException(PRESAGE_CONFIG_VARIABLE_ERROR, message);
    }

    return it->second;
}
Пример #9
0
void
SchemaTypeTypedef::checkRule(
	const SchemaValidator *		sv,
	const Configuration *		cfg,
	const char *				typeName,
	const StringVector &		typeArgs,
	const char *				rule) const throw(ConfigurationException)
{
	StringBuffer				msg;

	if (typeArgs.length() != 0) {
		msg << "you cannot specify arguments when using user-defined type '"
			<< typeName << "' in '" << rule << "'";
		throw ConfigurationException(msg.c_str());
	}
}
Пример #10
0
void
SchemaTypeScope::checkRule(
	const SchemaValidator *		sv,
	const Configuration *		cfg,
	const char *				typeName,
	const StringVector &		typeArgs,
	const char *				rule) const throw(ConfigurationException)
{
	StringBuffer				msg;

	if (typeArgs.length() != 0) {
		msg << "the '" << typeName << "' type should not take arguments "
			<< "in rule '" << rule << "'";
		throw ConfigurationException(msg.c_str());
	}
}
Пример #11
0
void ConfigurationResult::required(const std::string &msg) const
{
    if (! result_)
    {
        std::string text = msg;
        if (! text.empty())
        {
            text += ". ";
        }

        text += "Configuration of required member on path[" + path_ + "] is failed.";
        LOG4CXX_ERROR(logger_, text);

        throw ConfigurationException(text);
    }
}
Пример #12
0
PhraseSegmentation
FileReadStateInitialiser::initSegmentation(
	boost::shared_ptr<const PhrasePairCollection> phraseTranslations,
	const std::vector<Word> &sentence,
	int documentNumber,
	int sentenceNumber
) const {
	PhraseSegmentation phraseSegmentation = segmentations_[documentNumber][sentenceNumber];
	//Check that all phrases in the phraseSegmentation exist in phraseTranslations
	if (!phraseTranslations->phrasesExist(phraseSegmentation)) {
		//!checkPhrases(phraseTranslations, phraseSegmentation)) {
		LOG(logger_, error, "ERROR: A phrase from the saved state does not exist in phrase table, make sure that the same phrase table is used as when saving the state");
		BOOST_THROW_EXCEPTION(ConfigurationException());
	}

	return phraseSegmentation;
}
Пример #13
0
SearchAlgorithm
*SearchAlgorithm::createSearchAlgorithm(
	const std::string &algo,
	const DecoderConfiguration &config,
	const Parameters &params
) {
	if(algo == "simulated-annealing")
		return new SimulatedAnnealing(config, params);
	else if(algo == "local-beam-search")
		return new LocalBeamSearch(config, params);
	//else if(algo == "metropolis-hastings-sampler")
	//	return new MetropolisHastingsSampler(config, params);
	else {
		Logger logger("DecoderConfiguration");
		LOG(logger, error, "Unknown search algorithm: " << algo);
		BOOST_THROW_EXCEPTION(ConfigurationException());
	}
}
Пример #14
0
StateGenerator::StateGenerator(
	const std::string &initMethod,
	const Parameters &params,
	Random(random)
) :	logger_("StateGenerator"),
	random_(random)
{
	if(initMethod == "monotonic")
		initialiser_ = new MonotonicStateInitialiser(params);
	else if(initMethod == "testset")
		initialiser_ = new NistXmlStateInitialiser(params);
	else if(initMethod == "saved-state")
		initialiser_ = new FileReadStateInitialiser(params);
	else {
		LOG(logger_, error, "Unknown initialisation method: " << initMethod);
		BOOST_THROW_EXCEPTION(ConfigurationException());
	}
}
Пример #15
0
bool loadParam(const std::map<std::string, std::string> &map,
               const std::string &key,
               T &dest,
               std::string failMsg,
               const Validator &validate) {
  const auto it = map.find(key);
  if (it == end(map)) {
    return false;
  }

  bool ok = false;
  T value;
  fromString<T>(it->second, value, ok);
  if (!ok || !validate(value)) {
    throw ConfigurationException(std::move(failMsg));
  }
  dest = value;
  return true;
}
Пример #16
0
 void addOption(const std::string& optName,
                const std::string& helpString,
                bool hasShortName,
                char shortName,
                bool hasDefault,
                const std::string& defaultValue)
 {
   std::string name = optName;
   std::transform(name.begin(), name.end(), name.begin(), ::tolower);
   if (options.find(name) != options.end()) {
     std::string message = "Duplicate option registration: " + name;
     throw ConfigurationException(message.c_str());
   }
   options[name] = ConfigOption(helpString,
                                Validator<T>(),
                                hasShortName,
                                shortName,
                                hasDefault,
                                defaultValue);
 }
Пример #17
0
void Configuration::parseLogLevel(const Json::Value &root) {
    if (root["LogLevel"].asString() == "INFO") {
        logLevel = Logger::INFO;
    }
    else if (root["logLevel"].asString() == "WARNING") {
        logLevel = Logger::WARNING;
    }
    else if (root["logLevel"].asString() == "DEBUG") {
        logLevel = Logger::DEBUG;
    }
    else if (root["logLevel"].asString() == "NONE") {
        logLevel = Logger::NONE;
    }
    else {
        ConfigurationException exception = ConfigurationException(
            ConfigurationException::INCOMPLETE_CONFIG_FILE);
        exception.setDescription("Unkonwn logLevel type " +
                                 root["logLevel"].asString());
        throw exception;
    }
}
Пример #18
0
/**
 * @brief Executes tested program and initializes communication with it.
 * Creates new process in which tested program is executed. After succesfull execution realizes
 * initial phase of the communication with tested program (receives INIT message and sends
 * OPTION message as response).
 * @param msg Object containing OPTION message with analysis options sent to tested program.
 */
void Tracer::init(InitialMsg *optionMsg) {
   pid_t newProcess;
   // Create new process
   newProcess = fork();
   if (newProcess >= 0) {
      if (newProcess == 0) {
         socket->closeWelcomeSocket();

         // Redirect stdout and stderr to /dev/null
         int fd = open("/dev/null", O_WRONLY);
         dup2(fd, 1);
         dup2(fd, 2);
         // Add shared library to LD_PRELOAD
         char ldPreloadTxt[] = "LD_PRELOAD=bin/lib_filesystem.so";
         putenv(ldPreloadTxt);
         // Execute tested program
         if (execv(programArgs[0], programArgs) == -1)
            throw ConfigurationException("Program cannot be executed");
      }
      else {
         // Create socket connection to other process
         socket->acceptConnection();

         // Initialization phase
         // Receive first message and parse it
         std::string msgStr = socket->recvMsg();
         InboundMsg initMsg;
         initMsg.parse(msgStr);
         if (initMsg.getType() == INIT) {
            // If INIT message received, send OPTION message
            socket->sendMsg(optionMsg->compose());
         }
         else {
            throw ProtocolException("INIT not received.");
         }
      }
   }
}
Пример #19
0
Configuration::Configuration(const std::string& directory,
    const std::string& filename) throw (ConfigurationException)
{
    if (!filename.length()) {
        throw ConfigurationException("No valid configuration filename.");
    }

    std::string base_dir = get_home_directory();
    create_directory(directory, base_dir);
    this->filename = base_dir + "/" + directory + "/" + filename;

    /* load file */
    if (file_exists(this->filename)) {
        settings.read(this->filename);
    }

    /* load defaults */
    cdef("player_name", generate_name());
    cdef("show_player_name", "1");
    cdef("player_skin", "goat");
    cdef("fullscreen", "0");
    cdef("show_scanlines", "1");
    cdef("scanlines_intensity", "50");
    cdef("music_volume", "128");
    cdef("sfx_volume", "128");
    cdef("master_server", "master.goatattack.net");
    cdef("master_port", "25113");

    cdef("server_name", "frederic's temple");
    cdef("server_port", "25111");
    cdef("game_mode", "0");
    cdef("max_players", "12");
    cdef("duration", "20");
    cdef("warmup", "0");

    cdef("bind_escape_device", "0");
    cdef("bind_escape_param", "27");
    cdef("bind_chat_device", "0");
    cdef("bind_chat_param", "116");
    cdef("bind_down_device", "0");
    cdef("bind_down_param", "1073741905");
    cdef("bind_drop1_device", "0");
    cdef("bind_drop1_param", "115");
    cdef("bind_drop2_device", "0");
    cdef("bind_drop2_param", "100");
    cdef("bind_drop3_device", "0");
    cdef("bind_drop3_param", "102");
    cdef("bind_fire_device", "0");
    cdef("bind_fire_param", "97");
    cdef("bind_jump_device", "0");
    cdef("bind_jump_param", "32");
    cdef("bind_left_device", "0");
    cdef("bind_left_param", "1073741904");
    cdef("bind_right_device", "0");
    cdef("bind_right_param", "1073741903");
    cdef("bind_stats_device", "0");
    cdef("bind_stats_param", "9");
    cdef("bind_up_device", "0");
    cdef("bind_up_param", "1073741906");

    cdef("deadzone_horizontal", "3200");
    cdef("deadzone_vertical", "3200");

    /* extract -> ready for quick access */
    extract();
}
Пример #20
0
void Configuration::parse(std::string fileName) {
    std::ifstream infile(fileName);
    // check if file exists
    if (not infile.good()) {
        infile.close();
        throw ConfigurationException(
            ConfigurationException::Type::NO_CONFIG_FILE);
    }
    Json::Value root;
    Json::Reader reader;
    bool parseOK = reader.parse(infile, root, false);
    if (not parseOK) {
        std::string details = reader.getFormattedErrorMessages();
        ConfigurationException configurationException(
            ConfigurationException::Type::CONFIG_FILE_SYNTAX_ERROR);
        configurationException.setDescription(details);
        infile.close();
        throw configurationException;
    }
    if (not root["httpServer"]["address"].empty())
        this->httpServerAddress = root["httpServer"]["address"].asString();
    else {
        ConfigurationException exception = ConfigurationException(
            ConfigurationException::Type::INCOMPLETE_CONFIG_FILE);
        exception.setDescription(
            "httpServer.address not provided in config file");
        throw exception;
    }
    if (not root["httpServer"]["port"].empty())
        this->httpServerPort = root["httpServer"]["port"].asInt();
    else {
        ConfigurationException exception = ConfigurationException(
            ConfigurationException::Type::INCOMPLETE_CONFIG_FILE);
        exception.setDescription("httpServer.port not provided in config file");
        throw exception;
    }
    if (not root["httpServer"]["readTimeout"].empty())
        this->httpServerReadTimeout = root["httpServer"]["readTimeout"].asInt();
    else {
        ConfigurationException exception = ConfigurationException(
            ConfigurationException::Type::INCOMPLETE_CONFIG_FILE);
        exception.setDescription(
            "httpServer.readTimeout not provided in config file");
        throw exception;
    }
    if (not root["httpServer"]["maxThreads"].empty())
        this->httpServerMaxThreads = root["httpServer"]["maxThreads"].asInt();
    else {
        ConfigurationException exception = ConfigurationException(
            ConfigurationException::Type::INCOMPLETE_CONFIG_FILE);
        exception.setDescription(
            "httpServer.maxThreads not provided in config file");
        throw exception;
    }
    if (not root["dnsPooler"]["interval"].empty())
        this->dnsPoolerInterval = root["dnsPooler"]["interval"].asInt();
    else {
        ConfigurationException exception = ConfigurationException(
            ConfigurationException::Type::INCOMPLETE_CONFIG_FILE);
        exception.setDescription(
            "dnsPooler.interval not provided in config file");
        throw exception;
    }
    parseLogLevel(root);
    this->readyToUse = true;
}
Пример #21
0
/**
 * @brief Adds function to the notify list.
 * @param f Name of the function to be added.
 * @throws ConfigurationException if function is not valid (if the string is not found in
 * Call::functionsMap)
 */
void InitialMsg::addNotifyFunction(std::string f) {
   if (Call::functionExists(f))
      notifyList.push_back(f);
   else
      throw ConfigurationException("Invalid notify list");
}
Пример #22
0
void
SchemaTypeDurationSeconds::checkRule(
	const SchemaValidator *		sv,
	const Configuration *		cfg,
	const char *				typeName,
	const StringVector &		typeArgs,
	const char *				rule) const throw(ConfigurationException)
{
	StringBuffer				msg;
	int							len;
	int							min;
	int							max;

	len = typeArgs.length();
	if (len == 0) {
		return;
	}
	if (len != 2) {
		msg << "The '" << typeName << "' type should take "
		    << "either no arguments or 2 arguments (denoting "
		    << "min and max durations) in rule '" << rule << "'";
		throw ConfigurationException(msg.c_str());
	}
	try {
		min = cfg->stringToDurationSeconds("", "", typeArgs[0]);
	} catch (const ConfigurationException & ex) {
		msg << "Bad " << typeName << " value for the first ('min') "
			<< "argument in rule '" << rule << "'; should be 'infinite' "
			<< "or in the format '<float> <units>' where <units> is one of: "
			<< "'second', 'seconds', "
			<< "'minute', 'minutes', "
			<< "'hour', 'hours', "
			<< "'day', 'days', "
			<< "'week', 'weeks";
		throw ConfigurationException(msg.c_str());
	}
	try {
		max = cfg->stringToDurationSeconds("", "", typeArgs[1]);
	} catch (const ConfigurationException & ex) {
		msg << "Bad " << typeName << " value for the second ('max') "
			<< "argument in rule '" << rule << "'; should be 'infinite' "
			<< "or in the format '<float> <units>' where <units> is one of: "
			<< "'second', 'seconds', "
			<< "'minute', 'minutes', "
			<< "'hour', 'hours', "
			<< "'day', 'days', "
			<< "'week', 'weeks";
		throw ConfigurationException(msg.c_str());
	}
	if ((min < -1) || (max < -1)) {
		msg << "The 'min' and 'max' of a " << typeName
			<< " cannot be negative in rule '" << rule << "'"
			<< "; min=" << min << "; max=" << max;
		throw ConfigurationException(msg.c_str());
	}
	if ((max != -1) && (min == -1 || min > max)) {
		msg << "The first ('min') argument is larger than the second "
			<< "('max') argument in rule '" << rule << "'";
		throw ConfigurationException(msg.c_str());
	}
}
Пример #23
0
void
LexBase::consumeString(LexToken &token)
{
	StringBuffer			spelling;
	StringBuffer			msg;

	assert(m_ch == '"');

	//--------
	// Note the line number at the start of the string
	//--------
	const int	lineNum = m_lineNum;

	//--------
	// Consume chars until we get to the end of the sting
	//--------
	nextChar();
	while (m_ch != '"') {
		if (m_atEOF || m_ch.c_str()[0] == '\n') {
			token.reset(LEX_STRING_WITH_EOL_SYM, lineNum, spelling.c_str());
			return;
		}
		switch (m_ch.c_str()[0]) {
		case '%':
			//--------
			// Escape char in string
			//--------
			nextChar();
			if (m_atEOF || m_ch.c_str()[0] == '\n') {
				token.reset(LEX_STRING_WITH_EOL_SYM, lineNum, spelling.c_str());
				return;
			}
			switch (m_ch.c_str()[0]) {
			case 't':
				spelling << '\t';
				break;
			case 'n':
				spelling << '\n';
				break;
			case '%':
				spelling << '%';
				break;
			case '"':
				spelling << '"';
				break;
			default:
				msg << "Invalid escape sequence (%" << m_ch.c_str()[0]
					<< ") in string on line " << m_lineNum;
				throw ConfigurationException(msg.c_str());
			}
			break;
		default:
			//--------
			// Typical char in string
			//--------
			spelling << m_ch.c_str();
			break;
		}
		nextChar();
	}
	nextChar();	// consume the terminating double-quote char

	//--------
	// At the end of the string.
	//--------
	token.resetWithOwnership(LEX_STRING_SYM, lineNum, spelling);
	return;
}
Пример #24
0
void
SchemaTypeTuple::validate(
	const SchemaValidator *		sv,
	const Configuration *		cfg,
	const char *				scope,
	const char *				name,
	const char *				typeName,
	const char *				origTypeName,
	const StringVector &		typeArgs,
	int							indentLevel) const
											throw(ConfigurationException)
{
    (void) origTypeName;
    
	StringBuffer				msg;
	StringBuffer				errSuffix;
	StringBuffer				fullyScopedName;
	const char **				list;
	const char *				elemValue;
	const char *				elemTypeName;
	int							i;
	int							listSize;
	int							typeArgsSize;
	int							elemNameIndex;
	int							typeIndex;
	int							numElems;
	SchemaType *				elemTypeDef;
	StringVector				emptyArgs;
	bool						ok;
	const char *				sep;

	//--------
	// Check the length of the list matches the size of the tuple
	//--------
	typeArgsSize = typeArgs.length();
	assert(typeArgsSize != 0);
	assert(typeArgsSize % 2 == 0);
	numElems = typeArgsSize / 2;
	cfg->lookupList(scope, name, list, listSize);
	if (listSize != numElems) {
		cfg->mergeNames(scope, name, fullyScopedName);
		msg << cfg->fileName() << ": there should be " << numElems
			<< " entries in the '" << fullyScopedName << "' " << typeName
		    << "; entries denote";
		for (i = 0; i < numElems; i++) {
			msg << " '" << typeArgs[i*2+0] << "'";
			if (i < numElems-1) {
				msg << ",";
			}
		}
		throw ConfigurationException(msg.c_str());
	}
	//--------
	// Check each item is of the type specified in the tuple
	//--------
	for (i = 0; i < listSize; i++) {
		typeIndex     = (i * 2 + 0) % typeArgsSize;
		elemNameIndex = (i * 2 + 1) % typeArgsSize;
		elemValue = list[i];
		elemTypeName = typeArgs[typeIndex];
		elemTypeDef = findType(sv, elemTypeName);
		ok = callIsA(elemTypeDef, sv, cfg, elemValue, elemTypeName, emptyArgs,
					 indentLevel + 1, errSuffix);
		if (!ok) {
			if (errSuffix.length() == 0) {
				sep = "";
			} else {
				sep = "; ";
			}
			cfg->mergeNames(scope, name, fullyScopedName);
			msg << cfg->fileName() << ": bad " << elemTypeName << " value ('"
				<< elemValue << "') for element " << i+1 << " ('"
			    << typeArgs[elemNameIndex] << "') of the '" << fullyScopedName
				<< "' " << typeName << sep << errSuffix;
			throw ConfigurationException(msg.c_str());
		}
	}
}