bool SIMPLEAPI ExpandResponseFiles(CVector<CUniString>& args, CUniString& strError)
{
	for (int i=0; i<args.GetSize(); i++)
	{
		const wchar_t* pszFile=args[i];

		// Commented switch
		if (pszFile[0]=='#')
		{
			args.RemoveAt(i);
			i--;
			continue;
		}

		// Response file?
		if (pszFile[0]=='@')
		{
			pszFile++;

			bool bOptional=false;
			if (pszFile[0]=='@')
			{
				bOptional++;
				pszFile++;
			}

			// Load response file
			CUniString strResponseText;
			if (!LoadTextFile<wchar_t>(pszFile, strResponseText))
			{
				args.RemoveAt(i);
				i--;
				if (bOptional)
					continue;

				strError=Format(L"Failed to load response file '%s'", pszFile);
				return false;
			}

			// Parse args
			CVector<CUniString> vecFile;
			SplitCommandLine(strResponseText, vecFile);

			args.RemoveAt(i);
			args.InsertAt(i, vecFile);
			i--;
		}
	}

	return true;
}
void SplitCommandLine(const UString &s, UStringVector &parts)
{
  UString sTemp = s;
  sTemp.Trim();
  parts.Clear();
  for (;;)
  {
    UString s1, s2;
    if (SplitCommandLine(sTemp, s1, s2))
      parts.Add(s1);
    if (s2.IsEmpty())
      break;
    sTemp = s2;
  }
}
void SplitCommandLine(const UString &s, UStringVector &parts)
{
  UString sTemp = s;
  sTemp.Trim();
  parts.Clear();
  while (true)
  {
    UString s1, s2;
    SplitCommandLine(sTemp, s1, s2);
    // s1.Trim();
    // s2.Trim();
    if (!s1.IsEmpty())
      parts.Add(s1);
    if (s2.IsEmpty())
      return;
    sTemp = s2;
  }
}