Skip to content

Commit

Permalink
add packages import path subdir crawl
Browse files Browse the repository at this point in the history
  • Loading branch information
gewang committed Nov 4, 2024
1 parent 9c5f6a5 commit 59f6852
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 24 deletions.
2 changes: 2 additions & 0 deletions VERSIONS
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ ChucK VERSIONS log
=======
(patch release)
- (fixed, linux) a crash when the OTF handles an OTF command (add or replace)
- (added) support for crawling subdirectories for importing for packages
to be managed by the upcoming ChuMP (ChucK Manager of Packages)


1.5.4.0 (November 2024)
Expand Down
38 changes: 24 additions & 14 deletions src/core/chuck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,7 @@ t_CKBOOL ChucK::initCompiler()

//-----------------------------------------------------------------------------
// name: initChugin()
// desc: initialize chugin system
// desc: initialize chugin system (auto-load system chugins)
//-----------------------------------------------------------------------------
t_CKBOOL ChucK::initChugins()
{
Expand Down Expand Up @@ -817,6 +817,12 @@ void ChucK::probeChugins()
std::list<std::string> ck_libs_to_preload;
// host verison
std::ostringstream ostr; ostr << CK_DLL_VERSION_MAJOR << "." << CK_DLL_VERSION_MINOR;
// chugin extension
std::string extension = ".chug";
#ifdef __EMSCRIPTEN__
// webchugins have extension ".chug.wasm" | 1.5.2.0 (terryzfeng) added
extension = "chug.wasm";
#endif

// print whether chugins enabled
EM_log( CK_LOG_SYSTEM, "chugin system: %s", getParamInt( CHUCK_PARAM_CHUGIN_ENABLE ) ? "ON" : "OFF" );
Expand All @@ -832,9 +838,20 @@ void ChucK::probeChugins()
// pop
EM_poplog();

// list of search pathes (added 1.3.0.0)
// list of search pathes (added 1.3.0.0; revisited 1.5.4.0)
// start with system paths (auto-load chugins; .ck files must be @imported)
std::list<std::string> dl_search_path = getParamStringList( CHUCK_PARAM_IMPORT_PATH_SYSTEM );
append_path_list( dl_search_path, getParamStringList( CHUCK_PARAM_IMPORT_PATH_PACKAGES) );
// next, process packages paths (e.g., as managed by ChuMP; no auto-load; all must be @imported)
std::list<std::string> packages_paths = getParamStringList( CHUCK_PARAM_IMPORT_PATH_PACKAGES);
// append packages paths to search paths
append_path_list( dl_search_path, packages_paths );
// iterate over packages paths | 1.5.4.1 (ge & nshaheed) added
for( std::list<std::string>::iterator it = packages_paths.begin(); it != packages_paths.end(); it++ )
{
// scan for subdirs, but only one-level in each packages path
scan_for_dirs_in_directory( *it, extension, FALSE, dl_search_path );
}
// finally, add user-managed search paths (no auto-load; all must be @imported)
append_path_list( dl_search_path, getParamStringList( CHUCK_PARAM_IMPORT_PATH_USER) );

// list of individually named chug-ins (added 1.3.0.0)
Expand All @@ -845,13 +862,6 @@ void ChucK::probeChugins()
// push indent level
// EM_pushlog();

// chugin extension
std::string extension = ".chug";
#ifdef __EMSCRIPTEN__
// webchugins have extension ".chug.wasm" | 1.5.2.0 (terryzfeng) added
extension = "chug.wasm";
#endif

// load external libs; recurse changed to FALSE in 1.5.4.0 (ge)
if( !Chuck_Compiler::probe_external_modules( extension.c_str(), dl_search_path, named_dls, FALSE, ck_libs_to_preload ) )
{
Expand All @@ -863,9 +873,9 @@ void ChucK::probeChugins()

//-------------------------------------------------------------------------
// 1.5.4.0 | .ck files are no longer auto compiled; need to be @import
/*-------------------------------------------------------------------------
//-------------------------------------------------------------------------
// log
EM_log( CK_LOG_SYSTEM, "probing auto-load chuck files (.ck)..." );
EM_log( CK_LOG_SYSTEM, "probing chuck files (.ck)..." );
EM_pushlog();

// iterate over list of ck files that the compiler found
Expand All @@ -875,7 +885,8 @@ void ChucK::probeChugins()
// the filename
std::string filename = *j;
// log
EM_log( CK_LOG_SYSTEM, "[%s] '%s'...", TC::green("FOUND",true).c_str(), filename.c_str() );
logCKFileFound( filename, CK_LOG_SYSTEM );
// EM_log( CK_LOG_SYSTEM, "[%s] '%s'...", TC::green("FOUND",true).c_str(), filename.c_str() );
}

// check
Expand All @@ -884,7 +895,6 @@ void ChucK::probeChugins()

// pop log
EM_poplog();
-------------------------------------------------------------------------*/
}


Expand Down
118 changes: 108 additions & 10 deletions src/core/chuck_compile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -666,17 +666,30 @@ std::string Chuck_Compiler::resolveFilename( const std::string & filename,
// TODO: possible caching -- search for match first in registry
// match-right between each entry and fname; if found, return entry absolute path

// get search paths; order: system, packages, user
list<string> searchPaths = this->carrier()->chuck->getParamStringList( CHUCK_PARAM_IMPORT_PATH_SYSTEM );
append_path_list( searchPaths, this->carrier()->chuck->getParamStringList( CHUCK_PARAM_IMPORT_PATH_PACKAGES ) );
append_path_list( searchPaths, this->carrier()->chuck->getParamStringList( CHUCK_PARAM_IMPORT_PATH_USER ) );
// search paths: start with system paths
std::list<std::string> searchPaths = this->carrier()->chuck->getParamStringList( CHUCK_PARAM_IMPORT_PATH_SYSTEM );
// next, process packages paths (e.g., as managed by ChuMP)
std::list<std::string> packages_paths = this->carrier()->chuck->getParamStringList( CHUCK_PARAM_IMPORT_PATH_PACKAGES);
// append packages paths to search paths
append_path_list( searchPaths, packages_paths );
// iterate over packages paths | 1.5.4.1 (ge & nshaheed) added
for( std::list<std::string>::iterator it = packages_paths.begin(); it != packages_paths.end(); it++ )
{
// scan for subdirs, but only one-level in each packages path
scan_for_dirs_in_directory( *it, "", FALSE, searchPaths );
}
// finally, add user-managed search paths (no auto-load; all must be @imported)
append_path_list( searchPaths, this->carrier()->chuck->getParamStringList( CHUCK_PARAM_IMPORT_PATH_USER) );

// go over paths
for( list<string>::iterator it = searchPaths.begin(); it != searchPaths.end(); it++ )
{
// construct path; expand path again here in case search path has things like ~
absolutePath = expand_filepath(*it+fname);
// try to match
hasMatch = matchFilename( absolutePath, extension, exts );
// log
EM_log( CK_LOG_FINER, "testing match: '%s' ('%s')", absolutePath.c_str(), hasMatch ? "yes" : "no" );
// if match found, break out
if( hasMatch ) break;
}
Expand Down Expand Up @@ -1419,7 +1432,7 @@ t_CKBOOL scan_external_modules_in_directory( const string & directory,
vector<string> & ckfiles2load )
{
// expand directory path
string path = expand_filepath( string(directory), FALSE );
string path = expand_filepath( directory, FALSE );
// open the directory
DIR * dir = opendir( path.c_str() );

Expand All @@ -1429,7 +1442,7 @@ t_CKBOOL scan_external_modules_in_directory( const string & directory,
// do first read | 1.5.0.0 (ge + eito) #chunreal
struct dirent * de = readdir( dir );
// while( (de = readdir(dir)) ) <- UE5 forces us to not do this
while( de != NULL )
for( de = readdir(dir); de != NULL; de = readdir(dir) )
{
t_CKBOOL is_regular = false;
t_CKBOOL is_directory = false;
Expand Down Expand Up @@ -1490,14 +1503,83 @@ t_CKBOOL scan_external_modules_in_directory( const string & directory,
chugins2load.push_back( ChuginFileInfo( de->d_name, subdirectory, true ) );
}
#endif // #ifdef __PLATFORM_APPLE__
}

// close
closedir( dir );

return TRUE;
}




//-----------------------------------------------------------------------------
// name: scan_for_dirs_in_directory() | 1.5.4.1 (ge & nshaheed) added
// desc: scan all subdirectories within a directory
//-----------------------------------------------------------------------------
t_CKBOOL scan_for_dirs_in_directory( const string & directory,
const string & extensionForSubdirTest,
t_CKBOOL recursiveSearch,
list<string> & results )
{
// expand directory path
string path = normalize_directory_name( expand_filepath( directory, FALSE ) );
// open the directory
DIR * dir = opendir( path.c_str() );
// cannot open
if( !dir ) return FALSE;

// local results
list<string> localResults;

// do first read | 1.5.0.0 (ge + eito) #chunreal
struct dirent * de = readdir( dir );
// while( (de = readdir(dir)) ) <- UE5 forces us to not do this
for( de = readdir(dir); de != NULL; de = readdir(dir) )
{
t_CKBOOL is_regularFile = false;
t_CKBOOL is_directory = false;
// get attributes
if( !getDirEntryAttribute( de, is_directory, is_regularFile ) ) continue;

// read next | 1.5.0.0 (ge) moved here due to #chunreal
de = readdir( dir );
// check if directory
if( is_directory )
{
// test for special cases (e.g., chugins that are directories)
if( extensionForSubdirTest.length() && !subdir_ok2recurse( de->d_name, extensionForSubdirTest ) ) continue;

// check dir entry
if( strncmp( de->d_name, ".", sizeof( "." ) ) != 0 &&
strncmp( de->d_name, "..", sizeof( ".." ) ) != 0 )
{
// construct absolute path (use the non-expanded path for consistency when printing)
string absolute_path = string(path) + de->d_name;
// queue sub-directory
localResults.push_back( normalize_directory_name(absolute_path) );
}
}
}

// close
closedir( dir );

// sort the local results
localResults.sort();
// copy local results
append_path_list( results, localResults );

// recurse?
if( recursiveSearch )
{
// iterate over local directoriesug
for( list<string>::iterator it = localResults.begin(); it != localResults.end(); it++ )
{
// scan subdirs in this local dir
scan_for_dirs_in_directory( *it, extensionForSubdirTest, recursiveSearch, results );
}
}

return TRUE;
}

Expand All @@ -1508,7 +1590,7 @@ t_CKBOOL scan_external_modules_in_directory( const string & directory,
// name: logChuginLoad() | 1.5.2.5 (ge)
// desc: local function quick-hand for logging a chugin load
//-----------------------------------------------------------------------------
static void logChuginLoad( const string & name, t_CKINT logLevel )
void logChuginLoad( const string & name, t_CKINT logLevel )
{
// log with no newline; print `[chugin] X.chug`
EM_log_opts( logLevel, EM_LOG_NO_NEWLINE, "[%s] %s ", TC::magenta("chugin",true).c_str(), name.c_str() );
Expand All @@ -1517,6 +1599,22 @@ static void logChuginLoad( const string & name, t_CKINT logLevel )



//-----------------------------------------------------------------------------
// name: logCKFileFound() | 1.5.4.1 (ge & nshaheed)
// desc: local function quick-hand for logging a chuck file found
//-----------------------------------------------------------------------------
void logCKFileFound( const string & name, t_CKINT logLevel )
{
// log with no newline; print `[chuck file] X.ck`
EM_log_opts( logLevel, EM_LOG_NO_NEWLINE, "[%s] %s ", TC::blue("chuck file",true).c_str(), name.c_str() );

// print success status
EM_log_opts( logLevel, EM_LOG_NO_PREFIX, "[%s]", TC::green("FOUND",true).c_str() );
}




//-----------------------------------------------------------------------------
// name: import_chugin_opt()
// desc: load chugin module by path, with options
Expand Down Expand Up @@ -1987,7 +2085,7 @@ t_CKBOOL Chuck_Compiler::probe_external_modules( const string & extension,
// push
EM_pushlog();

// now recurse through search paths and load any DLs or .ck files found
// now recurse through search paths and note any DLs or .ck files found
for( list<string>::iterator i_sp = chugin_search_paths.begin();
i_sp != chugin_search_paths.end(); i_sp++ )
{
Expand Down
16 changes: 16 additions & 0 deletions src/core/chuck_compile.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include "chuck_vm.h"
#include <list>
#include <set>
#include <string>



Expand Down Expand Up @@ -419,5 +420,20 @@ struct Chuck_Compiler



//-----------------------------------------------------------------------------
// helper functions
//-----------------------------------------------------------------------------
// log a chugin load
void logChuginLoad( const std::string & name, t_CKINT logLevel );
// log a chuck file found
void logCKFileFound( const std::string & name, t_CKINT logLevel );
// scan for subdirs in a dir
t_CKBOOL scan_for_dirs_in_directory( const std::string & directory,
const std::string & extensionForSubdirTest,
t_CKBOOL recursiveSearch,
std::list<std::string> & results );




#endif

0 comments on commit 59f6852

Please sign in to comment.