//! \param sourceName Pointer to string containing the name of the source to look up.
//!		May be NULL, in which case the default source is used.
//! \param line The line number on which the source name was located.
//!
//! \result A source file object that was previously created in the processSources()
//!		stage.
//!
//! \exception std::runtime_error Thrown if the source name is invalid, or if it
//!		was NULL and there is no default source (i.e., we're not inside a from
//!		statement).
SourceFile * ConversionController::getSourceFromName(std::string * sourceName, int line)
{
	SourceFile * sourceFile = NULL;
	if (sourceName)
	{
		// look up source in map
		source_map_t::iterator it = m_sources.find(*sourceName);
		if (it == m_sources.end())
		{
			source_name_vector_t::const_iterator findIt = std::find<source_name_vector_t::const_iterator, std::string>(m_failedSources.begin(), m_failedSources.end(), *sourceName);
			if (findIt != m_failedSources.end())
			{
				throw semantic_error(format_string("line %d: error opening source '%s'", line, sourceName->c_str()));
			}
			else
			{
				throw semantic_error(format_string("line %d: invalid source name '%s'", line, sourceName->c_str()));
			}
		}
		sourceFile = it->second;
	}
	else
	{
		// no name provided - use default source
		sourceFile = m_defaultSource;
		if (!sourceFile)
		{
			throw semantic_error(format_string("line %d: source required but no default source is available", line));
		}
	}
	
	// open the file if it hasn't already been
	if (!sourceFile->isOpen())
	{
		sourceFile->open();
	}
	return sourceFile;
}