File: clConsoleCodeLiteTerminal.cpp

package info (click to toggle)
codelite 17.0.0%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 136,244 kB
  • sloc: cpp: 491,547; ansic: 280,393; php: 10,259; sh: 8,930; lisp: 7,664; vhdl: 6,518; python: 6,020; lex: 4,920; yacc: 3,123; perl: 2,385; javascript: 1,715; cs: 1,193; xml: 1,110; makefile: 804; cobol: 741; sql: 709; ruby: 620; f90: 566; ada: 534; asm: 464; fortran: 350; objc: 289; tcl: 258; java: 157; erlang: 61; pascal: 51; ml: 49; awk: 44; haskell: 36
file content (167 lines) | stat: -rw-r--r-- 5,481 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#include "clConsoleCodeLiteTerminal.h"

#include "cl_standard_paths.h"
#include "file_logger.h"
#include "fileutils.h"
#include "procutils.h"

#include <wx/arrstr.h>
#include <wx/tokenzr.h>

clConsoleCodeLiteTerminal::clConsoleCodeLiteTerminal()
{
    wxString cmd = GetBinary();
#ifndef __WXOSX__
    WrapWithQuotesIfNeeded(cmd);
#endif
    SetTerminalCommand(wxString() << cmd << " --working-directory=%WD% --file=%COMMANDFILE%");
    SetEmptyTerminalCommand(wxString() << cmd << " --working-directory=%WD%");
}

clConsoleCodeLiteTerminal::~clConsoleCodeLiteTerminal() {}

wxString clConsoleCodeLiteTerminal::PrepareCommand()
{
    // Build the command to execute
    wxString commandToExecute;
    if(IsTerminalNeeded()) {
        wxFileName tmpfile(clStandardPaths::Get().GetTempDir(), "codelite-terminal.txt");
        bool hasCommand = !GetCommand().IsEmpty();
        commandToExecute = hasCommand ? GetTerminalCommand() : GetEmptyTerminalCommand();

        // For testing purposes
        wxString command = WrapWithQuotesIfNeeded(GetCommand());
        if(!command.IsEmpty()) {
#ifdef __WXMSW__
            command.Prepend("start /B /WAIT "); // start the application in the foreground
#endif
            if(!GetCommandArgs().IsEmpty()) {
                wxString cmdArgs = GetCommandArgs();
                command << " " << GetCommandArgs();
            }

            // Write the content of the command into a file
            FileUtils::WriteFileContent(tmpfile, command);
        }

        wxString wd = GetWorkingDirectory();
        if(wd.IsEmpty() || !wxFileName::DirExists(wd)) {
            wd = WrapWithQuotesIfNeeded(wxGetCwd());
        }
        if(IsWaitWhenDone()) {
            commandToExecute << " --wait ";
        }

        wxString commandFile = tmpfile.GetFullPath();
        commandFile = WrapWithQuotesIfNeeded(commandFile);

        commandToExecute.Replace("%COMMANDFILE%", commandFile);
        commandToExecute.Replace("%WD%", wd);

    } else {
        commandToExecute = WrapWithQuotesIfNeeded(GetCommand());
        if(!GetCommandArgs().IsEmpty()) {
            commandToExecute << " " << GetCommandArgs();
        }
    }
    return commandToExecute;
}

bool clConsoleCodeLiteTerminal::StartForDebugger()
{
#ifdef __WXMSW__
    return false;
#else
    // generate a random value to differntiate this instance of codelite
    // from other instances

    time_t curtime = time(NULL);
    int randomSeed = (curtime % 947);
    wxString secondsToSleep;

    secondsToSleep << (85765 + randomSeed);

    wxString sleepCommand = "/bin/sleep";
    sleepCommand << " " << secondsToSleep;

    wxString homedir = wxGetHomeDir();
    if(homedir.Contains(" ")) {
        homedir.Prepend("\"").Append("\"");
    }
    wxString commandToExecute;
    commandToExecute << GetBinary();
#ifndef __WXOSX__
    WrapWithQuotesIfNeeded(commandToExecute);
#endif
    wxFileName tmpfile("/tmp", "codelite-terminal.txt");
    tmpfile.SetFullName(wxString() << "codelite-terminal." << secondsToSleep << ".txt");

    commandToExecute << " --print-tty=" << tmpfile.GetFullPath() << " --working-directory=" << homedir
                     << " --command=\"" << sleepCommand << "\"";
    m_pid = ::wxExecute(commandToExecute);

    // Let it start ... (wait for it up to 5 seconds)
    for(size_t i = 0; i < 100; ++i) {
        if(tmpfile.FileExists()) {
            FileUtils::ReadFileContent(tmpfile.GetFullPath(), m_tty);
            // On GTK, redirection to TTY does not work with lldb
            // as a workaround, we create a symlink with different name

            // Keep the real tty
            m_realPts = m_tty;

            wxString symlinkName = m_tty;
            symlinkName.Replace("/dev/pts/", "/tmp/pts");
            wxString lnCommand;
            lnCommand << "ln -sf " << m_tty << " " << symlinkName;
            if(::system(lnCommand.mb_str(wxConvUTF8).data()) == 0) {
                m_tty.swap(symlinkName);
            }
            break;
        }
        wxThread::Sleep(50);
    }
#ifdef __WXOSX__
    // on OSX, wxExecute return the PID of the open command
    // we want the sleep command PID (when we kill the 'sleep' the terminal will
    // close itself)
    m_pid = wxNOT_FOUND;
    wxString psCommand;
    psCommand << "ps -A -o pid,command";
    wxString psOutput = ProcUtils::SafeExecuteCommand(psCommand);
    LOG_IF_TRACE { clDEBUG1() << "ps command output:\n" << psOutput; }
    wxArrayString lines = ::wxStringTokenize(psOutput, "\n", wxTOKEN_STRTOK);
    for(size_t u = 0; u < lines.GetCount(); ++u) {
        wxString l = lines.Item(u);
        l.Trim().Trim(false);
        if(l.Contains("sleep") && l.Contains(secondsToSleep) && !l.Contains("codelite-terminal")) {
            // we got a match
            wxString ppidString = l.BeforeFirst(' ');
            ppidString.ToCLong(&m_pid);
            clDEBUG() << "codelite-terminal process ID is:" << m_pid;
            break;
        }
    }
#endif

    return !m_tty.IsEmpty();
#endif
}

wxString clConsoleCodeLiteTerminal::GetBinary() const
{
    wxFileName codeliteTerminal(clStandardPaths::Get().GetBinFolder(), "codelite-terminal");
#ifdef __WXMSW__
    codeliteTerminal.SetExt("exe");
#elif defined(__WXOSX__)
    codeliteTerminal.AppendDir("codelite-terminal.app");
#endif

#ifdef __WXOSX__
    wxString cmd = codeliteTerminal.GetPath();
    cmd = WrapWithQuotesIfNeeded(cmd);
    return cmd;
#else
    return codeliteTerminal.GetFullPath();
#endif
}