mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-05-31 18:46:29 +03:00
eepp: Added Sys::getEnvironmentVariables. Improved Process class.
ecode: Fixed a bug in StatusBuildOuputController. Improvements when code completion and signature help are present at the same time.
This commit is contained in:
@@ -73,6 +73,16 @@ class EE_API Process {
|
||||
const std::unordered_map<std::string, std::string>& environment = {},
|
||||
const std::string& workingDirectory = "" );
|
||||
|
||||
/** @brief Create a process.
|
||||
** @param command Command line to execute for this process.
|
||||
** @param args Command line arguments to execute for this process.
|
||||
** @param options A bit field of Options's to pass.
|
||||
** @return On success true is returned. */
|
||||
bool create( const std::string& command, const std::vector<std::string>& args,
|
||||
Uint32 options = getDefaultOptions(),
|
||||
const std::unordered_map<std::string, std::string>& environment = {},
|
||||
const std::string& workingDirectory = "" );
|
||||
|
||||
/** @brief Starts a new thread to receive all stdout and stderr data */
|
||||
void startAsyncRead( ReadFn readStdOut = nullptr, ReadFn readStdErr = nullptr );
|
||||
|
||||
@@ -149,6 +159,11 @@ class EE_API Process {
|
||||
** @return The number of bytes actually written into buffer. */
|
||||
size_t write( const std::string& buffer );
|
||||
|
||||
/** @brief Write the standard output from the child process.
|
||||
** @param buffer The buffer to write into.
|
||||
** @return The number of bytes actually written into buffer. */
|
||||
size_t write( const std::string_view& buffer );
|
||||
|
||||
/** @brief Wait for a process to finish execution.
|
||||
** @param returnCodeOut The return code of the returned process (can be nullptr).
|
||||
** @return On success true is returned.
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <eepp/system/time.hpp>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace EE { namespace System {
|
||||
@@ -103,6 +104,9 @@ class EE_API Sys {
|
||||
|
||||
/** @return True if current running platform / os is a mobile one */
|
||||
static bool isMobile();
|
||||
|
||||
/** @return The process environment variables */
|
||||
static std::unordered_map<std::string, std::string> getEnvironmentVariables();
|
||||
};
|
||||
|
||||
}} // namespace EE::System
|
||||
|
||||
@@ -51,52 +51,27 @@ Process::~Process() {
|
||||
bool Process::create( const std::string& command, Uint32 options,
|
||||
const std::unordered_map<std::string, std::string>& environment,
|
||||
const std::string& workingDirectory ) {
|
||||
if ( mProcess )
|
||||
return false;
|
||||
std::vector<std::string> cmdArr = String::split( command, " ", "", "\"", true );
|
||||
std::vector<const char*> strings;
|
||||
mProcess = eeMalloc( sizeof( subprocess_s ) );
|
||||
memset( mProcess, 0, sizeof( subprocess_s ) );
|
||||
if ( !environment.empty() ) {
|
||||
std::string rcommand;
|
||||
if ( FileSystem::fileExists( command ) ) {
|
||||
rcommand = command;
|
||||
} else {
|
||||
rcommand = Sys::which( command );
|
||||
if ( rcommand.empty() )
|
||||
return false;
|
||||
}
|
||||
strings.push_back( rcommand.c_str() );
|
||||
std::vector<std::string> envArr;
|
||||
std::vector<const char*> envStrings;
|
||||
for ( const auto& pair : environment ) {
|
||||
envArr.push_back( String::format( "%s=%s", pair.first.c_str(), pair.second.c_str() ) );
|
||||
envStrings.push_back( envArr[envArr.size() - 1].c_str() );
|
||||
}
|
||||
envStrings.push_back( NULL );
|
||||
|
||||
auto ret = 0 == subprocess_create_ex( strings.data(), options, envStrings.data(),
|
||||
!workingDirectory.empty() ? workingDirectory.c_str()
|
||||
: nullptr,
|
||||
PROCESS_PTR );
|
||||
return ret;
|
||||
}
|
||||
for ( size_t i = 0; i < cmdArr.size(); ++i )
|
||||
strings.push_back( cmdArr[i].c_str() );
|
||||
strings.push_back( NULL );
|
||||
auto ret =
|
||||
0 == subprocess_create_ex( strings.data(), options, nullptr,
|
||||
!workingDirectory.empty() ? workingDirectory.c_str() : nullptr,
|
||||
PROCESS_PTR );
|
||||
return ret;
|
||||
if ( cmdArr.empty() )
|
||||
return false;
|
||||
std::string cmd( cmdArr[0] );
|
||||
cmdArr.erase( cmdArr.begin() );
|
||||
return create( cmd, cmdArr, options, environment, workingDirectory );
|
||||
}
|
||||
|
||||
bool Process::create( const std::string& command, const std::string& args, Uint32 options,
|
||||
const std::unordered_map<std::string, std::string>& environment,
|
||||
const std::string& workingDirectory ) {
|
||||
return create( command, String::split( args, " ", "", "\"", true ), options, environment,
|
||||
workingDirectory );
|
||||
}
|
||||
|
||||
bool Process::create( const std::string& command, const std::vector<std::string>& cmdArr,
|
||||
Uint32 options,
|
||||
const std::unordered_map<std::string, std::string>& environment,
|
||||
const std::string& workingDirectory ) {
|
||||
if ( mProcess )
|
||||
return false;
|
||||
std::vector<std::string> cmdArr = String::split( args, " ", "", "\"", true );
|
||||
std::vector<const char*> strings;
|
||||
mProcess = eeMalloc( sizeof( subprocess_s ) );
|
||||
memset( mProcess, 0, sizeof( subprocess_s ) );
|
||||
@@ -109,17 +84,31 @@ bool Process::create( const std::string& command, const std::string& args, Uint3
|
||||
if ( rcommand.empty() )
|
||||
return false;
|
||||
}
|
||||
std::vector<std::string> envArr;
|
||||
std::vector<const char*> envStrings;
|
||||
std::unordered_map<std::string, std::string> envVars;
|
||||
if ( options & Process::InheritEnvironment ) {
|
||||
envVars = Sys::getEnvironmentVariables();
|
||||
options &= ~Process::InheritEnvironment;
|
||||
}
|
||||
envArr.reserve( environment.size() + envVars.size() );
|
||||
strings.reserve( cmdArr.size() + 1 );
|
||||
envStrings.reserve( envArr.size() + 1 );
|
||||
|
||||
strings.push_back( rcommand.c_str() );
|
||||
for ( size_t i = 0; i < cmdArr.size(); ++i )
|
||||
strings.push_back( cmdArr[i].c_str() );
|
||||
strings.push_back( NULL );
|
||||
|
||||
std::vector<std::string> envArr;
|
||||
std::vector<const char*> envStrings;
|
||||
for ( const auto& pair : environment ) {
|
||||
// Set / Overwrite our envs
|
||||
for ( auto& pair : environment )
|
||||
envVars[pair.first] = std::move( pair.second );
|
||||
|
||||
for ( const auto& pair : envVars ) {
|
||||
envArr.push_back( String::format( "%s=%s", pair.first.c_str(), pair.second.c_str() ) );
|
||||
envStrings.push_back( envArr[envArr.size() - 1].c_str() );
|
||||
}
|
||||
|
||||
envStrings.push_back( NULL );
|
||||
|
||||
auto ret = 0 == subprocess_create_ex( strings.data(), options, envStrings.data(),
|
||||
@@ -179,6 +168,10 @@ size_t Process::write( const std::string& buffer ) {
|
||||
return write( buffer.c_str(), buffer.size() );
|
||||
}
|
||||
|
||||
size_t Process::write( const std::string_view& buffer ) {
|
||||
return write( buffer.data(), buffer.size() );
|
||||
}
|
||||
|
||||
bool Process::join( int* const returnCodeOut ) {
|
||||
eeASSERT( mProcess != nullptr );
|
||||
return 0 == subprocess_join( PROCESS_PTR, returnCodeOut );
|
||||
@@ -312,7 +305,7 @@ void Process::startAsyncRead( ReadFn readStdOut, ReadFn readStdErr ) {
|
||||
mBufferSize );
|
||||
if ( n == 0 )
|
||||
break;
|
||||
if ( n < static_cast<long>( mBufferSize - 1 ) )
|
||||
if ( n < mBufferSize - 1 )
|
||||
buffer[n] = '\0';
|
||||
if ( !mShuttingDown )
|
||||
mReadStdOutFn( buffer.c_str(), static_cast<size_t>( n ) );
|
||||
@@ -329,7 +322,7 @@ void Process::startAsyncRead( ReadFn readStdOut, ReadFn readStdErr ) {
|
||||
mBufferSize );
|
||||
if ( n == 0 )
|
||||
break;
|
||||
if ( n < static_cast<long>( mBufferSize - 1 ) )
|
||||
if ( n < mBufferSize - 1 )
|
||||
buffer[n] = '\0';
|
||||
|
||||
if ( !mShuttingDown )
|
||||
|
||||
@@ -77,6 +77,32 @@ using namespace EE::Network;
|
||||
#define PATH_MAX 4096
|
||||
#endif
|
||||
|
||||
std::unordered_map<std::string, std::string> _getEnvironmentVariables() {
|
||||
std::unordered_map<std::string, std::string> ret;
|
||||
char** env;
|
||||
#if defined( WIN ) && ( _MSC_VER >= 1900 )
|
||||
env = *__p__environ();
|
||||
#else
|
||||
extern char** environ;
|
||||
env = environ;
|
||||
#endif
|
||||
|
||||
for ( ; *env; ++env ) {
|
||||
auto var = EE::String::split( *env, "=" );
|
||||
|
||||
if ( var.size() == 2 ) {
|
||||
ret.insert( std::make_pair( var[0], var[1] ) );
|
||||
} else if ( var.size() > 2 ) {
|
||||
auto val( var[1] );
|
||||
for ( size_t i = 2; i < var.size(); ++i )
|
||||
val += var[i];
|
||||
ret.insert( std::make_pair( var[0], val ) );
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
namespace EE { namespace System {
|
||||
|
||||
#if EE_PLATFORM == EE_PLATFORM_WIN
|
||||
@@ -1192,6 +1218,10 @@ bool Sys::isMobile() {
|
||||
#endif
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, std::string> Sys::getEnvironmentVariables() {
|
||||
return _getEnvironmentVariables();
|
||||
}
|
||||
|
||||
std::string Sys::getProcessFilePath() {
|
||||
#if EE_PLATFORM != EE_PLATFORM_WIN
|
||||
char exename[PATH_MAX];
|
||||
|
||||
@@ -262,10 +262,12 @@ bool AutoCompletePlugin::onKeyDown( UICodeEditor* editor, const KeyEvent& event
|
||||
editor->invalidateDraw();
|
||||
return true;
|
||||
} else if ( event.getKeyCode() == KEY_ESCAPE ) {
|
||||
resetSuggestions( editor );
|
||||
resetSignatureHelp();
|
||||
editor->invalidateDraw();
|
||||
return true;
|
||||
if ( !ret ) {
|
||||
resetSuggestions( editor );
|
||||
resetSignatureHelp();
|
||||
editor->invalidateDraw();
|
||||
return true;
|
||||
}
|
||||
} else if ( event.getKeyCode() == KEY_HOME ) {
|
||||
mSuggestionIndex = 0;
|
||||
mSuggestionsStartIndex = 0;
|
||||
|
||||
@@ -17,33 +17,6 @@ using json = nlohmann::json;
|
||||
|
||||
using namespace EE::Scene;
|
||||
|
||||
/** @return The process environment variables */
|
||||
static ecode::ProjectBuildKeyVal getEnvironmentVariables() {
|
||||
ecode::ProjectBuildKeyVal ret;
|
||||
char** env;
|
||||
#if defined( WIN ) && ( _MSC_VER >= 1900 )
|
||||
env = *__p__environ();
|
||||
#else
|
||||
extern char** environ;
|
||||
env = environ;
|
||||
#endif
|
||||
|
||||
for ( ; *env; ++env ) {
|
||||
auto var = String::split( *env, "=" );
|
||||
|
||||
if ( var.size() == 2 ) {
|
||||
ret.push_back( std::make_pair( var[0], var[1] ) );
|
||||
} else if ( var.size() > 2 ) {
|
||||
auto val( var[1] );
|
||||
for ( size_t i = 2; i < var.size(); ++i )
|
||||
val += var[i];
|
||||
ret.push_back( std::make_pair( var[0], val ) );
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
namespace ecode {
|
||||
|
||||
static const char* VAR_PROJECT_ROOT = "${project_root}";
|
||||
@@ -764,17 +737,8 @@ void ProjectBuildManager::runBuild( const std::string& buildName, const std::str
|
||||
int progress = c > 0 ? c / (Float)totSteps : 0;
|
||||
mProcess = std::make_unique<Process>();
|
||||
auto options = Process::SearchUserPath | Process::NoWindow | Process::CombinedStdoutStderr;
|
||||
ProjectBuildKeyVal env;
|
||||
if ( !cmd.config.clearSysEnv ) {
|
||||
if ( !res.envs.empty() ) {
|
||||
env = getEnvironmentVariables();
|
||||
env.insert( env.begin(), res.envs.begin(), res.envs.end() );
|
||||
} else {
|
||||
options |= Process::InheritEnvironment;
|
||||
}
|
||||
} else {
|
||||
env = res.envs;
|
||||
}
|
||||
if ( !cmd.config.clearSysEnv )
|
||||
options |= Process::InheritEnvironment;
|
||||
|
||||
if ( !cmd.enabled ) {
|
||||
c++;
|
||||
@@ -797,7 +761,7 @@ void ProjectBuildManager::runBuild( const std::string& buildName, const std::str
|
||||
nullptr );
|
||||
}
|
||||
|
||||
if ( mProcess->create( cmd.cmd, cmd.args, options, toUnorderedMap( env ),
|
||||
if ( mProcess->create( cmd.cmd, cmd.args, options, toUnorderedMap( res.envs ),
|
||||
cmd.workingDir ) ) {
|
||||
std::string buffer( 1024, '\0' );
|
||||
unsigned bytesRead = 0;
|
||||
|
||||
@@ -568,12 +568,11 @@ void StatusBuildOutputController::createContainer() {
|
||||
->setId( "copy-error-message" );
|
||||
menu->add( mApp->i18n( "copy_file_path", "Copy File Path" ), mApp->findIcon( "copy" ) )
|
||||
->setId( "copy-file-path" );
|
||||
menu->on( Event::OnItemClicked, [this, model, modelEvent, idx]( const Event* event ) {
|
||||
menu->on( Event::OnItemClicked, [this, model, idx]( const Event* event ) {
|
||||
UIMenuItem* item = event->getNode()->asType<UIMenuItem>();
|
||||
std::string id( item->getId() );
|
||||
if ( id == "copy-error-message" ) {
|
||||
Variant msg( model->data( model->index( modelEvent->getModelIndex().row(), 0 ),
|
||||
ModelRole::Display ) );
|
||||
Variant msg( model->data( model->index( idx.row(), 0 ), ModelRole::Display ) );
|
||||
mApp->getWindow()->getClipboard()->setText( msg.toString() );
|
||||
} else if ( id == "copy-file-path" ) {
|
||||
Variant msg( model->data( idx, ModelRole::Custom ) );
|
||||
|
||||
Reference in New Issue
Block a user