void DbgGdb::GetDebugeePID(const wxString& line)
{
    if(m_debuggeePid == wxNOT_FOUND) {
        if(GetIsRemoteDebugging()) {
            m_debuggeePid = m_gdbProcess->GetPid();

        } else {

            static wxRegEx reDebuggerPidWin(wxT("New Thread ([0-9]+)\\.(0[xX][0-9a-fA-F]+)"));
            static wxRegEx reGroupStarted(wxT("id=\"([0-9]+)\""));
            static wxRegEx reSwitchToThread(wxT("Switching to process ([0-9]+)"));

            // test for the debuggee PID
            // in the line with the following pattern:
            // =thread-group-started,id="i1",pid="15599"
            if(m_debuggeePid < 0 && !line.IsEmpty()) {
                wxString debuggeePidStr;

                if(line.Contains(wxT("=thread-group-started")) && reGroupStarted.Matches(line)) {
                    debuggeePidStr = reGroupStarted.GetMatch(line, 1);

                } else if(line.Contains(wxT("=thread-group-created")) && reGroupStarted.Matches(line)) {
                    debuggeePidStr = reGroupStarted.GetMatch(line, 1);

                } else if(reDebuggerPidWin.Matches(line)) {
                    debuggeePidStr = reDebuggerPidWin.GetMatch(line, 1);

                } else if(reSwitchToThread.Matches(line)) {
                    debuggeePidStr = reSwitchToThread.GetMatch(line, 1);
                }

                if(!debuggeePidStr.IsEmpty()) {
                    long iPid(0);
                    if(debuggeePidStr.ToLong(&iPid)) {
                        m_debuggeePid = iPid;
                        wxString msg;
                        msg << wxT(">> Debuggee process ID: ") << m_debuggeePid;
                        m_observer->UpdateAddLine(msg);

                        // Now there's a known pid, the debugger can be interrupted to let any to-be-disabled bps be
                        // disabled. So...
                        m_observer->DebuggerPidValid();
                    }
                }
            }
        }
    }
}
Exemplo n.º 2
0
void SvnConsole::OnReadProcessOutput(wxCommandEvent& event)
{
    ProcessEventData *ped = (ProcessEventData *)event.GetClientData();
    if (ped) {
        m_output.Append(ped->GetData().c_str());
    }

    wxString s (ped->GetData());
    s.MakeLower();

    if (m_currCmd.printProcessOutput)
        AppendText( ped->GetData() );
    
    static wxRegEx reUsername("username[ \t]*:", wxRE_DEFAULT|wxRE_ICASE);
    wxArrayString lines = wxStringTokenize(s, wxT("\n"), wxTOKEN_STRTOK);
    if( !lines.IsEmpty() && lines.Last().StartsWith(wxT("password for '")) ) {
        m_output.Clear();
        wxString pass = wxGetPasswordFromUser(ped->GetData(), wxT("Subversion"));
        if(!pass.IsEmpty() && m_process) {
            m_process->WriteToConsole(pass);
        }
    } else if ( !lines.IsEmpty() && reUsername.IsValid() && reUsername.Matches( lines.Last() ) ) {
        // Prompt the user for "Username:"******"Subversion");
        if ( !username.IsEmpty() && m_process ) {
            m_process->Write(username + "\n");
        }
    }
    delete ped;
}
Exemplo n.º 3
0
void CodeLiteApp::AdjustPathForCygwinIfNeeded()
{
#ifdef __WXMSW__
    CL_DEBUG("AdjustPathForCygwinIfNeeded called");
    if(!::clIsCygwinEnvironment()) {
        CL_DEBUG("Not running under Cygwin - nothing be done");
        return;
    }
    
    CL_SYSTEM("Cygwin environment detected");
    
    wxString cygwinRootDir;
    CompilerLocatorCygwin cygwin;
    if(cygwin.Locate()) {
        // this will return the base folder for cygwin (e.g. D:\cygwin)
        cygwinRootDir = (*cygwin.GetCompilers().begin())->GetInstallationPath();
    }

    // Running under Cygwin
    // Adjust the PATH environment variable
    wxString pathEnv;
    ::wxGetEnv("PATH", &pathEnv);

    // Always add the default paths
    wxArrayString paths;
    if(!cygwinRootDir.IsEmpty()) {
        CL_SYSTEM("Cygwin root folder is: %s", cygwinRootDir);
        wxFileName cygwinBinFolder(cygwinRootDir, "");
        cygwinBinFolder.AppendDir("bin");
        paths.Add(cygwinBinFolder.GetPath());
    }

    paths.Add("/usr/local/bin");
    paths.Add("/usr/bin");
    paths.Add("/usr/sbin");
    paths.Add("/bin");
    paths.Add("/sbin");

    // Append the paths from the environment variables
    wxArrayString userPaths = ::wxStringTokenize(pathEnv, ";", wxTOKEN_STRTOK);
    paths.insert(paths.end(), userPaths.begin(), userPaths.end());

    wxString fixedPath;
    for(size_t i = 0; i < paths.GetCount(); ++i) {
        wxString& curpath = paths.Item(i);
        static wxRegEx reCygdrive("/cygdrive/([A-Za-z])");
        if(reCygdrive.Matches(curpath)) {
            // Get the drive letter
            wxString volume = reCygdrive.GetMatch(curpath, 1);
            volume << ":";
            reCygdrive.Replace(&curpath, volume);
        }

        fixedPath << curpath << ";";
    }

    CL_DEBUG("Setting PATH environment variable to:\n%s", fixedPath);
    ::wxSetEnv("PATH", fixedPath);
#endif
}
Exemplo n.º 4
0
void MemoryView::OnUpdate(wxCommandEvent& e)
{
    static wxRegEx reHex(wxT("[0][x][0-9a-fA-F][0-9a-fA-F]"));

    // extract the text memory from the text control and pass it to the debugger
    wxString memory;
    wxArrayString lines = wxStringTokenize(m_textCtrlMemory->GetValue(), wxT("\n"), wxTOKEN_STRTOK);
    for (size_t i=0; i<lines.GetCount(); i++) {
        wxString line = lines.Item(i).AfterFirst(wxT(':')).BeforeFirst(wxT(':')).Trim().Trim(false);
        wxArrayString hexValues = wxStringTokenize(line, wxT(" "), wxTOKEN_STRTOK);
        for (size_t y=0; y<hexValues.GetCount(); y++) {
            wxString hex = hexValues.Item(y);
            if (reHex.Matches( hex ) && hex.Len() == 4) {
                // OK
                continue;
            } else {
                wxMessageBox(wxString::Format(_("Invalid memory value: %s"), hex), _("CodeLite"), wxICON_WARNING|wxOK);
                // update the pane to old value
                ManagerST::Get()->UpdateDebuggerPane();
                return;
            }
        }

        if (line.IsEmpty() == false) {
            memory << line << wxT(" ");
        }
    }

    // set the new memory
    memory = memory.Trim().Trim(false);
    ManagerST::Get()->SetMemory(m_textCtrlExpression->GetValue(), GetSize(), memory);

    // update the view
    ManagerST::Get()->UpdateDebuggerPane();
}
Exemplo n.º 5
0
double clClangFormatLocator::GetVersion(const wxString& clangFormat) const
{
    double double_version = 3.3;
#ifdef __WXGTK__
    //    Ubuntu clang-format version 3.5.0-4ubuntu2~trusty2 (tags/RELEASE_350/final) (based on LLVM 3.5.0) // Linux
    //    LLVM version 3.3 // Linux, old format
    //    clang-format version 3.6.0 (217570) // Windows
    double_version = 3.3;
    
    static wxRegEx reClangFormatVersion("version ([0-9]+\\.[0-9]+)");
    wxString command;
    command << clangFormat;
    ::WrapWithQuotes(command);
    command << " --version";
    wxString output = ProcUtils::SafeExecuteCommand(command);

    wxArrayString lines = ::wxStringTokenize(output, "\n", wxTOKEN_STRTOK);
    for(size_t i = 0; i < lines.GetCount(); ++i) {
        if(reClangFormatVersion.Matches(lines.Item(i))) {
            wxString version = reClangFormatVersion.GetMatch(lines.Item(i), 1);
            //wxLogMessage("clang-format version is %s", version);
            version.ToCDouble(&double_version);
            return double_version;
        }
    }
#elif defined(__WXMSW__)
    double_version = 3.6;
#else
    double_version = 3.5;
#endif
    return double_version; // Default
}
Exemplo n.º 6
0
wxString SvnLogHandler::Compact(const wxString& message)
{
    wxString compactMsg (message);
    compactMsg.Replace(wxT("\r\n"), wxT("\n"));
    compactMsg.Replace(wxT("\r"),   wxT("\n"));
    compactMsg.Replace(wxT("\v"),   wxT("\n"));
    wxArrayString lines = wxStringTokenize(compactMsg, wxT("\n"), wxTOKEN_STRTOK);
    compactMsg.Clear();
    for(size_t i=0; i<lines.GetCount(); i++) {
        wxString line = lines.Item(i);
        line.Trim().Trim(false);

        if(line.IsEmpty())
            continue;

        if(line.StartsWith(wxT("----------"))) {
            continue;
        }

        if(line == wxT("\"")) {
            continue;
        }
        static wxRegEx reRevisionPrefix(wxT("^(r[0-9]+)"));
        if(reRevisionPrefix.Matches(line)) {
            continue;
        }
        compactMsg << line << wxT("\n");
    }
    if(compactMsg.IsEmpty() == false) {
        compactMsg.RemoveLast();
    }
    return compactMsg;
}
Exemplo n.º 7
0
bool IsBusLabel( const wxString& aLabel )
{
    wxCHECK_MSG( busLabelRe.IsValid(), false,
                 wxT( "Invalid regular expression in IsBusLabel()." ) );

    return busLabelRe.Matches( aLabel );
}
Exemplo n.º 8
0
/**
 * Compare two references (e.g. "R100", "R19") and perform a 'natural' sort
 * This sorting must preserve numerical order rather than alphabetical
 * e.g. "R100" is lower (alphabetically) than "R19"
 * BUT should be placed after R19
 */
