Example #1
0
const std::string replaceEnvVars(const std::string& str)
{
   std::string ret_str(str);

   ret_str = replaceEnvVars(ret_str, std::string("${"), std::string("}") );
   ret_str = replaceEnvVars(ret_str, std::string("$("), std::string(")") );

   return ret_str;
}
Example #2
0
bool ConfigMap::readFile(const std::string &filename) 
{
	std::string instr;

	if (MinVR::FileSystem::getInstance().exists(filename))
	{
		std::string output = "ConfigMap parsing file \"" + filename + "\".";
		std::cout << output << std::endl;

		ifstream fIn;
		fIn.open(filename.c_str(),std::ios::in);

		if (!fIn) {
			MinVR::Logger::getInstance().assertMessage(false, "ConfigMap Error: Unable to load config file");
		}
		std::stringstream ss;
		ss << fIn.rdbuf();
    
		instr =  ss.str();
	}
	else
	{  
		std::stringstream ss;
		ss << "Cannot locate config file " << filename;
		MinVR::Logger::getInstance().assertMessage(false, ss.str().c_str());
	}


	// convert all endline characters to \n's
	for (int i=0;i<instr.size();i++)
	{ 
		if (instr[i] == '\r') {
			instr[i] = '\n';
		}
	}

	// remove any cases of two \n's next to each other
	for (int i=0;i<instr.size()-1;i++)
	{ 
		if ((instr[i] == '\n') && (instr[i+1] == '\n'))	{
			instr = instr.substr(0,i) + instr.substr(i+1);
		}
	}

	// add a \n so that every file ends in at least one \n
	instr = instr + std::string("\n");

	// start pulling out name, value pairs
	// the config file must end with a newline
	//
	while (instr.size()) {
		int endline = instr.find("\n");
		std::string nameval = instr.substr(0,endline);

		// a backslash not followed by a second backslash means continue on
		// the next line, wipe out everything from the backslash to the newline
		/**  Note, this will miss the following scenario, which will probably
		never occur in practice:
		myname myvalue with a single slash here \\ and \
		continued on the next line like this
		So, this doesn't handle a \\ on the same line as a \
		**/
		int slash = nameval.find("\\");

		bool nextCharIsSlash = false;
		if (slash < nameval.size() - 1) {
			nextCharIsSlash = (nameval[slash+1] == '\\');
		} 
		else {
			nextCharIsSlash = false;
		}

		while ((slash != nameval.npos) && !nextCharIsSlash && (endline != nameval.npos)) {
			std::string fromPrevLine = nameval.substr(0,slash);
			instr = instr.substr(endline+1);
			endline = instr.find("\n");
			nameval = fromPrevLine + instr.substr(0,endline);
			slash = nameval.find("\\");
			if (slash < nameval.size() - 1) {
				nextCharIsSlash = (nameval[slash+1] == '\\');
			}
			else {
				nextCharIsSlash = false;
			}
		}

		// a line starting with # is a comment, ignore it
		//
		if (nameval.size() > 0 && nameval[0] != '#')
		{ 
			// if we have two backslashes \\ treat this as an escape sequence for
			// a single backslash, so replace the two with one
			int doubleslash = nameval.find("\\\\");

			if (doubleslash >= 0)
			{  nameval = nameval.substr(0,doubleslash)
			+ nameval.substr(doubleslash + 1);
			}

			// replace all $(NAME) sequences with the value of the environment
			// variable NAME.  under cygwin, cygwin-style paths are replaced with
			// windows style paths.
			nameval = replaceEnvVars(nameval);

			int firstspace = nameval.find(" ");
			int firsttab = nameval.find('\t');
			if (((firsttab >=0) && (firsttab < firstspace)) || ((firsttab >=0) && (firstspace < 0)))
			{
				firstspace = firsttab;
			}

			std::string name = nameval.substr(0,firstspace);
			std::string val;

			if (firstspace >= 0)
			{  
				val = trimWhitespace(nameval.substr(firstspace + 1));
			}

			if (name != "")	{
				if ((name.size() > 2) && (name[name.size()-2] == '+') && (name[name.size()-1] == '='))
				{
					name = name.substr(0,name.size()-2);

					if (ConfigMap::containsKey(name)) {
						std::string newVal = ConfigMap::getValue(name) + " " + val;
						ConfigMap::set(name, newVal);
					}
					else {
						ConfigMap::set(name, val);
					}
				}
				else {
					ConfigMap::set(name, val);
				}
			}
		} // end not a comment

		instr = instr.substr(endline+1);
	}

	return true;
}