From 1b98da382423dee8115f30740e544e1ed882ec80 Mon Sep 17 00:00:00 2001 From: Ge Wang Date: Sat, 26 Oct 2024 21:21:10 -0700 Subject: [PATCH] add optFilepath to compileCode() --- src/core/chuck.cpp | 7 +++++-- src/core/chuck.h | 4 +++- src/core/chuck_compile.cpp | 38 +++++++++++++++++++++++++++++--------- src/core/chuck_compile.h | 10 +++++++--- src/core/ulib_machine.cpp | 5 ++++- 5 files changed, 48 insertions(+), 16 deletions(-) diff --git a/src/core/chuck.cpp b/src/core/chuck.cpp index 6df4f520c..e8aa5013f 100644 --- a/src/core/chuck.cpp +++ b/src/core/chuck.cpp @@ -1222,11 +1222,14 @@ t_CKBOOL ChucK::compileFile( const std::string & path, // the next time step (on the VM compute/audio thread) // returns TRUE if compilation successful (even if count == 0) // returns FALSE if compilation unsuccessful +// 'optFilepath' optionally specifies a file (name, or path ending in '/') +// as basis for path-related operations, e.g., @import //----------------------------------------------------------------------------- t_CKBOOL ChucK::compileCode( const std::string & code, const std::string & argsTogether, t_CKUINT count, t_CKBOOL immediate, - std::vector * shredIDs ) + std::vector * shredIDs, + const std::string & optFilepath ) { // clear | 1.5.0.8 if( shredIDs ) shredIDs->clear(); @@ -1269,7 +1272,7 @@ t_CKBOOL ChucK::compileCode( const std::string & code, } // parse, type-check, and emit - if( !m_carrier->compiler->compileCode( code ) ) + if( !m_carrier->compiler->compileCode( code, optFilepath ) ) goto error; // get the code diff --git a/src/core/chuck.h b/src/core/chuck.h index 6aa7e0ebb..338ce56e8 100644 --- a/src/core/chuck.h +++ b/src/core/chuck.h @@ -167,8 +167,10 @@ class ChucK // if `shredIDS` is not NULL, it will be filled with the ID(s) of the new resulting shreds // returns TRUE if compilation successful (even if count == 0) // returns FALSE if compilation unsuccessful + // 'optFilepath' optionally specifies a file (name, or path ending in '/') as basis for path-related operations, e.g., @import t_CKBOOL compileCode( const std::string & code, const std::string & argsTogether = "", - t_CKUINT count = 1, t_CKBOOL immediate = FALSE, std::vector * shredIDs = NULL ); + t_CKUINT count = 1, t_CKBOOL immediate = FALSE, std::vector * shredIDs = NULL, + const std::string & optFilepath = "" ); public: // run ChucK and synthesize audio for `numFrames`... diff --git a/src/core/chuck_compile.cpp b/src/core/chuck_compile.cpp index 6eb7b125f..39b48fa1f 100644 --- a/src/core/chuck_compile.cpp +++ b/src/core/chuck_compile.cpp @@ -226,10 +226,11 @@ t_CKBOOL Chuck_Compiler::compileFile( const string & filename ) // name: compileCode() // desc: parse, type-check, and emit a program from code //----------------------------------------------------------------------------- -t_CKBOOL Chuck_Compiler::compileCode( const string & codeLiteral ) +t_CKBOOL Chuck_Compiler::compileCode( const string & codeLiteral, + const string & optFilepath ) { // call internal compile file with option - return this->compile_code_opt( codeLiteral, te_do_all ); + return this->compile_code_opt( codeLiteral, optFilepath, te_do_all ); } @@ -252,10 +253,11 @@ t_CKBOOL Chuck_Compiler::importFile( const string & filename ) // name: importCode() // desc: import from code, observing the semantics of chuck @import //----------------------------------------------------------------------------- -t_CKBOOL Chuck_Compiler::importCode( const string & codeLiteral ) +t_CKBOOL Chuck_Compiler::importCode( const string & codeLiteral, + const string & optFilepath ) { // call internal compile file with option - return this->compile_code_opt( codeLiteral, te_do_import_only ); + return this->compile_code_opt( codeLiteral, optFilepath, te_do_import_only ); } @@ -300,18 +302,36 @@ t_CKBOOL Chuck_Compiler::compile_file_opt( const string & filename, te_HowMuch e //----------------------------------------------------------------------------- // name: compile_code_opt() -// desc: parse, type-check, and emit a program, with option for how much to compile +// desc: parse, type-check, and emit a program, with options for filepath +// and for how much to compile //----------------------------------------------------------------------------- -t_CKBOOL Chuck_Compiler::compile_code_opt( const string & codeLiteral, te_HowMuch extent ) +t_CKBOOL Chuck_Compiler::compile_code_opt( const string & codeLiteral, + const string & optFilepath, + te_HowMuch extent ) { // create a compile target Chuck_CompileTarget * target = new Chuck_CompileTarget( extent ); // set filename to code literal constant target->filename = CHUCK_CODE_LITERAL_SIGNIFIER; - // get working directory - string workingDir = this->carrier()->chuck->getParamString( CHUCK_PARAM_WORKING_DIRECTORY ); + // check for optional filename + string opt = trim(optFilepath); + // the path base (e.g., for import path) + string pathBase; + // is it empty? + if( opt == "" ) + { + // get working directory + pathBase = this->carrier()->chuck->getParamString( CHUCK_PARAM_WORKING_DIRECTORY ); + } + else // not empty + { + // use the optionally provided path, make into full path if not already + opt = get_full_path( opt ); + // get the path portion of the optionally provide path + pathBase = extract_filepath_dir( opt ); + } // construct full path to be associated with the file so me.sourceDir() works - target->absolutePath = workingDir + target->filename; + target->absolutePath = pathBase + target->filename; // set code literal target->codeLiteral = codeLiteral; diff --git a/src/core/chuck_compile.h b/src/core/chuck_compile.h index 1499dec07..d647fd2d9 100644 --- a/src/core/chuck_compile.h +++ b/src/core/chuck_compile.h @@ -288,7 +288,10 @@ struct Chuck_Compiler // parse, type-check, and emit a program from file t_CKBOOL compileFile( const std::string & filename ); // parse, type-check, and emit a program from code string - t_CKBOOL compileCode( const std::string & codeLiteral ); + // * can optionally provide a filename (or path ending in '/') + // for @import pathing (by default, working dir is used) + t_CKBOOL compileCode( const std::string & codeLiteral, + const std::string & optFilepath = "" ); // get the code generated from the last compile() Chuck_VM_Code * output(); @@ -296,7 +299,8 @@ struct Chuck_Compiler // import a .ck module by file path t_CKBOOL importFile( const std::string & filename ); // import from ChucK code - t_CKBOOL importCode( const std::string & codeLiteral ); + t_CKBOOL importCode( const std::string & codeLiteral, + const std::string & optFilepath ); // import a chugin by path (and optional short-hand name) t_CKBOOL importChugin( const std::string & path, const std::string & name = "" ); @@ -377,7 +381,7 @@ struct Chuck_Compiler // parse, type-check, and emit a program from file (with option on extent) t_CKBOOL compile_file_opt( const std::string & filename, te_HowMuch extent ); // parse, type-check, and emit a program from code string (with option on extent) - t_CKBOOL compile_code_opt( const std::string & codeLiteral, te_HowMuch extent ); + t_CKBOOL compile_code_opt( const std::string & codeLiteral, const std::string & optFilepath, te_HowMuch extent ); // compile a single target t_CKBOOL compile_single( Chuck_CompileTarget * target ); // compile entire file diff --git a/src/core/ulib_machine.cpp b/src/core/ulib_machine.cpp index 900619442..a3e043257 100644 --- a/src/core/ulib_machine.cpp +++ b/src/core/ulib_machine.cpp @@ -342,9 +342,12 @@ t_CKUINT machine_eval( Chuck_String * codeStr, Chuck_String * argsTogether, string code = codeStr->str(); // get args, if there string args = argsTogether ? argsTogether->str() : ""; + // get filepath to use as optional filepath + // (e.g., for @import statements in the eval'ed code) + string optFilepath = evaluator->code ? evaluator->code->filename : ""; // compile and spork | 1.5.0.5 (ge) immediate=TRUE - t_CKUINT retval = chuck->compileCode( code, args, count, TRUE ); + t_CKUINT retval = chuck->compileCode( code, args, count, TRUE, NULL, optFilepath ); // automatically yield current shred to let new code run | 1.5.0.5 (ge) evaluator->yield();