File: LINUX.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 (180 lines) | stat: -rw-r--r-- 4,829 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
168
169
170
171
172
173
174
175
176
177
178
179
180
#include "LINUX.hpp"

#include "PlatformCommon.hpp"
#include "clFilesCollector.h"
#include "clVersionString.hpp"
#include "file_logger.h"
#include "procutils.h"

#include <algorithm>
#include <cmath>
#include <wx/arrstr.h>
#include <wx/filename.h>
#include <wx/string.h>
#include <wx/tokenzr.h>
#include <wx/utils.h>

namespace
{
#ifdef __WXMAC__
/// Homebrew install formulas in a specific location, this function
/// attempts to discover this location
bool macos_find_homebrew_cellar_path_for_formula(const wxString& formula, wxString* install_path)
{
    wxString cellar_path = "/opt/homebrew/Cellar";
    if (!wxFileName::DirExists(cellar_path)) {
        cellar_path = "/usr/local/Cellar";
    }
    
    cellar_path << "/" << formula;

    if(!wxFileName::DirExists(cellar_path)) {
        return false;
    }

    // we take the string with the highest value
    clFilesScanner fs;
    clFilesScanner::EntryData::Vec_t results;
    if(fs.ScanNoRecurse(cellar_path, results) == 0) {
        return false;
    }

    // we are only interested in the name part
    for(auto& result : results) {
        result.fullpath = result.fullpath.AfterLast('/');
    }

    std::sort(results.begin(), results.end(),
              [](const clFilesScanner::EntryData& a, const clFilesScanner::EntryData& b) {
                  clVersionString vs_a{ a.fullpath };
                  clVersionString vs_b{ b.fullpath };
                  // want to sort in descending order
                  return vs_b.to_number() < vs_a.to_number();
              });

    *install_path << cellar_path << "/" << results[0].fullpath;
    clDEBUG() << "Using cellar path:" << *install_path << endl;
    return true;
}
#endif
} // namespace

/// Locate rustup bin folder
/// the path is set to:
/// $HOME/.rustup/toolchains/TOOLCHAIN-NAME/bin
bool LINUX::get_rustup_bin_folder(wxString* rustup_bin_dir)
{
    if(rust_toolchain_scanned) {
        *rustup_bin_dir = RUST_TOOLCHAIN_BIN;
        return !RUST_TOOLCHAIN_BIN.empty();
    }

    FindRustupToolchainBinDir(&RUST_TOOLCHAIN_BIN);
    rust_toolchain_scanned = true;

    // call this method again, this time rust_toolchain_scanned is set to true
    return get_rustup_bin_folder(rustup_bin_dir);
}

bool LINUX::FindInstallDir(wxString* installpath)
{
    *installpath = "/";
    return true;
}

bool LINUX::FindHomeDir(wxString* homedir)
{
#ifdef __WXMAC__
    *homedir << "/Users/" << ::wxGetUserId();
#else
    *homedir << "/home/" << ::wxGetUserId();
#endif
    return true;
}

bool LINUX::Which(const wxString& command, wxString* command_fullpath)
{
    wxString HOME;
    FindHomeDir(&HOME);

    wxArrayString special_paths;

#ifdef __WXMAC__
    // macOS only
    special_paths.Add("/opt/homebrew/bin");
#endif

#ifdef __WXGTK__
    special_paths.Add(wxString() << HOME << "/.local/bin");
    // linux also supports homebrew
    if(wxFileName::DirExists("/home/linuxbrew/.linuxbrew/bin")) {
        special_paths.Add("/home/linuxbrew/.linuxbrew/bin");
    }
#endif

    // cargo
    special_paths.Add(wxString() << HOME << "/.cargo/bin");

    // rustup
    wxString rustup_bin_folder;
    if(get_rustup_bin_folder(&rustup_bin_folder)) {
        special_paths.Add(rustup_bin_folder);
    }

    // /usr/local/bin is not always in the PATH, so add it
    special_paths.Add("/usr/local/bin");

    // common paths: read the env PATH and append the other paths to it
    // so common paths found ENV:PATH will come first
    wxArrayString paths;
    if(m_flags & SEARCH_PATH_ENV) {
        wxString pathenv;
        ::wxGetEnv("PATH", &pathenv);
        paths = ::wxStringTokenize(pathenv, ":", wxTOKEN_STRTOK);
    }

    // append the special paths to the end
    paths.insert(paths.end(), special_paths.begin(), special_paths.end());

#ifdef __WXMAC__
    // llvm is placed under a special location
    // if we find it, we place it first
    wxString llvm_path;
    if(macos_find_homebrew_cellar_path_for_formula("llvm", &llvm_path)) {
        paths.Insert(llvm_path + "/bin", 0);
    }
#endif

    // remove duplicate entries
    wxStringSet_t S;
    wxArrayString unique_paths;
    unique_paths.reserve(paths.size());
    for(const auto& path : paths) {
        if(S.count(path) == 0) {
            S.insert(path);
            unique_paths.Add(path);
        }
    }

    paths.swap(unique_paths);

    for(auto path : paths) {
        path << "/" << command;
        if(wxFileName::FileExists(path)) {
            *command_fullpath = path;
            return true;
        }
    }
    return false;
}

bool LINUX::WhichWithVersion(const wxString& command, const std::vector<int>& versions, wxString* command_fullpath)
{
    return PlatformCommon::WhichWithVersion(command, versions, command_fullpath);
}

namespace
{
thread_local LINUX instance;
}
LINUX* LINUX::Get() { return &instance; }