Example #1
0
bool PHPSourceFile::ReadExpression(wxString& expression)
{
    expression.clear();
    phpLexerToken token;
    int depth(0);
    while(NextToken(token)) {
        if(token.type == ';') {
            return true;

        } else if(token.type == '{') {
            UngetToken(token);
            return true;
        }

        switch(token.type) {
        case kPHP_T_REQUIRE:
        case kPHP_T_REQUIRE_ONCE:
            expression.clear();
            return false;

        case kPHP_T_STRING_CAST:
        case kPHP_T_CONSTANT_ENCAPSED_STRING:
        case kPHP_T_C_COMMENT:
        case kPHP_T_CXX_COMMENT:
            // skip comments and strings
            break;
        case '(':
            depth++;
            expression << "(";
            break;
        case ')':
            depth--;
            if(depth == 0) {
                expression << ")";
            }
            break;
        case kPHP_T_NEW:
            if(depth == 0) {
                expression << token.text << " ";
            }
            break;
        default:
            if(depth == 0) {
                expression << token.text;
            }
            break;
        }
    }
    // reached EOF
    return false;
}
Example #2
0
wxString wxRedirectableFd::Release()
{
    Restore();
    wxString name = m_name;
    m_name.clear();
    return name;
}
Example #3
0
// this function should only be called from a catch clause
static string GetExceptionMessage()
{
    wxString msg;

    try
    {
        throw;
    }
#if wxDEBUG_LEVEL
    catch ( TestAssertFailure& )
    {
        msg = s_lastAssertMessage;
        s_lastAssertMessage.clear();
    }
#endif // wxDEBUG_LEVEL
#ifdef wxUSE_VC_CRTDBG
    catch ( CrtAssertFailure& e )
    {
        msg << "CRT assert failure: " << e.m_msg;
    }
#endif // wxUSE_VC_CRTDBG
    catch ( std::exception& e )
    {
        msg << "std::exception: " << e.what();
    }
    catch ( ... )
    {
        msg = "Unknown exception caught.";
    }

    return string(msg.mb_str());
}
Example #4
0
// ----------------------------------------------------------------------------
// wxIconManager implementation
// ----------------------------------------------------------------------------
wxIconManager::wxIconManager(wxString sub_dir)
{
   const String localDir(mApplication->GetLocalDir());

   m_GlobalDir = mApplication->GetDataDir();

   // look in the source directory if there is no global one
#ifdef M_TOP_SOURCEDIR
   if ( m_GlobalDir == localDir )
   {
      m_GlobalDir.clear();
      m_GlobalDir << M_TOP_SOURCEDIR << DIR_SEPARATOR << _T("src");
   }
#endif // defined(M_TOP_SOURCEDIR)

   m_GlobalDir << DIR_SEPARATOR << _T("icons");

   m_LocalDir << localDir << DIR_SEPARATOR << _T("icons");

   if(sub_dir == _T("default") || sub_dir == _("default"))
      sub_dir.clear();
   SetSubDirectory(sub_dir);

   m_unknownIcon = wxIcon(unknown_xpm);
}
Example #5
0
bool CServerPath::Segmentize(wxString str, tSegmentList& segments)
{
	bool append = false;
	while (!str.empty())
	{
		wxString segment;
		int pos = str.Find(traits[m_type].separator);
		if (pos == -1)
		{
			segment = str,
			str.clear();
		}
		else if (!pos)
		{
			str = str.Mid(1);
			continue;
		}
		else
		{
			segment = str.Left(pos);
			str = str.Mid(pos + 1);
		}

		if (traits[m_type].has_dots)
		{
			if (segment == _T("."))
				continue;
			else if (segment == _T(".."))
			{
				if (segments.empty())
					return false;
				else
				{
					segments.pop_back();
					continue;
				}
			}
		}

		bool append_next = false;
		if (traits[m_type].separatorEscape && segment.Last() == traits[m_type].separatorEscape)
		{
			append_next = true;
			segment.RemoveLast();
			segment += traits[m_type].separator;
		}

		if (append)
			segments.back() += segment;
		else
			segments.push_back(segment);

		append = append_next;
	}
	if (append)
		return false;

	return true;
}
Example #6
0
void clTernServer::ProcessType(const wxString& type, wxString& signature, wxString& retValue, int& imgID)
{
    // initialize values
    imgID = wxNOT_FOUND;
    retValue.clear();
    signature.clear();

    if(type.StartsWith("fn(")) {
        imgID = 9; // function
        int depth = 1;
        wxString tmp = type.Mid(3); // skip fn(
        signature = "(";
        bool cont = true;
        while(!tmp.IsEmpty() && cont) {
            wxChar ch = tmp.GetChar(0);
            tmp.Remove(0, 1);
            switch(ch) {
            case '(':
                ++depth;
                signature << "(";
                break;

            case ')':
                --depth;
                if(depth == 0) cont = false;
                signature << ")";
                break;

            default:
                signature << ch;
                break;
            }
        }

        tmp.Trim().Trim(false);
        if(tmp.StartsWith("->")) {
            tmp = tmp.Mid(2);
            retValue = tmp;
        }

    } else {
        imgID = 3; // Member public
        signature.clear();
        retValue = type;
    }
}
Example #7
0
bool MyConnection::OnStopAdvise(const wxString& topic, const wxString& item)
{
    wxLogMessage("OnStopAdvise(\"%s\",\"%s\")", topic, item);
    wxLogMessage("Returning true");
    m_sAdvise.clear();
    Stop();
    return true;
}
Example #8
0
// Returns default device and port names
static bool wxGetDefaultDeviceName(wxString& deviceName, wxString& portName)
{
    deviceName.clear();

    LPDEVNAMES  lpDevNames;
    LPTSTR      lpszDeviceName;
    LPTSTR      lpszPortName;

    PRINTDLG    pd;

    // Cygwin has trouble believing PRINTDLG is 66 bytes - thinks it is 68
#ifdef __GNUWIN32__
    memset(&pd, 0, 66);
    pd.lStructSize    = 66; // sizeof(PRINTDLG);
#else
    memset(&pd, 0, sizeof(PRINTDLG));
    pd.lStructSize    = sizeof(PRINTDLG);
#endif

    pd.hwndOwner      = (HWND)NULL;
    pd.hDevMode       = NULL; // Will be created by PrintDlg
    pd.hDevNames      = NULL; // Ditto
    pd.Flags          = PD_RETURNDEFAULT;
    pd.nCopies        = 1;

    if (!PrintDlg((LPPRINTDLG)&pd))
    {
        if ( pd.hDevMode )
            GlobalFree(pd.hDevMode);
        if (pd.hDevNames)
            GlobalFree(pd.hDevNames);

        return false;
    }

    if (pd.hDevNames)
    {
        lpDevNames = (LPDEVNAMES)GlobalLock(pd.hDevNames);
        lpszDeviceName = (LPTSTR)lpDevNames + lpDevNames->wDeviceOffset;
        lpszPortName   = (LPTSTR)lpDevNames + lpDevNames->wOutputOffset;

        deviceName = lpszDeviceName;
        portName = lpszPortName;

        GlobalUnlock(pd.hDevNames);
        GlobalFree(pd.hDevNames);
        pd.hDevNames=NULL;
    }

    if (pd.hDevMode)
    {
        GlobalFree(pd.hDevMode);
        pd.hDevMode=NULL;
    }
    return ( !deviceName.empty() );
}
Example #9
0
wxString MemCheckPlugin::PrepareCommand(const wxString& projectName, wxString& wd)
{
    wd.clear();
    if(!clCxxWorkspaceST::Get()->IsOpen()) { return ""; }

    ProjectPtr proj = clCxxWorkspaceST::Get()->GetProject(projectName);
    if(!proj) {
        clWARNING() << "MemCheckPlugin::PrepareCommand(): could not find project:" << projectName;
        return wxEmptyString;
    }

    BuildConfigPtr bldConf = clCxxWorkspaceST::Get()->GetProjBuildConf(projectName, wxEmptyString);
    if(!bldConf) {
        clWARNING() << "MemCheckPlugin::PrepareCommand(): failed to find project configuration for project:"
                    << projectName;
        return wxEmptyString;
    }

    wxString projectPath = proj->GetFileName().GetPath();

    // expand variables
    wxString cmd = bldConf->GetCommand();
    cmd = MacroManager::Instance()->Expand(cmd, NULL, projectName);

    wxString cmdArgs = bldConf->GetCommandArguments();
    cmdArgs = MacroManager::Instance()->Expand(cmdArgs, NULL, projectName);

    // Execute command & cmdArgs
    wd = bldConf->GetWorkingDirectory();
    wd = MacroManager::Instance()->Expand(wd, NULL, projectName);

    wxFileName workingDir(wd, "");
    if(workingDir.IsRelative()) { workingDir.MakeAbsolute(projectPath); }

    wxFileName fileExe(cmd);
    if(fileExe.IsRelative()) { fileExe.MakeAbsolute(workingDir.GetPath()); }
    fileExe.Normalize();

#ifdef __WXMSW__
    if(!fileExe.Exists() && fileExe.GetExt().IsEmpty()) {
        // Try with .exe
        wxFileName withExe(fileExe);
        withExe.SetExt("exe");
        if(withExe.Exists()) { fileExe = withExe; }
    }
#endif
    wd = workingDir.GetPath();
    cmd = fileExe.GetFullPath();

    cmd = ::WrapWithQuotes(cmd);
    cmd << " " << cmdArgs;
    clDEBUG() << "Command to execute:" << cmd;
    clDEBUG() << "Working directory:" << wd;
    return cmd;
}
bool ModuleManager::RegisterPlugin(const PluginID & providerID, const wxString & path, wxString &errMsg)
{
   errMsg.clear();
   if (mDynModules.find(providerID) == mDynModules.end())
   {
      return false;
   }

   auto nFound = mDynModules[providerID]->DiscoverPluginsAtPath(path, errMsg);

   return nFound > 0;
}
Example #11
0
wxString GetParamByChar(wxString& params, const wxChar& sep)
{
	const int pos = params.Find(sep);
	if (pos == wxNOT_FOUND) { // no separator found, return params
		const wxString ret = params;
		params.clear();
		return ret;
	}
	const wxString ret = params.Left(pos); //separator found, return before sep
	params = params.Mid(pos + 1);	  //return everything after first seperator
	return ret;
}
Example #12
0
// close the current display
void wxCloseDisplay()
{
    if ( gs_currentDisplay )
    {
        if ( XCloseDisplay(gs_currentDisplay) != 0 )
        {
            wxLogWarning(_("Failed to close the display \"%s\""),
                         gs_displayName.c_str());
        }

        gs_currentDisplay = NULL;
        gs_displayName.clear();
    }
}
Example #13
0
bool COptions::GetXmlValue(unsigned int nID, wxString &value, TiXmlElement *settings /*=0*/)
{
	if (!settings)
	{
		if (!m_pXmlFile)
			return false;

		settings = m_pXmlFile->GetElement()->FirstChildElement("Settings");
		if (!settings)
		{
			TiXmlNode *node = m_pXmlFile->GetElement()->InsertEndChild(TiXmlElement("Settings"));
			if (!node)
				return false;
			settings = node->ToElement();
			if (!settings)
				return false;
		}
	}

	TiXmlNode *node = 0;
	while ((node = settings->IterateChildren("Setting", node)))
	{
		TiXmlElement *setting = node->ToElement();
		if (!setting)
			continue;

		const char *attribute = setting->Attribute("name");
		if (!attribute)
			continue;
		if (strcmp(attribute, options[nID].name))
			continue;

		TiXmlNode *text = setting->FirstChild();
		if (!text)
		{
			value.clear();
			return true;
		}

		if (!text->ToText())
			return false;

		value = ConvLocal(text->Value());

		return true;
	}

	return false;
}
Example #14
0
bool CControlSocket::ParsePwdReply(wxString reply, bool unquoted /*=false*/, const CServerPath& defaultPath /*=CServerPath()*/)
{
	if (!unquoted)
	{
		int pos1 = reply.Find('"');
		int pos2 = reply.Find('"', true);
		if (pos1 == -1 || pos1 >= pos2) {
			pos1 = reply.Find('\'');
			pos2 = reply.Find('\'', true);

			if (pos1 != -1 && pos1 < pos2)
				LogMessage(__TFILE__, __LINE__, this, MessageType::Debug_Info, _T("Broken server sending single-quoted path instead of double-quoted path."));
		}
		if (pos1 == -1 || pos1 >= pos2) {
			LogMessage(__TFILE__, __LINE__, this, MessageType::Debug_Info, _T("Broken server, no quoted path found in pwd reply, trying first token as path"));
			pos1 = reply.Find(' ');
			if (pos1 != -1) {
				reply = reply.Mid(pos1 + 1);
				pos2 = reply.Find(' ');
				if (pos2 != -1)
					reply = reply.Left(pos2);
			}
			else
				reply.clear();
		}
		else {
			reply = reply.Mid(pos1 + 1, pos2 - pos1 - 1);
			reply.Replace(_T("\"\""), _T("\""));
		}
	}

	m_CurrentPath.SetType(m_pCurrentServer->GetType());
	if (reply.empty() || !m_CurrentPath.SetPath(reply)) {
		if (reply.empty())
			LogMessage(MessageType::Error, _("Server returned empty path."));
		else
			LogMessage(MessageType::Error, _("Failed to parse returned path."));

		if (!defaultPath.empty()) {
			LogMessage(MessageType::Debug_Warning, _T("Assuming path is '%s'."), defaultPath.GetPath());
			m_CurrentPath = defaultPath;
			return true;
		}
		return false;
	}

	return true;
}
Example #15
0
void PHPCodeCompletion::GetMembers(IEditor* editor, PHPEntityBase::List_t& members, wxString& scope)
{
    members.clear();
    scope.clear();
    if(!editor) {
        return;
    }

    // Parse until the current position to get the current scope name
    {
        wxString text = editor->GetTextRange(0, editor->GetCurrentPosition());
        PHPSourceFile sourceFile(text);
        sourceFile.SetParseFunctionBody(true);
        sourceFile.SetFilename(editor->GetFileName());
        sourceFile.Parse();

        const PHPEntityClass* scopeAtPoint = sourceFile.Class()->Cast<PHPEntityClass>();
        if(!scopeAtPoint) {
            return;
        }
        scope = scopeAtPoint->GetFullName();
    }

    // Second parse: parse the entire buffer so we are not limited by the caret position
    wxString text = editor->GetTextRange(0, editor->GetLength());
    PHPSourceFile sourceFile(text);
    sourceFile.SetParseFunctionBody(true);
    sourceFile.SetFilename(editor->GetFileName());
    sourceFile.Parse();

    // Locate the scope
    PHPEntityBase::Ptr_t parentClass = sourceFile.Namespace()->FindChild(scope);
    if(!parentClass) return;

    // filter out
    const PHPEntityBase::List_t& children = parentClass->GetChildren();
    PHPEntityBase::List_t::const_iterator iter = children.begin();

    for(; iter != children.end(); ++iter) {
        PHPEntityBase::Ptr_t child = *iter;
        if(child->Is(kEntityTypeVariable) && child->Cast<PHPEntityVariable>()->IsMember() &&
            !child->Cast<PHPEntityVariable>()->IsConst() && !child->Cast<PHPEntityVariable>()->IsStatic()) {
            // a member of a class
            members.push_back(child);
        }
    }
}
Example #16
0
bool CServerPath::ExtractFile(wxString& dir, wxString& file)
{
	int pos = dir.Find(traits[m_type].separator, true);
	if (pos == (int)dir.Length() - 1)
		return false;

	if (pos == -1)
	{
		file = dir;
		dir.clear();
		return true;
	}

	file = dir.Mid(pos + 1);
	dir = dir.Left(pos + 1);

	return true;
}
Example #17
0
bool FileUtils::ReadFileContent(const wxFileName& fn, wxString& data, const wxMBConv& conv)
{
    wxString filename = fn.GetFullPath();
    data.clear();
    const char* cfile = filename.mb_str(wxConvUTF8).data();
    FILE* fp = fopen(cfile, "rb");
    if(!fp) {
        // Nothing to be done
        clERROR() << "Failed to open file:" << fn << "." << strerror(errno);
        return false;
    }

    // Get the file size
    fseek(fp, 0, SEEK_END);
    long fsize = ftell(fp);
    fseek(fp, 0, SEEK_SET);

    // Allocate buffer for the read
    char* buffer = (char*)malloc(fsize + 1);
    long bytes_read = fread(buffer, 1, fsize, fp);
    if(bytes_read != fsize) {
        // failed to read
        clERROR() << "Failed to read file content:" << fn << "." << strerror(errno);
        fclose(fp);
        free(buffer);
        return false;
    }
    buffer[fsize] = 0;

    // Close the handle
    fclose(fp);

    // Convert it into wxString
    data = wxString(buffer, conv, fsize);
    if(data.IsEmpty() && fsize != 0) {
        // Conversion failed
        data = wxString::From8BitData(buffer, fsize);
    }

    // Release the C-buffer allocated earlier
    free(buffer);
    return true;
}
bool GdbMIThreadInfoParser::ReadBlock(wxString& input, const wxString& pair, wxString& block)
{
    wxChar openChar  = pair.GetChar(0);
    wxChar closeChar = pair.GetChar(1);
    block.clear();
    int depth = 0;
    
    const int StateSearchStart = 0;
    const int StateCollecting  = 1;
    
    int curstate = StateSearchStart;
    for(size_t i=0; i<input.length(); ++i) {
        wxChar ch = input.GetChar(i);
        switch ( curstate ) {
        case StateSearchStart:
            if ( ch == openChar ) {
                depth++;
                curstate = StateCollecting;
            }
            break;
        case StateCollecting:
            // Incase the open/close are the same, always
            // test for closeure before an open
            if ( ch == closeChar ) {
                depth--;
                if ( depth == 0 ) {
                    // remove the content up to the current position
                    // from input and return the collected block
                    input = input.Mid(i);
                    return true;
                }
            } else if ( ch == openChar ) {
                depth++;
            }
            
            block << ch;
            break;
        }
    }
    return false;
}
Example #19
0
unsigned VampEffectsModule::DiscoverPluginsAtPath(
   const wxString & path, wxString &errMsg,
   const RegistrationCallback &callback)
{
   errMsg.clear();
   int output;
   bool hasParameters;

   auto vp = FindPlugin(path, output, hasParameters);
   if (vp)
   {
      VampEffect effect(std::move(vp), path, output, hasParameters);
      if (callback)
         callback( this, &effect );

      return 1;
   }

   errMsg = _("Could not load the library");
   return 0;
}
Example #20
0
void GotoFileList::Find(const wxString& searchtext, const std::map<wxString,wxString>& triggers) {
	m_tempEntry->Clear();

	if (searchtext.empty()) {
		// Remove highlights
		m_searchText.clear();
		SetSelection(-1); // de-select
		ScrollToLine(0);
		UpdateList(true);
		return;
	}

	// Convert to lower case for case insensitive search
	m_searchText = searchtext.Lower();

	// Find all matching filenames
	m_items.clear();
	std::vector<unsigned int> hlChars;
	for (unsigned int i = 0; i < m_actions.size(); ++i)
		AddFileIfMatching(m_searchText, m_actions[i]);

	sort(m_items.begin(), m_items.end());

	// Check if we have a matching trigger
	int selection = FindMatchesAndSelection(triggers);

	// Update display
	Freeze();
	SetItemCount(m_items.size());

	if (m_items.empty())
		SetSelection(-1); // deselect
	else if (selection != wxNOT_FOUND)
		SetSelection(selection);
	else
		SetSelection(0);

	RefreshAll();
	Thaw();
}
Example #21
0
int FunctionsParser::ReadClassName(wxString& clsname)
{
    clsname.clear();
    int type = 0;

    while(true) {
        type = m_scanner.yylex();
        if(type == 0) return 0;

        if(type == IDENTIFIER) {
            clsname = m_scanner.YYText();

        } else if(type == '{' || type == ':') {
            return type;

        } else if(type == ';') {
            // we probably encountered a forward declaration or 'friend' statement
            clsname.Clear();
            return (int)';';
        }
    }
    return 0;
}
Example #22
0
void FileEntry::Clear() {
	name.clear();
	nameLower.clear();
	path.clear();
}
Example #23
0
// Helpers to generate a key value pair for item 'i', out of a total of 'count'
void MakeKeyValuePair(size_t i, size_t /*count*/, wxString& key, wxString& val)
{
    key.clear();
    key << i;
    val = wxT("A") + key + wxT("C");
}
// Translate kFSEventStreamEventFlag* flags
// to wxFSW_EVENT_* flags.
// warning and msg are out parameters, filled in when
// there is an error in the stream.
static int wxFSEventsToWatcherFlags(FSEventStreamEventFlags flags,
wxFSWWarningType& warning, wxString& msg)
{
    msg.clear();
    warning = wxFSW_WARNING_NONE;

    // see https://developer.apple.com/library/mac/documentation/Darwin/Reference/FSEvents_Ref/index.html
    // for event flag meanings
    int ret = 0;
    int warnings =
        kFSEventStreamEventFlagMustScanSubDirs
        | kFSEventStreamEventFlagUserDropped
        | kFSEventStreamEventFlagKernelDropped
        | kFSEventStreamEventFlagMount
    ;

    int errors = kFSEventStreamEventFlagRootChanged;

    // The following flags are not handled:
    // kFSEventStreamEventFlagHistoryDone (we never ask for old events)
    // kFSEventStreamEventFlagEventIdsWrapped ( we don't keep track nor
    //  expose event IDs)

    int created = kFSEventStreamEventFlagItemCreated;
    int deleted = kFSEventStreamEventFlagItemRemoved;
    int renamed = kFSEventStreamEventFlagItemRenamed;
    int modified = kFSEventStreamEventFlagItemModified;
    int attrib = kFSEventStreamEventFlagItemChangeOwner
        | kFSEventStreamEventFlagItemFinderInfoMod
        | kFSEventStreamEventFlagItemInodeMetaMod
        | kFSEventStreamEventFlagItemXattrMod;

    if ( created & flags )
    {
        ret |= wxFSW_EVENT_CREATE;
    }
    if ( deleted & flags )
    {
        ret |= wxFSW_EVENT_DELETE;
    }
    if ( renamed & flags )
    {
        ret |= wxFSW_EVENT_RENAME;
    }
    if ( modified & flags )
    {
        ret |= wxFSW_EVENT_MODIFY;
    }
    if ( attrib & flags )
    {
        ret |= wxFSW_EVENT_ATTRIB;
    }
    if ( kFSEventStreamEventFlagUnmount & flags )
    {
        ret |= wxFSW_EVENT_UNMOUNT;
    }
    if ( warnings & flags )
    {
        warning = wxFSW_WARNING_GENERAL;
        ret |= wxFSW_EVENT_WARNING;
        if (flags & kFSEventStreamEventFlagMustScanSubDirs)
        {
            msg += "Must re-scan sub directories.";
        }
        if (flags & kFSEventStreamEventFlagUserDropped)
        {
            msg += "User dropped events";
            warning = wxFSW_WARNING_OVERFLOW;
        }
        if (flags & kFSEventStreamEventFlagKernelDropped)
        {
            msg += "Kernel dropped events";
            warning = wxFSW_WARNING_OVERFLOW;
        }
        if (flags & kFSEventStreamEventFlagMount)
        {
            msg += "A volume was mounted underneath the watched directory.";
        }
    }
    if ( errors & flags )
    {
        ret |= wxFSW_EVENT_ERROR;
        msg = "Path being watched has been renamed";
    }

    //  don't think that FSEvents tells us about wxFSW_EVENT_ACCESS
    return ret;
}
Example #25
0
/* static */
wxProtocolError wxProtocol::ReadLine(wxSocketBase *sock, wxString& result)
{
    static const int LINE_BUF = 4095;

    result.clear();

    wxCharBuffer buf(LINE_BUF);
    char *pBuf = buf.data();
    while ( sock->WaitForRead() )
    {
        // peek at the socket to see if there is a CRLF
        sock->Peek(pBuf, LINE_BUF);

        size_t nRead = sock->LastCount();
        if ( !nRead && sock->Error() )
            return wxPROTO_NETERR;

        // look for "\r\n" paying attention to a special case: "\r\n" could
        // have been split by buffer boundary, so check also for \r at the end
        // of the last chunk and \n at the beginning of this one
        pBuf[nRead] = '\0';
        const char *eol = strchr(pBuf, '\n');

        // if we found '\n', is there a '\r' as well?
        if ( eol )
        {
            if ( eol == pBuf )
            {
                // check for case of "\r\n" being split
                if ( result.empty() || result.Last() != _T('\r') )
                {
                    // ignore the stray '\n'
                    eol = NULL;
                }
                //else: ok, got real EOL

                // read just this '\n' and restart
                nRead = 1;
            }
            else // '\n' in the middle of the buffer
            {
                // in any case, read everything up to and including '\n'
                nRead = eol - pBuf + 1;

                if ( eol[-1] != '\r' )
                {
                    // as above, simply ignore stray '\n'
                    eol = NULL;
                }
            }
        }

        sock->Read(pBuf, nRead);
        if ( sock->LastCount() != nRead )
            return wxPROTO_NETERR;

        pBuf[nRead] = '\0';
        result += wxString::FromAscii(pBuf);

        if ( eol )
        {
            // remove trailing "\r\n"
            result.RemoveLast(2);

            return wxPROTO_NOERR;
        }
    }

    return wxPROTO_NETERR;
}
// Get PID and name of each process that has our DLL loaded.
static bool GetProcesses(std::vector<ProcessInfo>& processes)
{
   // PSAPI function pointers.
   BOOL (WINAPI* lpfEnumProcesses)(DWORD*, DWORD, DWORD*);
   BOOL (WINAPI* lpfEnumProcessModules)(HANDLE, HMODULE*, DWORD, LPDWORD );
   DWORD (WINAPI* lpfGetModuleBaseName)(HANDLE, HMODULE, LPCTSTR, DWORD);
   
   bool found = false;
         
   // Load library and get function pointers.
   HINSTANCE hInstLib = LoadLibraryA("PSAPI.DLL");
   if (!hInstLib)
   {
       DBG("Failed to load PSAPI.DLL");
       return false;
   }
   
   // Get procedure addresses.
   lpfEnumProcesses = (BOOL (WINAPI*)(DWORD*,DWORD,DWORD*)) GetProcAddress(hInstLib, "EnumProcesses");
   lpfEnumProcessModules = (BOOL (WINAPI*)(HANDLE, HMODULE*, DWORD, LPDWORD)) GetProcAddress( hInstLib, "EnumProcessModules" );
   lpfGetModuleBaseName =(DWORD (WINAPI*)(HANDLE, HMODULE, LPCTSTR, DWORD )) GetProcAddress( hInstLib, "GetModuleBaseNameW" );

   if (!lpfEnumProcesses ||
       !lpfEnumProcessModules ||
       !lpfGetModuleBaseName)
   {
       DBG("GetProcAddress failed");
       FreeLibrary(hInstLib);
       return false;
   }

   DWORD pidList[1000];
   DWORD iCbneeded;
   if (!lpfEnumProcesses(pidList, sizeof(pidList), &iCbneeded))
   {
       DBG("EnumProcesses failed");
       FreeLibrary(hInstLib);
       return false;
   }

   // How many processes are there?
   int iNumProc = iCbneeded/sizeof(DWORD);

   // Get and match the name of each process
   for (int i = 0; i < iNumProc; ++i)
   {
       // First, get a handle to the process
       HANDLE processHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pidList[i]);
       if (processHandle)
       {
           // Get modules loaded by process
           int maxModules = 1000;
           HMODULE* hMod = 0;
           while (1)
           {
               hMod = new HMODULE[maxModules];
               // Determine number of modules
               if (!lpfEnumProcessModules(processHandle, hMod, maxModules*sizeof(HMODULE), &iCbneeded))
               {
                   DWORD err = GetLastError();
                   if (err = ERROR_PARTIAL_COPY)
                   {
                       // This means that we are looking at the SYSTEM process. Skip it.
                       delete[] hMod;
                       hMod = 0;
                       break;
                   }
               }
               else if (iCbneeded <= maxModules*sizeof(HMODULE))
                   break;
               delete[] hMod;
               if (maxModules > 50000)
               {
                   DBG("maxModules: " << maxModules);
                   return false; // This is getting ridiculous...
               }
           }
           if (!hMod)
               continue;
           // Explorer?
           TCHAR executableName[MAX_PATH];
           if (!lpfGetModuleBaseName(processHandle, hMod[0], executableName, MAX_PATH))
           {
               DBG("GetModuleBaseName failed for process " << pidList[i]);
               return false;
           }
           //DBG("PROCESS " << wxAscii(executableName));
           if (!_tcsicmp(executableName, wxT("explorer.exe")))
           {
               // Explorer must always be killed
               processes.push_back(ProcessInfo(pidList[i], executableName, wxT("")));
               continue;
           }
           // Check if any of the modules are our DLL
           int numModules = iCbneeded/sizeof(HMODULE);
           for (int j = 1; j < numModules; ++j)
           {
               TCHAR name[MAX_PATH];
               if (!lpfGetModuleBaseName(processHandle, hMod[j], name, MAX_PATH))
               {
                   DBG("GetModuleBaseName failed for module " << j);
                   return false;
               }
               if (!_tcsicmp(name, wxT("tortoiseshell.dll")) ||
                   !_tcsicmp(name, wxT("tortoiseshell64.dll")))
               {
                   DBG("Process " << pidList[i] << " has " << wxAscii(name) << " loaded");
                   // Yes, this process must be terminated
                   windowTitle.clear();
                   EnumWindows(EnumWindowsCallback, pidList[i]);
                   processes.push_back(ProcessInfo(pidList[i], executableName, windowTitle));
               }
           }
           delete[] hMod;
           CloseHandle(processHandle);
       }
   }
   FreeLibrary(hInstLib);
   DBG("GetProcesses SUCCESS");
   return true;
}