int BOM_TABLE_GROUP::SortReferences( const wxString& aFirst, const wxString& aSecond )
{
    // Default sorting
    int defaultSort = aFirst.Cmp( aSecond );

    static const wxString REGEX_STRING = "^([a-zA-Z]+)(\\d+)$";

    // Compile regex statically
    static wxRegEx regexFirst( REGEX_STRING, wxRE_ICASE | wxRE_ADVANCED );
    static wxRegEx regexSecond( REGEX_STRING, wxRE_ICASE | wxRE_ADVANCED );

    if( !regexFirst.Matches( aFirst ) || !regexSecond.Matches( aSecond ) )
    {
        return defaultSort;
    }

    // First priority is to order by prefix
    wxString prefixFirst  = regexFirst.GetMatch( aFirst, 1 );
    wxString prefixSecond = regexSecond.GetMatch( aSecond, 1 );

    if( prefixFirst.CmpNoCase( prefixSecond ) != 0 ) // Different prefixes!
    {
        return defaultSort;
    }

    wxString numStrFirst   = regexFirst.GetMatch( aFirst, 2 );
    wxString numStrSecond  = regexSecond.GetMatch( aSecond, 2 );

    // If either match failed, just return normal string comparison
    if( numStrFirst.IsEmpty() || numStrSecond.IsEmpty() )
    {
        return defaultSort;
    }

    // Convert each number string to an integer
    long numFirst    = 0;
    long numSecond   = 0;

    // If either conversion fails, return normal string comparison
    if( !numStrFirst.ToLong( &numFirst ) || !numStrSecond.ToLong( &numSecond ) )
    {
        return defaultSort;
    }

    return (int) (numFirst - numSecond);
}
Exemplo n.º 9
0
void clTernServer::OnTernOutput(clProcessEvent& event)
{
    static wxRegEx rePort("Listening on port ([0-9]+)");
    if(rePort.IsValid() && rePort.Matches(event.GetOutput())) {
        wxString strPort = rePort.GetMatch(event.GetOutput(), 1);
        strPort.ToCLong(&m_port);
    }
    PrintMessage(event.GetOutput());
}
Exemplo n.º 10
0
wxString CompilerLocatorCygwin::GetGCCVersion(const wxString& gccBinary)
{
    static wxRegEx reVersion("([0-9]+\\.[0-9]+\\.[0-9]+)");
    wxString command;
    command << gccBinary << " --version";
    wxString versionString = ProcUtils::SafeExecuteCommand(command);
    if ( !versionString.IsEmpty() && reVersion.Matches( versionString ) ) {
        return reVersion.GetMatch( versionString );
    }
    return wxEmptyString;
}
Exemplo n.º 11
0
void CppCheckReportPage::AppendLine(const wxString& line)
{
    wxString tmpLine(line);

    // Locate status messages:
    // 6/7 files checked 85% done
    static wxRegEx reProgress(wxT("([0-9]+)/([0-9]+)( files checked )([0-9]+%)( done)"));
    static wxRegEx reFileName(wxT("(Checking )([a-zA-Z:]{0,2}[ a-zA-Z\\.0-9_/\\+\\-]+ *)"));

    // Locate the progress messages and update our progress bar
    wxArrayString arrLines = wxStringTokenize(tmpLine, wxT("\n\r"), wxTOKEN_STRTOK);
    for(size_t i = 0; i < arrLines.GetCount(); i++) {

        if(reProgress.Matches(arrLines.Item(i))) {

            // Get the current progress
            wxString currentLine = reProgress.GetMatch(arrLines.Item(i), 1);

            long fileNo(0);
            currentLine.ToLong(&fileNo);
        }

        if(reFileName.Matches(arrLines.Item(i))) {

            // Get the file name
            wxString filename = reFileName.GetMatch(arrLines.Item(i), 2);
            m_mgr->SetStatusMessage("CppCheck: checking file " + filename);
        }
    }

    // Remove progress messages from the printed output
    reProgress.ReplaceAll(&tmpLine, wxEmptyString);
    tmpLine.Replace(wxT("\r"), wxT(""));
    tmpLine.Replace(wxT("\n\n"), wxT("\n"));

    m_stc->SetReadOnly(false);
    m_stc->AppendText(tmpLine);
    m_stc->SetReadOnly(true);

    m_stc->ScrollToLine(m_stc->GetLineCount() - 1);
}
Exemplo n.º 12
0
void OpenResourceDialog::GetLineNumberFromFilter(const wxString& filter, wxString& modFilter, long& lineNumber)
{
    modFilter = filter;
    lineNumber = -1;
    static wxRegEx reNumber(":([0-9]+)", wxRE_ADVANCED);
    if(reNumber.IsValid() && reNumber.Matches(modFilter)) {
        wxString strLineNumber;
        strLineNumber = reNumber.GetMatch(modFilter, 1);
        strLineNumber.ToCLong(&lineNumber);
        reNumber.Replace(&modFilter, "");
    }
}
Exemplo n.º 13
0
void DisassemblyTextCtrl::OnDclick(wxMouseEvent& event)
{

        if(GetStatus())
        {
            SetStatus(0);
           PluginsArray plugins = Manager::Get()->GetPluginManager()->GetDebuggerOffers();
            if (plugins.GetCount())
            {
                cbDebuggerPlugin* dbg = (cbDebuggerPlugin*)plugins[0];
                if (dbg)
                {
                    // is the debugger running?
                    if (dbg->IsRunning())
                    {
                        dbg->StepByStep();
                    }
                }
            }
        }
        int LineNum = GetCurrentLine();
        int L2 = GetCurrentLine();
        wxString LineText,SourceFile;
       unsigned long SourceLine=0;

        while(LineNum > 0)
        {
            LineText = GetLine(LineNum--);
            if(reRelativePath.Matches(LineText))
            break;
        }

        if(LineText.IsEmpty())
        return ;

        LineText.AfterLast(_T(':')).ToULong(&SourceLine,10);
        SourceFile = Manager::Get()->GetProjectManager()->GetActiveProject()->GetBasePath();
        SourceFile  <<  LineText.Before(_T(':'));



        SyncEditor(LineText.Before(_T(':')),SourceLine,true);

        SetReadOnly(false);
        MarkerDeleteAll(DEBUG_MARKER);
        MarkerAdd(SourceLine,DEBUG_MARKER);


        SetReadOnly(true);
    //wxMessageBox(wxString::Format(_T("%s:%d"),SourceFile.c_str(),SourceLine));
     event.Skip();

}
Exemplo n.º 14
0
Falcon::Falcon(const std::string& ip)
{
	_ip = ip;

    _http.SetMethod("GET");
	_connected = _http.Connect(_ip);

    if (_connected)
    {
        std::string versionxml = GetURL("/status.xml");
        std::string version = GetURL("/index.htm");
        if (versionxml != "")
        {
            static wxRegEx versionregex("(\\<v\\>)([0-9]+\\.[0-9]+)\\<\\/v\\>", wxRE_ADVANCED | wxRE_NEWLINE);
            if (versionregex.Matches(wxString(versionxml)))
            {
                _version = versionregex.GetMatch(wxString(versionxml), 2).ToStdString();
            }
        }
        else
        {
            //<title>F4V2            - v1.10</title>
            static wxRegEx versionregex("(title.*?v)([0-9]+\\.[0-9]+)\\<\\/title\\>", wxRE_ADVANCED | wxRE_NEWLINE);
            if (versionregex.Matches(wxString(version)))
            {
                _version = versionregex.GetMatch(wxString(version), 2).ToStdString();
            }
        }
        static wxRegEx modelregex("(SW Version:.*?\\>)(F[0-9]+V[0-9]+)", wxRE_ADVANCED);
        if (modelregex.Matches(wxString(version)))
        {
            _model = modelregex.GetMatch(wxString(version), 2).ToStdString();
        }
    }
    else
    {
        static log4cpp::Category &logger_base = log4cpp::Category::getInstance(std::string("log_base"));
        logger_base.error("Error connecting to falcon controller on %s.", (const char *)_ip.c_str());
    }
}
Exemplo n.º 15
0
void CMP_LIBRARY::SearchEntryNames( wxArrayString& aNames, const wxRegEx& aRe, bool aSort )
{
    if( !aRe.IsValid() )
        return;

    LIB_ALIAS_MAP::iterator it;

    for( it=aliases.begin();  it!=aliases.end();  it++ )
    {
        if( aRe.Matches( (*it).second->GetKeyWords() ) )
            aNames.Add( (*it).first );
    }

    if( aSort )
        aNames.Sort();
}
bool PHPEditorContextMenu::IsIncludeOrRequireStatement(wxString& includeWhat)
{
    // Do a basic check to see whether this line is include statement or not.
    // Don't bother in full parsing the file since it can be a quite an expensive operation
    // (include|require_once|require|include_once)[ \t\\(]*(.*?)[\\) \t)]*;
    static wxRegEx reInclude(wxT("(include|require_once|require|include_once)[ \t\\(]*(.*?)[\\) \t]*;"), wxRE_ADVANCED);

    IEditor* editor = m_manager->GetActiveEditor();
    if(!editor) return false;

    wxString line = editor->GetCtrl()->GetLine(editor->GetCurrentLine());
    if(reInclude.IsValid() && reInclude.Matches(line)) {
        includeWhat = reInclude.GetMatch(line, 2);
        return true;
    }
    return false;
}
Exemplo n.º 17
0
wxString Compiler::GetGCCVersion() const
{
    // Get the compiler version
    static wxRegEx reVersion("([0-9]+\\.[0-9]+\\.[0-9]+)");
    wxString command;
    command << GetTool("CXX") << " --version";
    wxArrayString out;
    ProcUtils::SafeExecuteCommand(command, out);
    if(out.IsEmpty()) {
        return "";
    }

    if(reVersion.Matches(out.Item(0))) {
        return reVersion.GetMatch(out.Item(0));
    }
    return "";
}
Exemplo n.º 18
0
// When a a breakpoint is hit, see if it's got a command-list that needs faking
void BreakptMgr::BreakpointHit(int id)
{
    int index = FindBreakpointById(id, m_bps);
    if ((index == wxNOT_FOUND) || (index >= FIRST_INTERNAL_ID)) {
        return;
    }

    BreakpointInfo bp = m_bps.at(index);
    if (! bp.commandlist.IsEmpty()) {
        IDebugger *dbgr = DebuggerMgr::Get().GetActiveDebugger();
        if (dbgr && dbgr->IsRunning()) {
            // A likely command, presumably at the end of the command-list, is 'continue' or 'cont'
            // Filter this out and do it separately, otherwise Manager::UpdateLostControl isn't called to blank the indicator
            static wxRegEx reContinue(wxT("(([[:space:]]|(^))((cont$)|(continue)))"));
            bool needsCont = false;
            wxString commands = bp.commandlist;
            if (reContinue.IsValid() && reContinue.Matches(commands)) {
                size_t start, len;
                if (reContinue.GetMatch(&start,&len)) {
                    commands = commands.Left(start);
                    needsCont = true;
                }
            }
            if (! commands.IsEmpty()) {	// Just in case someone's _only_ command is 'continue' !
                dbgr->ExecuteCmd(commands);
            }
            if (needsCont) {
                dbgr->Continue();
            }
        }
    }

    if (bp.bp_type == BP_type_tempbreak) {
        // If this is a temporary bp, remove it from m_bps now it's been hit
        // Otherwise it will be treated as a 'Pending' bp, the button will be displayed
        // and, if clicked, the bp will be resurrected.
        int index = FindBreakpointById(id, m_bps);
        if (index != wxNOT_FOUND) {
            m_bps.erase(m_bps.begin()+index);
        }

    }
}
Exemplo n.º 19
0
void CppCheckReportPage::PrintStatusMessage()
{
    wxString statusLine;
    sErrorCount = 0;
    wxString text = m_stc->GetText();
    wxArrayString lines = ::wxStringTokenize(text, "\n", wxTOKEN_RET_EMPTY_ALL);
    static wxRegEx gccPattern(wxT("^([^ ][a-zA-Z:]{0,2}[ a-zA-Z\\.0-9_/\\+\\-]+ *)(:)([0-9]*)(:)([a-zA-Z ]*)"));
    for(size_t i = 0; i < lines.GetCount(); ++i) {
        if(gccPattern.Matches(lines.Item(i))) {
            m_stc->MarkerAdd(i, CPPCHECK_ERROR_MARKER);
            ++sErrorCount;
        }
    }

    statusLine << wxT("===== ");
    statusLine << _("cppcheck analysis ended. Found ") << sErrorCount << _(" possible errors");
    statusLine << wxT("=====");

    AppendLine(statusLine);
    SetMessage(_("Done"));
}
Exemplo n.º 20
0
void CppCheckReportPage::DoOpenLine(int outputLine)
{
    static wxRegEx gccPattern(wxT("^([^ ][a-zA-Z:]{0,2}[ a-zA-Z\\.0-9_/\\+\\-]+ *)(:)([0-9]*)(:)([a-zA-Z ]*)"));
    static int fileIndex = 1;
    static int lineIndex = 3;

    wxString txt = m_stc->GetLine(outputLine);

    if(gccPattern.Matches(txt)) {
        wxString file = gccPattern.GetMatch(txt, fileIndex);
        wxString lineNumber = gccPattern.GetMatch(txt, lineIndex);

        if(file.IsEmpty() == false) {
            long n(0);
            lineNumber.ToCLong(&n);

            // Zero based line number
            if(n) n--;
            m_mgr->OpenFile(file, wxEmptyString, n);
        }
    }
}
Exemplo n.º 21
0
inline int DetectRepeatingSymbols(wxString const &str, int pos)
{
    int newPos = -1, currPos = pos;
    while (1)
    {
        if (currPos + 4 >= static_cast<int>(str.length()))
            break;
        if (str[currPos + 1] != wxT(','))
            break;
        if (str[currPos + 3] == wxT('\''))
        {
            const wxString &s = str.substr(currPos + 3, str.length() - (currPos + 3));
            if (regexRepeatedChars.Matches(s))
            {
                size_t start, length;
                regexRepeatedChars.GetMatch(&start, &length, 0);
                newPos = currPos + 3 + length;
                if ((newPos + 4 < static_cast<int>(str.length()))
                    && str[newPos] == wxT(',') && str[newPos + 2] == wxT('"'))
                {
                    newPos += 3;
                    while (newPos < static_cast<int>(str.length()) && str[newPos] != wxT('"'))
                        ++newPos;
                    if (newPos + 1 < static_cast<int>(str.length()) && str[newPos] == wxT('"'))
                        ++newPos;
                }
                currPos = newPos;
            }
            else
                break;
        }
        else
            break;

        // move the current position to point at the '"' character
        currPos--;
    }
    return newPos;
}
Exemplo n.º 22
0
IDbType* MySqlDbAdapter::parseTypeString(const wxString& typeString)
{
	static wxRegEx reType(wxT("([a-zA-Z]+)(\\([0-9]+\\))?"));
	IDbType* type(NULL);
	if(reType.Matches(typeString)) {
		wxString typeName = reType.GetMatch(typeString, 1);
		wxString strSize  = reType.GetMatch(typeString, 2);
		typeName.MakeUpper();
		
		type = this->GetDbTypeByName(typeName);
		if(type) {
			strSize.Trim().Trim(false);
			if(strSize.StartsWith(wxT("("))) { strSize.Remove(0, 1); }
			if(strSize.EndsWith(wxT(")")))   { strSize.RemoveLast(); }
			
			long size = 0;
			if(strSize.ToLong(&size)){
				type->SetSize(size);
			}
		}
	}
	return type;
}
Exemplo n.º 23
0
const wxExLexer wxExLexers::FindByText(const wxString& text) const
{
  // Add automatic lexers if text starts with some special tokens.
  const wxString text_lowercase = text.Lower();

  if (text_lowercase.StartsWith("<html>"))
  {
    return FindByName("hypertext");
  }
  else if (text_lowercase.StartsWith("<?xml"))
  {
    return FindByName("xml");
  }
  // cpp files like #include <map> really do not have a .h extension 
  // (e.g. /usr/include/c++/3.3.5/map) so add here.
  else if (text_lowercase.StartsWith("//"))
  {
    return FindByName("cpp");
  }
  else if (text_lowercase.StartsWith("<?php"))
  {
    return FindByName("phpscript");
  }
  else
  {
    // If there is a Shell Language Indicator,
    // match with bash.
    const wxRegEx re("#!.*/bin/.*");
    
    if (re.Matches(text_lowercase))
    {
      return FindByName("bash");
    }
  }

  return wxExLexer();
}
Exemplo n.º 24
0
void CPasswordSubset::OnChar( wxKeyEvent& event )
{
  static wxRegEx charSet("[[:digit:]]|[[:space:]]|,|-|;");
  static wxRegEx seps(",|;");

  wxASSERT(charSet.IsValid() && seps.IsValid());

  wxChar uc = event.GetUnicodeKey();
  if (uc != WXK_NONE) {
    const int N = m_password.length();
    if (charSet.Matches(wxString(uc, 1))) {
      event.Skip(true); // accept
      // Check against valid pos regexp and update vals accordingly
      wxString pos_str = m_pos->GetLineText(0);
      pos_str += uc; // since accepted char will only be added to control later
      // could have used xwStringTokenizer in following, but this way we also convert to int
      // and catch bad usage of '-'
      seps.Replace(&pos_str, wxT(" ")); // replace ';' and ',' with ' ' for stream tokenizing
      m_vals->Clear();
      m_error->SetLabel(wxEmptyString);
      
      std::wistringstream is(pos_str.wc_str());
      int pos;
      while (is >> pos) {
	if (pos > 0 && pos <= N)
	  *m_vals << m_password[pos - 1] << wxT(" ");
	else if (pos < 0 && pos >= -N)
	  *m_vals << m_password[N + pos] << wxT(" ");
	else {
	  m_error->SetLabel(_("Invalid position"));
	}
      }
      if (!is.eof()) {
	m_error->SetLabel(_("Invalid position"));
      }
    } else {
      if (uc == WXK_BACK)
Exemplo n.º 25
0
void AddIncludeFileDlg::OnButtonOK(wxCommandEvent &e)
{
    wxUnusedVar(e);
    //get the include file to add
    wxString fullpath = m_textCtrlFullPath->GetValue();
    static wxRegEx reIncludeFile(wxT("include *[\\\"\\<]{1}([a-zA-Z0-9_/\\.]*)"));
    wxString relativePath;

    if (reIncludeFile.Matches(m_textCtrlLineToAdd->GetValue())) {
        relativePath = reIncludeFile.GetMatch(m_textCtrlLineToAdd->GetValue(), 1);
    }

    fullpath.Replace(wxT("\\"), wxT("/"));
    relativePath.Replace(wxT("\\"), wxT("/"));
    wxFileName fn(fullpath);

    wxString inclPath;
    if (fullpath.EndsWith(relativePath, &inclPath) &&
        fullpath != relativePath &&	//dont save the '.' path this is done by default
        fn.GetFullName() != relativePath) { //if the relative path is only file name, nothing to cache
        m_includePath.Add(inclPath);
    }
    EndModal(wxID_OK);
}
Exemplo n.º 26
0
void EnvVarsTableDlg::OnExport(wxCommandEvent& event)
{
    int selection = m_notebook1->GetSelection();
    if(selection == wxNOT_FOUND)
        return;

#ifdef __WXMSW__
    bool isWindows = true;
#else
    bool isWindows = false;
#endif

    wxString text;
    if(selection == 0) {
        text = m_textCtrlDefault->GetText();
    } else {
        EnvVarSetPage* page = dynamic_cast<EnvVarSetPage*>(m_notebook1->GetPage((size_t)selection));
        if(page) {
            text = page->m_textCtrl->GetText();
        }
    }

    if(text.IsEmpty())
        return;

    wxArrayString lines = wxStringTokenize(text, wxT("\r\n"), wxTOKEN_STRTOK);
    wxString envfile;
    if(isWindows) {
        envfile << wxT("environment.bat");
    } else {
        envfile << wxT("environment");
    }

    wxFileName fn(wxGetCwd(), envfile);
    wxFFile fp(fn.GetFullPath(), wxT("w+b"));
    if(fp.IsOpened() == false) {
        wxMessageBox(wxString::Format(_("Failed to open file: '%s' for write"), fn.GetFullPath().c_str()),
                     wxT("CodeLite"),
                     wxOK | wxCENTER | wxICON_WARNING);
        return;
    }

    for(size_t i = 0; i < lines.GetCount(); i++) {

        wxString sLine = lines.Item(i).Trim().Trim(false);
        if(sLine.IsEmpty())
            continue;

        static wxRegEx reVarPattern(wxT("\\$\\(( *)([a-zA-Z0-9_]+)( *)\\)"));
        if(isWindows) {
            while(reVarPattern.Matches(sLine)) {
                wxString varName = reVarPattern.GetMatch(sLine, 2);
                wxString text = reVarPattern.GetMatch(sLine);
                sLine.Replace(text, wxString::Format(wxT("%%%s%%"), varName.c_str()));
            }
            sLine.Prepend(wxT("set "));
            sLine.Append(wxT("\r\n"));

        } else {
            while(reVarPattern.Matches(sLine)) {
                wxString varName = reVarPattern.GetMatch(sLine, 2);
                wxString text = reVarPattern.GetMatch(sLine);
                sLine.Replace(text, wxString::Format(wxT("$%s"), varName.c_str()));
            }
            sLine.Prepend(wxT("export "));
            sLine.Append(wxT("\n"));
        }
        fp.Write(sLine);
    }

    wxMessageBox(wxString::Format(_("Environment exported to: '%s' successfully"), fn.GetFullPath().c_str()),
                 wxT("CodeLite"));
}
Exemplo n.º 27
0
wxString TagEntry::FormatComment()
{
    if(m_isCommentForamtted) return m_formattedComment;
    m_isCommentForamtted = true;
    m_formattedComment.Clear();
    
    // Send the plugins an event requesting tooltip for this tag
    if(IsMethod()) {

        if(IsConstructor())
            m_formattedComment << wxT("<b>[Constructor]</b>\n");

        else if(IsDestructor())
            m_formattedComment << wxT("<b>[Destructor]</b>\n");

        TagEntryPtr p(new TagEntry(*this));
        m_formattedComment << wxT("<code>")
               << TagsManagerST::Get()->FormatFunction(p, FunctionFormat_WithVirtual | FunctionFormat_Arg_Per_Line)
               << wxT("</code>\n");
        m_formattedComment.Replace(GetName(), wxT("<b>") + GetName() + wxT("</b>"));
    } else if(IsClass()) {

        m_formattedComment << wxT("<b>Kind:</b> ");
        m_formattedComment << GetKind() << "\n";

        if(GetInheritsAsString().IsEmpty() == false) {
            m_formattedComment << wxT("<b>Inherits:</b> ");
            m_formattedComment << GetInheritsAsString() << wxT("\n");
        }

    } else if(IsMacro() || IsTypedef() || IsContainer() || GetKind() == wxT("member") ||
              GetKind() == wxT("variable")) {

        m_formattedComment << wxT("<b>Kind:</b> ");
        m_formattedComment << GetKind() << "\n";

        m_formattedComment << wxT("<b>Match Pattern:</b> ");

        // Prettify the match pattern
        wxString matchPattern(GetPattern());
        matchPattern.Trim().Trim(false);

        if(matchPattern.StartsWith(wxT("/^"))) {
            matchPattern.Replace(wxT("/^"), wxT(""));
        }

        if(matchPattern.EndsWith(wxT("$/"))) {
            matchPattern.Replace(wxT("$/"), wxT(""));
        }

        matchPattern.Replace(wxT("\t"), wxT(" "));
        while(matchPattern.Replace(wxT("  "), wxT(" "))) {
        }

        matchPattern.Trim().Trim(false);

        // BUG#3082954: limit the size of the 'match pattern' to a reasonable size (200 chars)
        matchPattern = TagsManagerST::Get()->WrapLines(matchPattern);
        matchPattern.Replace(GetName(), wxT("<b>") + GetName() + wxT("</b>"));
        m_formattedComment << wxT("<code>") << matchPattern << wxT("</code>\n");

    }

    // Add comment section
    wxString tagComment;
    if(!GetFile().IsEmpty()) {
        
        CommentParseResult comments;
        ::ParseComments(GetFile().mb_str(wxConvUTF8).data(), comments);
    
        // search for comment in the current line, the line above it and 2 above it
        // use the first match we got
        for(size_t i = 0; i < 3; i++) {
            wxString comment = comments.getCommentForLine(GetLine()-i);
            if(!comment.IsEmpty()) {
                SetComment(comment);
                break;
            }
        }
    }
    
    if(!GetComment().IsEmpty()) {
        wxString theComment;
        theComment = GetComment();

        theComment = TagsManagerST::Get()->WrapLines(theComment);
        theComment.Trim(false);
        wxString tagComment = wxString::Format(wxT("%s\n"), theComment.c_str());
        if(m_formattedComment.IsEmpty() == false) {
            m_formattedComment.Trim().Trim(false);
            m_formattedComment << wxT("\n<hr>");
        }
        m_formattedComment << tagComment;
    }

    // Update all "doxy" comments and surround them with <green> tags
    static wxRegEx reDoxyParam("([@\\\\]{1}param)[ \t]+([_a-z][a-z0-9_]*)?", wxRE_DEFAULT | wxRE_ICASE);
    static wxRegEx reDoxyBrief("([@\\\\]{1}(brief|details))[ \t]*", wxRE_DEFAULT | wxRE_ICASE);
    static wxRegEx reDoxyThrow("([@\\\\]{1}(throw|throws))[ \t]*", wxRE_DEFAULT | wxRE_ICASE);
    static wxRegEx reDoxyReturn("([@\\\\]{1}(return|retval|returns))[ \t]*", wxRE_DEFAULT | wxRE_ICASE);
    static wxRegEx reDoxyToDo("([@\\\\]{1}todo)[ \t]*", wxRE_DEFAULT | wxRE_ICASE);
    static wxRegEx reDoxyRemark("([@\\\\]{1}(remarks|remark))[ \t]*", wxRE_DEFAULT | wxRE_ICASE);
    static wxRegEx reDate("([@\\\\]{1}date)[ \t]*", wxRE_DEFAULT | wxRE_ICASE);
    static wxRegEx reFN("([@\\\\]{1}fn)[ \t]*", wxRE_DEFAULT | wxRE_ICASE);

    if(reDoxyParam.IsValid() && reDoxyParam.Matches(m_formattedComment)) {
        reDoxyParam.ReplaceAll(&m_formattedComment, "\n<b>Parameter</b>\n<i>\\2</i>");
    }

    if(reDoxyBrief.IsValid() && reDoxyBrief.Matches(m_formattedComment)) {
        reDoxyBrief.ReplaceAll(&m_formattedComment, "");
    }

    if(reDoxyThrow.IsValid() && reDoxyThrow.Matches(m_formattedComment)) {
        reDoxyThrow.ReplaceAll(&m_formattedComment, "\n<b>Throws</b>\n");
    }

    if(reDoxyReturn.IsValid() && reDoxyReturn.Matches(m_formattedComment)) {
        reDoxyReturn.ReplaceAll(&m_formattedComment, "\n<b>Returns</b>\n");
    }

    if(reDoxyToDo.IsValid() && reDoxyToDo.Matches(m_formattedComment)) {
        reDoxyToDo.ReplaceAll(&m_formattedComment, "\n<b>TODO</b>\n");
    }

    if(reDoxyRemark.IsValid() && reDoxyRemark.Matches(m_formattedComment)) {
        reDoxyRemark.ReplaceAll(&m_formattedComment, "\n  ");
    }

    if(reDate.IsValid() && reDate.Matches(m_formattedComment)) {
        reDate.ReplaceAll(&m_formattedComment, "<b>Date</b> ");
    }

    if(reFN.IsValid() && reFN.Matches(m_formattedComment)) {
        size_t fnStart, fnLen, fnEnd;
        if(reFN.GetMatch(&fnStart, &fnLen)) {
            fnEnd = m_formattedComment.find('\n', fnStart);
            if(fnEnd != wxString::npos) {
                // remove the string from fnStart -> fnEnd (including ther terminating \n)
                m_formattedComment.Remove(fnStart, (fnEnd - fnStart) + 1);
            }
        }
    }

    // if nothing to display skip this
    m_formattedComment.Trim().Trim(false);
    return m_formattedComment;
}
Exemplo n.º 28
0
/* ParseTreeNode::parse
 * Parses formatted text data. Current valid formatting is:
 * (type) child = value;
 * (type) child = value1, value2, ...;
 * (type) child = { value1, value2, ... }
 * (type) child { grandchild = value; etc... }
 * (type) child : inherited { ... }
 * All values are read as strings, but can be retrieved as string,
 * int, bool or float.
 *******************************************************************/
bool ParseTreeNode::parse(Tokenizer& tz)
{
    // Get first token
    string token = tz.getToken();

    // Keep parsing until final } is reached (or end of file)
    while (!(S_CMP(token, "}")) && !token.IsEmpty())
    {
        // Check for preprocessor stuff
        if (parser)
        {
            // #define
            if (S_CMPNOCASE(token, "#define"))
            {
                parser->define(tz.getToken());
                token = tz.getToken();
                continue;
            }

            // #if(n)def
            if (S_CMPNOCASE(token, "#ifdef") || S_CMPNOCASE(token, "#ifndef"))
            {
                bool test = true;
                if (S_CMPNOCASE(token, "#ifndef"))
                    test = false;
                string define = tz.getToken();
                if (parser->defined(define) == test)
                {
                    // Continue
                    token = tz.getToken();
                    continue;
                }
                else
                {
                    // Skip section
                    int skip = 0;
                    while (true)
                    {
                        token = tz.getToken();
                        if (S_CMPNOCASE(token, "#endif"))
                            skip--;
                        else if (S_CMPNOCASE(token, "#ifdef"))
                            skip++;
                        else if (S_CMPNOCASE(token, "#ifndef"))
                            skip++;

                        if (skip < 0)
                            break;
                        if (token.IsEmpty())
                        {
                            wxLogMessage("Error: found end of file within #if(n)def block");
                            break;
                        }
                    }

                    continue;
                }
            }

            // #include (ignore)
            if (S_CMPNOCASE(token, "#include"))
            {
                tz.skipToken();	// Skip include path
                token = tz.getToken();
                continue;
            }

            // #endif (ignore)
            if (S_CMPNOCASE(token, "#endif"))
            {
                token = tz.getToken();
                continue;
            }
        }

        // If it's a special character (ie not a valid name), parsing fails
        if (tz.isSpecialCharacter(token.at(0)))
        {
            wxLogMessage("Parsing error: Unexpected special character '%s' in %s (line %d)", CHR(token), CHR(tz.getName()), tz.lineNo());
            return false;
        }

        // So we have either a node or property name
        string name = token;

        // Check next token to determine what we're doing
        string next = tz.peekToken();

        // Check for type+name pair
        string type = "";
        if (next != "=" && next != "{" && next != ";" && next != ":")
        {
            type = name;
            name = tz.getToken();
            next = tz.peekToken();
        }

        // Assignment
        if (S_CMP(next, "="))
        {
            // Skip =
            tz.skipToken();

            // Create item node
            ParseTreeNode* child = (ParseTreeNode*)addChild(name);
            child->type = type;

            // Check type of assignment list
            token = tz.getToken();
            string list_end = ";";
            if (token == "{")
            {
                list_end = "}";
                token = tz.getToken();
            }

            // Parse until ; or }
            while (1)
            {
                // Check for list end
                if (S_CMP(token, list_end) && !tz.quotedString())
                    break;

                // Setup value
                Property value;

                // Detect value type
                if (tz.quotedString())					// Quoted string
                    value = token;
                else if (S_CMPNOCASE(token, "true"))	// Boolean (true)
                    value = true;
                else if (S_CMPNOCASE(token, "false"))	// Boolean (false)
                    value = false;
                else if (re_int1.Matches(token) ||		// Integer
                         re_int2.Matches(token))
                {
                    long val;
                    token.ToLong(&val);
                    value = (int)val;
                }
                else if (re_int3.Matches(token))  		// Hex (0xXXXXXX)
                {
                    long val;
                    token.ToLong(&val, 0);
                    value = (int)val;
                    //wxLogMessage("%s: %s is hex %d", CHR(name), CHR(token), value.getIntValue());
                }
                else if (re_float.Matches(token))  		// Floating point
                {
                    double val;
                    token.ToDouble(&val);
                    value = (double)val;
                    //LOG_MESSAGE(3, S_FMT("%s: %s is float %1.3f", CHR(name), CHR(token), val));
                }
                else									// Unknown, just treat as string
                    value = token;

                // Add value
                child->values.push_back(value);

                // Check for ,
                if (S_CMP(tz.peekToken(), ","))
                    tz.skipToken();	// Skip it
                else if (!(S_CMP(tz.peekToken(), list_end)))
                {
                    string t = tz.getToken();
                    string n = tz.getName();
                    wxLogMessage("Parsing error: Expected \",\" or \"%s\", got \"%s\" in %s (line %d)", CHR(list_end), CHR(t), CHR(n), tz.lineNo());
                    return false;
                }

                token = tz.getToken();
            }
        }

        // Child node
        else if (S_CMP(next, "{"))
        {
            // Add child node
            ParseTreeNode* child = (ParseTreeNode*)addChild(name);
            child->type = type;

            // Skip {
            tz.skipToken();

            // Parse child node
            if (!child->parse(tz))
                return false;
        }

        // Child node (with no values/children)
        else if (S_CMP(next, ";"))
        {
            // Add child node
            ParseTreeNode* child = (ParseTreeNode*)addChild(name);
            child->type = type;

            // Skip ;
            tz.skipToken();
        }

        // Child node + inheritance
        else if (S_CMP(next, ":"))
        {
            // Skip :
            tz.skipToken();

            // Read inherited name
            string inherit = tz.getToken();

            // Check for opening brace
            if (tz.checkToken("{"))
            {
                // Add child node
                ParseTreeNode* child = (ParseTreeNode*)addChild(name);
                child->type = type;

                // Set its inheritance
                child->inherit = inherit;

                // Parse child node
                if (!child->parse(tz))
                    return false;
            }
        }

        // Unexpected token
        else
        {
            wxLogMessage("Parsing error: \"%s\" unexpected in %s (line %d)", CHR(next), CHR(tz.getName()), tz.lineNo());
            return false;
        }

        // Continue parsing
        token = tz.getToken();
    }

    return true;
}
Exemplo n.º 29
0
void SmartIndentCpp::DoBraceCompletion(cbStyledTextCtrl* control, const wxChar& ch)const
{
    int pos = control->GetCurrentPos();
    int style = control->GetStyleAt(pos);

    // match preprocessor commands
    if ( (ch == _T('\n')) || ( (control->GetEOLMode() == wxSCI_EOL_CR) && (ch == _T('\r')) ) )
    {
        wxRegEx ppIf(wxT("^[ \t]*#[ \t]*if"));
        wxRegEx ppElse(wxT("^[ \t]*#[ \t]*el"));
        wxRegEx ppEnd(wxT("^[ \t]*#[ \t]*endif"));
        wxRegEx pp(wxT("^([ \t]*#[ \t]*)[a-z]*([ \t]+([a-zA-Z0-9_]+)|())")); // generic match to extract parts
        const int ppLine = control->GetCurrentLine() - 1;
        if (ppIf.Matches(control->GetLine(ppLine)) || ppElse.Matches(control->GetLine(ppLine)))
        {
            int depth = 1;
            for (int i = ppLine + 1; i < control->GetLineCount(); ++i)
            {
                if (control->GetLine(i).Find(wxT('#')) != wxNOT_FOUND) // limit testing due to performance cost
                {
                    if (ppIf.Matches(control->GetLine(i))) // ignore else's, elif's, ...
                        ++depth;
                    else if (ppEnd.Matches(control->GetLine(i)))
                        --depth;
                }
                if (depth == 0)
                    break;
            }
            if (depth > 0)
            {
                wxString endIf = wxT("endif");
                if (pp.Matches(control->GetLine(ppLine)))
                {
                    endIf.Prepend(pp.GetMatch(control->GetLine(ppLine), 1));
                    if (!pp.GetMatch(control->GetLine(ppLine), 3).IsEmpty())
                        endIf.Append(wxT(" // ") + pp.GetMatch(control->GetLine(ppLine), 3));
                }
                else
                    endIf.Prepend(wxT("#"));
                control->InsertText(pos, GetEOLStr(control->GetEOLMode()) + endIf);
                return;
            }
        }
    }

    if ( control->IsComment(style) || control->IsPreprocessor(style) )
        return;
    if (ch == _T('\'') || ch == _T('"'))
    {
        if (   (control->GetCharAt(pos) == ch)
            && (control->GetCharAt(pos - 2) != _T('\\')) )
        {
            control->DeleteBack();
            control->GotoPos(pos);
        }
        else
        {
            const wxChar left = control->GetCharAt(pos - 2);
            const wxChar right = control->GetCharAt(pos);
            if (   control->IsCharacter(style)
                || control->IsString(style)
                || left == _T('\\')
                || (   (left > _T(' '))
                    && (left != _T('('))
                    && (left != _T('=')) )
                || (   (right > _T(' '))
                    && (right != _T(')')) ) )
            {
                return;
            }
            control->AddText(ch);
            control->GotoPos(pos);
        }
        return;
    }
    if ( control->IsCharacter(style) || control->IsString(style) )
        return;
    const wxString leftBrace(_T("([{"));
    const wxString rightBrace(_T(")]}"));
    int index = leftBrace.Find(ch);
    const wxString unWant(_T(");\n\r\t\b "));
    const wxChar nextChar = control->GetCharAt(pos);
    #if wxCHECK_VERSION(2, 9, 0)
    if ((index != wxNOT_FOUND) && ((unWant.Find(wxUniChar(nextChar)) != wxNOT_FOUND) || (pos == control->GetLength())))
    #else
    if ((index != wxNOT_FOUND) && ((unWant.Find(nextChar) != wxNOT_FOUND) || (pos == control->GetLength())))
    #endif
    {
        control->AddText(rightBrace.GetChar(index));
        control->GotoPos(pos);
        if (ch == _T('{'))
        {
            const int curLine = control->GetCurrentLine();
            int keyLine = curLine;
            wxString text;
            do
            {
                int keyPos = control->GetLineIndentPosition(keyLine);
                int start = control->WordStartPosition(keyPos, true);
                int end = control->WordEndPosition(keyPos, true);
                text = control->GetTextRange(start, end);
            }
            while (   (text.IsEmpty() || text == _T("public") || text == _T("protected") || text == _T("private"))
                   && (text != _T("namespace"))
                   && (--keyLine >= 0) );

            if (text == _T("class") || text == _T("struct") || text == _T("enum") || text == _T("union"))
                control->InsertText(control->GetLineEndPosition(curLine), _T(";"));

            const wxRegEx reg(_T("^[ \t]*{}[ \t]*"));
            if (reg.Matches(control->GetCurLine()))
            {
                control->NewLine();
                control->GotoPos(pos);
                control->NewLine();
                return;
            }
        }
    }
    else
    {
        index = rightBrace.Find(ch);
        if (index != wxNOT_FOUND)
        {
            if (control->GetCharAt(pos) == ch)
            {
                control->DeleteBack();
                control->GotoPos(pos);
                return;
            }
        }
    }
}
Exemplo n.º 30
0
LEditor* MainBook::OpenFile(const wxString& file_name,
    const wxString& projectName,
    int lineno,
    long position,
    OF_extra extra /*=OF_AddJump*/,
    bool preserveSelection /*=true*/)
{
    wxFileName fileName(file_name);
    fileName.MakeAbsolute();

#ifdef __WXMSW__
    // Handle cygwin paths
    wxString curpath = fileName.GetFullPath();
    static wxRegEx reCygdrive("/cygdrive/([A-Za-z])");
    if(reCygdrive.Matches(curpath)) {
        // Replace the /cygdrive/c with volume C:
        wxString volume = reCygdrive.GetMatch(curpath, 1);
        volume << ":";
        reCygdrive.Replace(&curpath, volume);
        fileName = curpath;
    }
#endif

    if(!IsFileExists(fileName)) {
        wxLogMessage(wxT("Failed to open: %s: No such file or directory"), fileName.GetFullPath().c_str());
        return NULL;
    }

    if(FileExtManager::GetType(fileName.GetFullName()) == FileExtManager::TypeBmp) {
        // a bitmap file, open it using an image viewer
        DoOpenImageViewer(fileName);
        return NULL;
    }

    wxString projName = projectName;
    if(projName.IsEmpty()) {
        // try to match a project name to the file. otherwise, CC may not work
        projName = ManagerST::Get()->GetProjectNameByFile(fileName.GetFullPath());
    }

    LEditor* editor = GetActiveEditor(true);
    BrowseRecord jumpfrom = editor ? editor->CreateBrowseRecord() : BrowseRecord();

    editor = FindEditor(fileName.GetFullPath());
    if(editor) {
        editor->SetProject(projName);
    } else if(fileName.IsOk() == false) {
        wxLogMessage(wxT("Invalid file name: ") + fileName.GetFullPath());
        return NULL;

    } else if(!fileName.FileExists()) {
        wxLogMessage(wxT("File: ") + fileName.GetFullPath() + wxT(" does not exist!"));
        return NULL;

    } else {

        // A Nice trick: hide the notebook, open the editor
        // and then show it
        bool hidden(false);
        if(m_book->GetPageCount() == 0) hidden = GetSizer()->Hide(m_book);

        editor = new LEditor(m_book);
        editor->Create(projName, fileName);

        int sel = m_book->GetSelection();
        if((extra & OF_PlaceNextToCurrent) && (sel != wxNOT_FOUND)) {
            AddPage(editor, fileName.GetFullName(), fileName.GetFullPath(), wxNullBitmap, false, sel + 1);
        } else {
            AddPage(editor, fileName.GetFullName(), fileName.GetFullPath());
        }
        editor->SetSyntaxHighlight();

        // mark the editor as read only if neede
        MarkEditorReadOnly(editor);

        // SHow the notebook
        if(hidden) GetSizer()->Show(m_book);

        if(position == wxNOT_FOUND && lineno == wxNOT_FOUND && editor->GetContext()->GetName() == wxT("C++")) {
            // try to find something interesting in the file to put the caret at
            // for now, just skip past initial blank lines and comments
            for(lineno = 0; lineno < editor->GetLineCount(); lineno++) {
                switch(editor->GetStyleAt(editor->PositionFromLine(lineno))) {
                case wxSTC_C_DEFAULT:
                case wxSTC_C_COMMENT:
                case wxSTC_C_COMMENTDOC:
                case wxSTC_C_COMMENTLINE:
                case wxSTC_C_COMMENTLINEDOC:
                    continue;
                }
                // if we got here, it's a line to stop on
                break;
            }
            if(lineno == editor->GetLineCount()) {
                lineno = 1; // makes sure a navigation record gets saved
            }
        }
    }

    if(position != wxNOT_FOUND) {
        editor->SetEnsureCaretIsVisible(position, preserveSelection);
        editor->SetLineVisible(editor->LineFromPosition(position));

    } else if(lineno != wxNOT_FOUND) {
        editor->CenterLine(lineno);
    }

    if(m_reloadingDoRaise) {
        if(GetActiveEditor() == editor) {
            editor->SetActive();
        } else {
            SelectPage(editor);
        }
    }

    // Add this file to the history. Don't check for uniqueness:
    // if it's already on the list, wxFileHistory will move it to the top
    // Also, sync between the history object and the configuration file
    m_recentFiles.AddFileToHistory(fileName.GetFullPath());
    clConfig::Get().AddRecentFile(fileName.GetFullPath());

    if(extra & OF_AddJump) {
        BrowseRecord jumpto = editor->CreateBrowseRecord();
        NavMgr::Get()->AddJump(jumpfrom, jumpto);
    }
#if !CL_USE_NATIVEBOOK
    if(m_book->GetPageCount() == 1) {
        m_book->GetSizer()->Layout();
    }
#endif
    return editor;
}