Unified · Split
| @@ -2,6 +2,15 @@ · 1 unmodified line | |||
| 2 | ChucK VERSIONS log | 2 | ChucK VERSIONS log |
| 3 | ------------------ | 3 | ------------------ |
| 4 | 4 | ||
| 5 | 1.5.0.4 | ||
| 6 | --- | ||
| 7 | - (added) --chugin-probe command-line flag to probe (and verify version) | ||
| 8 | for chugins and auto-load chuck sources in the search paths; print | ||
| 9 | results and any version mismatches | ||
| 10 | - (updated) setting chuck log level is no longer logged below | ||
| 11 | log level INFO | ||
| 12 | |||
| 13 | |||
| 5 | 1.5.0.3 (June 2023) | 14 | 1.5.0.3 (June 2023) |
| 6 | --- | 15 | --- |
| 7 | - (fixed) chuck audio I/O now correctly carries out extended probing | 16 | - (fixed) chuck audio I/O now correctly carries out extended probing |
| @@ -630,7 +630,7 @@ t_CKBOOL ChucK::initChugins() · 629 unmodified lines | |||
| 630 | // push indent level | 630 | // push indent level |
| 631 | EM_pushlog(); | 631 | EM_pushlog(); |
| 632 | // load external libs | 632 | // load external libs |
| 633 | if( !compiler()->load_external_modules( ".chug", dl_search_path, named_dls ) ) | 633 | if( !compiler()->load_external_modules( ".chug", dl_search_path, named_dls, true ) ) |
| 634 | { | 634 | { |
| 635 | // pop indent level | 635 | // pop indent level |
| 636 | EM_poplog(); | 636 | EM_poplog(); |
| @@ -722,11 +722,20 @@ error: // 1.4.1.0 (ge) added · 85 unmodified lines | |||
| 722 | //----------------------------------------------------------------------------- | 722 | //----------------------------------------------------------------------------- |
| 723 | void ChucK::probeChugins() | 723 | void ChucK::probeChugins() |
| 724 | { | 724 | { |
| 725 | Chuck_VM_Code * code = NULL; | 725 | // ck files to pre load |
| 726 | Chuck_VM_Shred * shred = NULL; | 726 | std::list<std::string> ck_libs_to_preload; |
| 727 | 727 | ||
| 728 | // print whether chugins enabled | 728 | // print whether chugins enabled |
| 729 | EM_log( CK_LOG_SYSTEM, "chugin system: %s", getParamInt( CHUCK_PARAM_CHUGIN_ENABLE ) ? "ON" : "OFF" ); | 729 | EM_log( CK_LOG_SYSTEM, "chugin system: %s", getParamInt( CHUCK_PARAM_CHUGIN_ENABLE ) ? "ON" : "OFF" ); |
| 730 | // print host version | ||
| 731 | EM_log( CK_LOG_SYSTEM, "chuck host version: %d.%d", CK_DLL_VERSION_MAJOR, CK_DLL_VERSION_MINOR ); | ||
| 732 | // push | ||
| 733 | EM_pushlog(); | ||
| 734 | // print host version | ||
| 735 | EM_log( CK_LOG_SYSTEM, "chugin major version must == host major version" ); | ||
| 736 | EM_log( CK_LOG_SYSTEM, "chugin minor version must <= host major version" ); | ||
| 737 | // pop | ||
| 738 | EM_poplog(); | ||
| 730 | 739 | ||
| 731 | // chugin dur | 740 | // chugin dur |
| 732 | std::string chuginDir = getParamString( CHUCK_PARAM_CHUGIN_DIRECTORY ); | 741 | std::string chuginDir = getParamString( CHUCK_PARAM_CHUGIN_DIRECTORY ); |
| @@ -741,61 +750,35 @@ void ChucK::probeChugins() · 8 unmodified lines | |||
| 741 | std::list<std::string> named_dls = getParamStringList( CHUCK_PARAM_USER_CHUGINS ); | 750 | std::list<std::string> named_dls = getParamStringList( CHUCK_PARAM_USER_CHUGINS ); |
| 742 | 751 | ||
| 743 | // log | 752 | // log |
| 744 | EM_log( CK_LOG_SYSTEM, "probing chugins..." ); | 753 | EM_log( CK_LOG_SYSTEM, "probing chugins (.chug)..." ); |
| 745 | // push indent level | 754 | // push indent level |
| 746 | EM_pushlog(); | 755 | EM_pushlog(); |
| 747 | // load external libs | 756 | // load external libs |
| 748 | if(!compiler()->load_external_modules( ".chug", dl_search_path, named_dls )) | 757 | if( !Chuck_Compiler::probe_external_modules( ".chug", dl_search_path, named_dls, TRUE, ck_libs_to_preload ) ) |
| 749 | { | 758 | { |
| 750 | // pop indent level | 759 | // warning |
| 751 | EM_poplog(); | 760 | EM_log( CK_LOG_SYSTEM, "error probing chugins..." ); |
| 752 | // clean up | ||
| 753 | // goto error; | ||
| 754 | } | 761 | } |
| 755 | // pop log | 762 | // pop log |
| 756 | EM_poplog(); | 763 | EM_poplog(); |
| 757 | 764 | ||
| 758 | // log | 765 | // log |
| 759 | EM_log( CK_LOG_SYSTEM, "probing pre-loading ChucK libs..." ); | 766 | EM_log( CK_LOG_SYSTEM, "probing auto-load chuck files (.ck)..." ); |
| 760 | EM_pushlog(); | 767 | EM_pushlog(); |
| 761 | 768 | ||
| 762 | // iterate over list of ck files that the compiler found | 769 | // iterate over list of ck files that the compiler found |
| 763 | for( std::list<std::string>::iterator j = | 770 | for( std::list<std::string>::iterator j = ck_libs_to_preload.begin(); |
| 764 | compiler()->m_cklibs_to_preload.begin(); | 771 | j != ck_libs_to_preload.end(); j++ ) |
| 765 | j != compiler()->m_cklibs_to_preload.end(); j++ ) | ||
| 766 | { | 772 | { |
| 767 | // the filename | 773 | // the filename |
| 768 | std::string filename = *j; | 774 | std::string filename = *j; |
| 769 | |||
| 770 | // log | 775 | // log |
| 771 | EM_log( CK_LOG_SEVERE, "preloading '%s'...", filename.c_str() ); | 776 | EM_log( CK_LOG_SYSTEM, "source '%s'...", filename.c_str() ); |
| 772 | // push indent | ||
| 773 | EM_pushlog(); | ||
| 774 | |||
| 775 | // SPENCERTODO: what to do for full path | ||
| 776 | std::string full_path = filename; | ||
| 777 | |||
| 778 | // parse, type-check, and emit | ||
| 779 | if(compiler()->go( filename, NULL, NULL, full_path )) | ||
| 780 | { | ||
| 781 | // TODO: how to compilation handle? | ||
| 782 | //return 1; | ||
| 783 | |||
| 784 | // get the code | ||
| 785 | code = compiler()->output(); | ||
| 786 | // name it - TODO? | ||
| 787 | // code->name += string(argv[i]); | ||
| 788 | |||
| 789 | // spork it | ||
| 790 | shred = vm()->spork( code, NULL, TRUE ); | ||
| 791 | } | ||
| 792 | |||
| 793 | // pop indent | ||
| 794 | EM_poplog(); | ||
| 795 | } | 777 | } |
| 796 | 778 | ||
| 797 | // clear the list of chuck files to preload | 779 | // check |
| 798 | compiler()->m_cklibs_to_preload.clear(); | 780 | if( ck_libs_to_preload.size() == 0 ) |
| 781 | EM_log( CK_LOG_SYSTEM, "(none found)" ); | ||
| 799 | 782 | ||
| 800 | // pop log | 783 | // pop log |
| 801 | EM_poplog(); | 784 | EM_poplog(); |
| @@ -745,6 +745,78 @@ error: · 744 unmodified lines | |||
| 745 | 745 | ||
| 746 | 746 | ||
| 747 | 747 | ||
| 748 | |||
| 749 | //----------------------------------------------------------------------------- | ||
| 750 | // name: expandfilePath() | ||
| 751 | // desc: expand file path, e.g., ~ on unix systems | 1.5.0.4 (ge) moved here | ||
| 752 | //----------------------------------------------------------------------------- | ||
| 753 | std::string expandFilePath( const string & directory ) | ||
| 754 | { | ||
| 755 | // expansion | ||
| 756 | string exp; | ||
| 757 | |||
| 758 | #ifndef __PLATFORM_WIN32__ | ||
| 759 | #ifndef __DISABLE_WORDEXP__ | ||
| 760 | // 1.5.0.0 (ge) added (for ~) | ||
| 761 | wordexp_t exp_result; | ||
| 762 | // "perform shell-style word expansions" | ||
| 763 | wordexp( directory.c_str(), &exp_result, 0 ); | ||
| 764 | // concatenate in case there are spaces in the path | ||
| 765 | for( t_CKINT i = 0; i < exp_result.we_wordc; i++ ) | ||
| 766 | exp += string(i > 0 ? " " : "") + exp_result.we_wordv[i]; | ||
| 767 | // free | ||
| 768 | wordfree( &exp_result ); | ||
| 769 | #endif | ||
| 770 | #endif | ||
| 771 | |||
| 772 | // if exp still empty, no change | ||
| 773 | if( exp == "" ) exp = directory; | ||
| 774 | |||
| 775 | // done | ||
| 776 | return exp; | ||
| 777 | } | ||
| 778 | |||
| 779 | |||
| 780 | |||
| 781 | |||
| 782 | //----------------------------------------------------------------------------- | ||
| 783 | // name: getDirEntryAttribute() | ||
| 784 | // desc: get directory entry attribute | 1.5.0.4 (ge) moved into function | ||
| 785 | //----------------------------------------------------------------------------- | ||
| 786 | t_CKBOOL getDirEntryAttribute( dirent * de, t_CKBOOL & isDirectory, t_CKBOOL & isRegular ) | ||
| 787 | { | ||
| 788 | #if defined(__PLATFORM_WIN32__) | ||
| 789 | isDirectory = de->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; | ||
| 790 | isRegular = ((de->data.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) || | ||
| 791 | (de->data.dwFileAttributes & FILE_ATTRIBUTE_READONLY) || | ||
| 792 | (de->data.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE)); | ||
| 793 | #elif defined(__WINDOWS_PTHREAD__) // Cygwin -- doesn't have dirent d_type | ||
| 794 | std::string absolute_path = std::string(directory) + "/" + de->d_name; | ||
| 795 | struct stat st; | ||
| 796 | if( stat(absolute_path.c_str(), &st) == 0 ) | ||
| 797 | { | ||
| 798 | isDirectory = st.st_mode & S_IFDIR; | ||
| 799 | isRegular = st.st_mode & S_IFREG; | ||
| 800 | } | ||
| 801 | else | ||
| 802 | { | ||
| 803 | // uhh ... | ||
| 804 | EM_log( CK_LOG_INFO, | ||
| 805 | "unable to open file '%s', ignoring for chugins", | ||
| 806 | absolute_path.c_str() ); | ||
| 807 | return false; | ||
| 808 | } | ||
| 809 | #else | ||
| 810 | isDirectory = de->d_type == DT_DIR; | ||
| 811 | isRegular = de->d_type == DT_REG; | ||
| 812 | #endif | ||
| 813 | |||
| 814 | return true; | ||
| 815 | } | ||
| 816 | |||
| 817 | |||
| 818 | |||
| 819 | |||
| 748 | //----------------------------------------------------------------------------- | 820 | //----------------------------------------------------------------------------- |
| 749 | // name: load_external_module_at_path() | 821 | // name: load_external_module_at_path() |
| 750 | // desc: ... | 822 | // desc: ... |
| @@ -789,116 +861,82 @@ t_CKBOOL load_external_module_at_path( Chuck_Compiler * compiler, · 38 unmodified lines | |||
| 789 | 861 | ||
| 790 | //----------------------------------------------------------------------------- | 862 | //----------------------------------------------------------------------------- |
| 791 | // name: load_external_modules_in_directory() | 863 | // name: load_external_modules_in_directory() |
| 792 | // desc: ... | 864 | // desc: load all external modules by extension within a directory |
| 793 | //----------------------------------------------------------------------------- | 865 | //----------------------------------------------------------------------------- |
| 794 | t_CKBOOL load_external_modules_in_directory( Chuck_Compiler * compiler, | 866 | t_CKBOOL load_external_modules_in_directory( Chuck_Compiler * compiler, |
| 795 | const char * directory, | 867 | const char * directory, |
| 796 | const char * extension ) | 868 | const char * extension, |
| 869 | t_CKBOOL recursiveSearch = FALSE ) | ||
| 797 | { | 870 | { |
| 798 | static const t_CKBOOL RECURSIVE_SEARCH = false; | 871 | // expand directory path |
| 799 | 872 | string path = expandFilePath( directory ); | |
| 800 | // directory path | ||
| 801 | string path = directory, exp = ""; | ||
| 802 | |||
| 803 | #ifndef __PLATFORM_WIN32__ | ||
| 804 | #ifndef __DISABLE_WORDEXP__ | ||
| 805 | // 1.5.0.0 (ge) added (for ~) | ||
| 806 | wordexp_t exp_result; | ||
| 807 | // "perform shell-style word expansions" | ||
| 808 | wordexp( directory, &exp_result, 0 ); | ||
| 809 | // concatenate in case there are spaces in the path | ||
| 810 | for( t_CKINT i = 0; i < exp_result.we_wordc; i++ ) | ||
| 811 | exp += string(i > 0 ? " " : "") + exp_result.we_wordv[i]; | ||
| 812 | // replace | ||
| 813 | path = exp; | ||
| 814 | #endif | ||
| 815 | #endif | ||
| 816 | |||
| 817 | // open the directory | 873 | // open the directory |
| 818 | DIR * dir = opendir( path.c_str() ); | 874 | DIR * dir = opendir( path.c_str() ); |
| 819 | 875 | ||
| 876 | // log | ||
| 877 | EM_log( CK_LOG_INFO, "examining directory for chugins..." ); | ||
| 878 | // push | ||
| 879 | EM_pushlog(); | ||
| 880 | // print directory to examine | ||
| 881 | EM_log( CK_LOG_INFO, "'%s'", directory ); | ||
| 882 | |||
| 820 | // if successful | 883 | // if successful |
| 821 | if( dir ) | 884 | if( dir ) |
| 822 | { | 885 | { |
| 823 | // log | ||
| 824 | EM_log( CK_LOG_INFO, "examining directory '%s' for chugins", directory ); | ||
| 825 | |||
| 826 | // do first read | 1.5.0.0 (ge + eito) #chunreal | 886 | // do first read | 1.5.0.0 (ge + eito) #chunreal |
| 827 | struct dirent * de = readdir(dir); | 887 | struct dirent * de = readdir(dir); |
| 828 | 888 | // while( (de = readdir(dir)) ) <- UE5 forces us to not do this | |
| 829 | // while( (de = readdir(dir)) ) <- in ge's opinion clearer than what UE5 forces us to do | ||
| 830 | while( de != NULL ) | 889 | while( de != NULL ) |
| 831 | { | 890 | { |
| 832 | t_CKBOOL is_regular = false; | 891 | t_CKBOOL is_regular = false; |
| 833 | t_CKBOOL is_directory = false; | 892 | t_CKBOOL is_directory = false; |
| 893 | // get attributes | ||
| 894 | if( !getDirEntryAttribute( de, is_directory, is_regular ) ) continue; | ||
| 834 | 895 | ||
| 835 | #if defined(__PLATFORM_WIN32__) | 896 | // check | TODO: follow links? |
| 836 | is_directory = de->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; | 897 | if( is_regular ) |
| 837 | is_regular = ((de->data.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) || | ||
| 838 | (de->data.dwFileAttributes & FILE_ATTRIBUTE_READONLY) || | ||
| 839 | (de->data.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE)); | ||
| 840 | #elif defined(__WINDOWS_PTHREAD__) // Cygwin -- doesn't have dirent d_type | ||
| 841 | std::string absolute_path = std::string(directory) + "/" + de->d_name; | ||
| 842 | struct stat st; | ||
| 843 | if( stat(absolute_path.c_str(), &st) == 0 ) | ||
| 844 | { | ||
| 845 | is_directory = st.st_mode & S_IFDIR; | ||
| 846 | is_regular = st.st_mode & S_IFREG; | ||
| 847 | } | ||
| 848 | else | ||
| 849 | { | ||
| 850 | // uhh ... | ||
| 851 | EM_log( CK_LOG_INFO, | ||
| 852 | "unable to open file '%s', ignoring for chugins", | ||
| 853 | absolute_path.c_str() ); | ||
| 854 | continue; | ||
| 855 | } | ||
| 856 | #else | ||
| 857 | is_directory = de->d_type == DT_DIR; | ||
| 858 | is_regular = de->d_type == DT_REG; | ||
| 859 | #endif | ||
| 860 | |||
| 861 | if( is_regular ) // TODO: follow links? | ||
| 862 | { | 898 | { |
| 863 | if( extension_matches(de->d_name, extension) ) | 899 | // check for ck files to pre-load |
| 900 | if( extension_matches(de->d_name, ".ck") ) | ||
| 864 | { | 901 | { |
| 902 | // construct absolute path | ||
| 865 | std::string absolute_path = std::string(directory) + "/" + de->d_name; | 903 | std::string absolute_path = std::string(directory) + "/" + de->d_name; |
| 866 | 904 | // append file path | |
| 867 | load_external_module_at_path(compiler, de->d_name, | 905 | compiler->m_cklibs_to_preload.push_back(absolute_path); |
| 868 | absolute_path.c_str()); | ||
| 869 | } | 906 | } |
| 870 | else if( extension_matches(de->d_name, ".ck") ) | 907 | // check extension passed in |
| 908 | else if( extension_matches(de->d_name, extension) ) | ||
| 871 | { | 909 | { |
| 910 | // construct absolute path | ||
| 872 | std::string absolute_path = std::string(directory) + "/" + de->d_name; | 911 | std::string absolute_path = std::string(directory) + "/" + de->d_name; |
| 873 | compiler->m_cklibs_to_preload.push_back(absolute_path); | 912 | // load module |
| 913 | load_external_module_at_path( compiler, de->d_name, absolute_path.c_str() ); | ||
| 874 | } | 914 | } |
| 875 | } | 915 | } |
| 876 | else if( RECURSIVE_SEARCH && is_directory ) | 916 | else if( recursiveSearch && is_directory ) |
| 877 | { | 917 | { |
| 878 | // recurse | 918 | // recurse | TODO: max depth? |
| 879 | // TODO: max depth? | ||
| 880 | if( strncmp(de->d_name, ".", sizeof(".")) != 0 && | 919 | if( strncmp(de->d_name, ".", sizeof(".")) != 0 && |
| 881 | strncmp(de->d_name, "..", sizeof("..")) != 0 ) | 920 | strncmp(de->d_name, "..", sizeof("..")) != 0 ) |
| 882 | { | 921 | { |
| 922 | // construct absolute path | ||
| 883 | std::string absolute_path = std::string(directory) + "/" + de->d_name; | 923 | std::string absolute_path = std::string(directory) + "/" + de->d_name; |
| 884 | load_external_modules_in_directory(compiler, | 924 | // search in sub-directory |
| 885 | absolute_path.c_str(), | 925 | load_external_modules_in_directory( compiler, absolute_path.c_str(), extension); |
| 886 | extension); | ||
| 887 | } | 926 | } |
| 888 | } | 927 | } |
| 889 | #ifdef __PLATFORM_MACOSX__ | 928 | #ifdef __PLATFORM_MACOSX__ |
| 890 | // #if __APPLE__ probably cleaner but using the above for consistency for now (ge) | 929 | else if( is_directory && extension_matches(de->d_name, extension) ) |
| 891 | // --- | 930 | { |
| 892 | // On macOS, a chugin can either be a regular file (a .dylib simply renamed to .chug) | 931 | // On macOS, a chugin can either be a regular file (a .dylib simply renamed to .chug) |
| 893 | // or it can be a MODULE like using CMake with add_library(FooChugin MODULE foo.cpp) | 932 | // or it can be a MODULE like using CMake with add_library(FooChugin MODULE foo.cpp) |
| 894 | // If it's a module bundle, then because .chug is a nonstandard extension, | 933 | // If it's a module bundle, then because .chug is a nonstandard extension, |
| 895 | // on the filesystem it shows up as a directory ending in .chug. | 934 | // on the filesystem it shows up as a directory ending in .chug. |
| 896 | // If we see one of these directories, we can dive directly to the Contents/MacOS subfolder | 935 | // If we see one of these directories, we can dive directly to the Contents/MacOS subfolder |
| 897 | // and look for a regular file. | 1.5.0.1 (dbraun) added | 936 | // and look for a regular file. | 1.5.0.1 (dbraun) added |
| 898 | else if (is_directory && extension_matches(de->d_name, extension)) { | ||
| 899 | std::string absolute_path = std::string(directory) + "/" + de->d_name + "/Contents/MacOS"; | 937 | std::string absolute_path = std::string(directory) + "/" + de->d_name + "/Contents/MacOS"; |
| 900 | const char* subdirectory = absolute_path.c_str(); | 938 | const char * subdirectory = absolute_path.c_str(); |
| 901 | load_external_modules_in_directory(compiler, subdirectory, ""); | 939 | load_external_modules_in_directory( compiler, subdirectory, "" ); |
| 902 | } | 940 | } |
| 903 | #endif // #ifdef __PLATFORM_MACOSX__ | 941 | #endif // #ifdef __PLATFORM_MACOSX__ |
| 904 | 942 | ||
| @@ -912,19 +950,14 @@ t_CKBOOL load_external_modules_in_directory( Chuck_Compiler * compiler, · 7 unmodified lines | |||
| 912 | else | 950 | else |
| 913 | { | 951 | { |
| 914 | // log (1.3.1.2: changed to 2 lines to stay within 80 chars) | 952 | // log (1.3.1.2: changed to 2 lines to stay within 80 chars) |
| 915 | EM_log( CK_LOG_INFO, "unable to open directory:" ); | ||
| 916 | EM_pushlog(); | 953 | EM_pushlog(); |
| 917 | EM_log( CK_LOG_INFO, "'%s'", directory ); | 954 | EM_log( CK_LOG_INFO, "unable to open directory..." ); |
| 918 | EM_log( CK_LOG_INFO, "ignoring for chugins..." ); | 955 | EM_log( CK_LOG_INFO, "ignoring for chugins..." ); |
| 919 | EM_poplog(); | 956 | EM_poplog(); |
| 920 | } | 957 | } |
| 921 | 958 | ||
| 922 | #ifndef __PLATFORM_WIN32__ | 959 | // pop log |
| 923 | #ifndef __DISABLE_WORDEXP__ | 960 | EM_poplog(); |
| 924 | // free | 1.5.0.0 (ge) added | ||
| 925 | wordfree( &exp_result ); | ||
| 926 | #endif | ||
| 927 | #endif | ||
| 928 | 961 | ||
| 929 | return TRUE; | 962 | return TRUE; |
| 930 | } | 963 | } |
| @@ -934,11 +967,12 @@ t_CKBOOL load_external_modules_in_directory( Chuck_Compiler * compiler, · 3 unmodified lines | |||
| 934 | 967 | ||
| 935 | //----------------------------------------------------------------------------- | 968 | //----------------------------------------------------------------------------- |
| 936 | // name: load_external_modules() | 969 | // name: load_external_modules() |
| 937 | // desc: ... | 970 | // desc: load external modules (e.g., .chug and .ck library files) |
| 938 | //----------------------------------------------------------------------------- | 971 | //----------------------------------------------------------------------------- |
| 939 | t_CKBOOL Chuck_Compiler:: load_external_modules( const char * extension, | 972 | t_CKBOOL Chuck_Compiler::load_external_modules( const char * extension, |
| 940 | std::list<std::string> & chugin_search_paths, | 973 | std::list<std::string> & chugin_search_paths, |
| 941 | std::list<std::string> & named_dls ) | 974 | std::list<std::string> & named_dls, |
| 975 | t_CKBOOL recursiveSearch ) | ||
| 942 | { | 976 | { |
| 943 | // get env | 977 | // get env |
| 944 | Chuck_Env * env = this->env(); | 978 | Chuck_Env * env = this->env(); |
| @@ -949,23 +983,25 @@ t_CKBOOL Chuck_Compiler:: load_external_modules( const char * extension, · 4 unmodified lines | |||
| 949 | // load it | 983 | // load it |
| 950 | type_engine_load_context( env, context ); | 984 | type_engine_load_context( env, context ); |
| 951 | 985 | ||
| 952 | /* first load dynamic libraries explicitly named on the command line */ | 986 | // first load dynamic libraries explicitly named on the command line |
| 953 | for(std::list<std::string>::iterator i_dl = named_dls.begin(); | 987 | for( std::list<std::string>::iterator i_dl = named_dls.begin(); |
| 954 | i_dl != named_dls.end(); i_dl++) | 988 | i_dl != named_dls.end(); i_dl++ ) |
| 955 | { | 989 | { |
| 990 | // get chugin name | ||
| 956 | std::string & dl_path = *i_dl; | 991 | std::string & dl_path = *i_dl; |
| 957 | if(!extension_matches(dl_path.c_str(), extension)) | 992 | // check extension, append if no match |
| 993 | if( !extension_matches(dl_path.c_str(), extension) ) | ||
| 958 | dl_path += extension; | 994 | dl_path += extension; |
| 959 | 995 | // load the module | |
| 960 | load_external_module_at_path(this, dl_path.c_str(), | 996 | load_external_module_at_path( this, dl_path.c_str(), dl_path.c_str() ); |
| 961 | dl_path.c_str()); | ||
| 962 | } | 997 | } |
| 963 | 998 | ||
| 964 | /* now recurse through search paths and load any DLs or .ck files found */ | 999 | // now recurse through search paths and load any DLs or .ck files found |
| 965 | for(std::list<std::string>::iterator i_sp = chugin_search_paths.begin(); | 1000 | for( std::list<std::string>::iterator i_sp = chugin_search_paths.begin(); |
| 966 | i_sp != chugin_search_paths.end(); i_sp++) | 1001 | i_sp != chugin_search_paths.end(); i_sp++ ) |
| 967 | { | 1002 | { |
| 968 | load_external_modules_in_directory(this, (*i_sp).c_str(), extension); | 1003 | // search directory and load contents |
| 1004 | load_external_modules_in_directory( this, (*i_sp).c_str(), extension, recursiveSearch ); | ||
| 969 | } | 1005 | } |
| 970 | 1006 | ||
| 971 | // clear context | 1007 | // clear context |
| @@ -975,18 +1011,207 @@ t_CKBOOL Chuck_Compiler:: load_external_modules( const char * extension, · 3 unmodified lines | |||
| 975 | env->global()->commit(); | 1011 | env->global()->commit(); |
| 976 | 1012 | ||
| 977 | return TRUE; | 1013 | return TRUE; |
| 978 | /* | 1014 | } |
| 979 | error: | ||
| 980 | 1015 | ||
| 981 | // probably dangerous: rollback | ||
| 982 | env->global()->rollback(); | ||
| 983 | 1016 | ||
| 984 | // clear context | ||
| 985 | type_engine_unload_context( env ); | ||
| 986 | 1017 | ||
| 987 | // pop indent level | 1018 | |
| 1019 | //----------------------------------------------------------------------------- | ||
| 1020 | // name: probe_external_module_at_path() | ||
| 1021 | // desc: probe external module | ||
| 1022 | //----------------------------------------------------------------------------- | ||
| 1023 | t_CKBOOL probe_external_module_at_path( const char * name, const char * dl_path ) | ||
| 1024 | { | ||
| 1025 | // create dynamic module | ||
| 1026 | Chuck_DLL * dll = new Chuck_DLL( NULL, name ); | ||
| 1027 | |||
| 1028 | // load the dll, lazy mode | ||
| 1029 | if( dll->load(dl_path, CK_QUERY_FUNC, TRUE) ) | ||
| 1030 | { | ||
| 1031 | // probe it | ||
| 1032 | dll->probe(); | ||
| 1033 | |||
| 1034 | EM_log( CK_LOG_SYSTEM, "chugin %s [version %d.%d]", name, dll->versionMajor(), dll->versionMinor() ); | ||
| 1035 | // if not compatible | ||
| 1036 | if( !dll->compatible() ) | ||
| 1037 | { | ||
| 1038 | // push | ||
| 1039 | EM_pushlog(); | ||
| 1040 | EM_log( CK_LOG_SYSTEM, "VERSION MISMATCH with host %d.%d", CK_DLL_VERSION_MAJOR, CK_DLL_VERSION_MINOR ); | ||
| 1041 | EM_poplog(); | ||
| 1042 | } | ||
| 1043 | } | ||
| 1044 | else | ||
| 1045 | { | ||
| 1046 | |||
| 1047 | EM_log( CK_LOG_SYSTEM, "chugin: '%s' FAILED to load...", name ); | ||
| 1048 | } | ||
| 1049 | |||
| 1050 | // done | ||
| 1051 | return TRUE; | ||
| 1052 | } | ||
| 1053 | |||
| 1054 | |||
| 1055 | |||
| 1056 | |||
| 1057 | //----------------------------------------------------------------------------- | ||
| 1058 | // name: probe_external_modules_in_directory() | ||
| 1059 | // desc: probe all external modules by extension within a directory | ||
| 1060 | //----------------------------------------------------------------------------- | ||
| 1061 | t_CKBOOL probe_external_modules_in_directory( const char * directory, | ||
| 1062 | const char * extension, | ||
| 1063 | t_CKBOOL recursiveSearch, | ||
| 1064 | std::list<std::string> & ck_libs ) | ||
| 1065 | { | ||
| 1066 | // expand directory path | ||
| 1067 | string path = expandFilePath( directory ); | ||
| 1068 | // open the directory | ||
| 1069 | DIR * dir = opendir( path.c_str() ); | ||
| 1070 | |||
| 1071 | // log | ||
| 1072 | // EM_log( CK_LOG_SYSTEM, "examining directory for chugins..." ); | ||
| 1073 | // print directory to examine | ||
| 1074 | EM_log( CK_LOG_SYSTEM, "%s", directory ); | ||
| 1075 | // push | ||
| 1076 | EM_pushlog(); | ||
| 1077 | |||
| 1078 | // if successful | ||
| 1079 | if( dir ) | ||
| 1080 | { | ||
| 1081 | // do first read | 1.5.0.0 (ge + eito) #chunreal | ||
| 1082 | struct dirent * de = readdir(dir); | ||
| 1083 | // while( (de = readdir(dir)) ) <- UE5 forces us to not do this | ||
| 1084 | while( de != NULL ) | ||
| 1085 | { | ||
| 1086 | t_CKBOOL is_regular = false; | ||
| 1087 | t_CKBOOL is_directory = false; | ||
| 1088 | // get attributes | ||
| 1089 | if( !getDirEntryAttribute( de, is_directory, is_regular ) ) continue; | ||
| 1090 | |||
| 1091 | // check | TODO: follow links? | ||
| 1092 | if( is_regular ) | ||
| 1093 | { | ||
| 1094 | // check for ck files to pre-load | ||
| 1095 | if( extension_matches(de->d_name, ".ck") ) | ||
| 1096 | { | ||
| 1097 | |||
| 1098 | // EM_log( CK_LOG_SYSTEM, "module %s", de->d_name ); | ||
| 1099 | |||
| 1100 | // construct absolute path | ||
| 1101 | std::string absolute_path = std::string(directory) + "/" + de->d_name; | ||
| 1102 | // append file path | ||
| 1103 | ck_libs.push_back(absolute_path); | ||
| 1104 | } | ||
| 1105 | // check extension passed in | ||
| 1106 | else if( extension_matches(de->d_name, extension) ) | ||
| 1107 | { | ||
| 1108 | // construct absolute path | ||
| 1109 | std::string absolute_path = std::string(directory) + "/" + de->d_name; | ||
| 1110 | // load module | ||
| 1111 | probe_external_module_at_path( de->d_name, absolute_path.c_str() ); | ||
| 1112 | } | ||
| 1113 | } | ||
| 1114 | else if( recursiveSearch && is_directory ) | ||
| 1115 | { | ||
| 1116 | // recurse | TODO: max depth? | ||
| 1117 | if( strncmp(de->d_name, ".", sizeof(".")) != 0 && | ||
| 1118 | strncmp(de->d_name, "..", sizeof("..")) != 0 ) | ||
| 1119 | { | ||
| 1120 | // construct absolute path | ||
| 1121 | std::string absolute_path = std::string(directory) + "/" + de->d_name; | ||
| 1122 | // search in sub-directory | ||
| 1123 | probe_external_modules_in_directory( absolute_path.c_str(), extension, TRUE, ck_libs ); | ||
| 1124 | } | ||
| 1125 | } | ||
| 1126 | #ifdef __PLATFORM_MACOSX__ | ||
| 1127 | else if( is_directory && extension_matches(de->d_name, extension) ) | ||
| 1128 | { | ||
| 1129 | // On macOS, a chugin can either be a regular file (a .dylib simply renamed to .chug) | ||
| 1130 | // or it can be a MODULE like using CMake with add_library(FooChugin MODULE foo.cpp) | ||
| 1131 | // If it's a module bundle, then because .chug is a nonstandard extension, | ||
| 1132 | // on the filesystem it shows up as a directory ending in .chug. | ||
| 1133 | // If we see one of these directories, we can dive directly to the Contents/MacOS subfolder | ||
| 1134 | // and look for a regular file. | 1.5.0.1 (dbraun) added | ||
| 1135 | std::string absolute_path = std::string(directory) + "/" + de->d_name + "/Contents/MacOS"; | ||
| 1136 | const char * subdirectory = absolute_path.c_str(); | ||
| 1137 | probe_external_modules_in_directory( subdirectory, "", FALSE, ck_libs ); | ||
| 1138 | } | ||
| 1139 | #endif // #ifdef __PLATFORM_MACOSX__ | ||
| 1140 | |||
| 1141 | // read next | 1.5.0.0 (ge) moved here due to #chunreal | ||
| 1142 | de = readdir( dir ); | ||
| 1143 | } | ||
| 1144 | |||
| 1145 | // close | ||
| 1146 | closedir( dir ); | ||
| 1147 | } | ||
| 1148 | else | ||
| 1149 | { | ||
| 1150 | // log (1.3.1.2: changed to 2 lines to stay within 80 chars) | ||
| 1151 | EM_pushlog(); | ||
| 1152 | EM_log( CK_LOG_SYSTEM, "unable to open directory..." ); | ||
| 1153 | EM_log( CK_LOG_SYSTEM, "ignoring for chugins..." ); | ||
| 1154 | EM_poplog(); | ||
| 1155 | } | ||
| 1156 | |||
| 1157 | // pop log | ||
| 988 | EM_poplog(); | 1158 | EM_poplog(); |
| 989 | 1159 | ||
| 990 | return FALSE; | 1160 | return TRUE; |
| 991 | */ | 1161 | } |
| 1162 | |||
| 1163 | |||
| 1164 | |||
| 1165 | |||
| 1166 | //----------------------------------------------------------------------------- | ||
| 1167 | // name: probe_external_modules() | ||
| 1168 | // desc: probe external modules (e.g., .chug and .ck library files) | ||
| 1169 | //----------------------------------------------------------------------------- | ||
| 1170 | t_CKBOOL Chuck_Compiler::probe_external_modules( const char * extension, | ||
| 1171 | std::list<std::string> & chugin_search_paths, | ||
| 1172 | std::list<std::string> & named_dls, | ||
| 1173 | t_CKBOOL recursiveSearch, | ||
| 1174 | std::list<std::string> & ck_libs ) | ||
| 1175 | { | ||
| 1176 | |||
| 1177 | EM_log( CK_LOG_SYSTEM, "probing specified chugins..." ); | ||
| 1178 | // push | ||
| 1179 | EM_pushlog(); | ||
| 1180 | |||
| 1181 | // first load dynamic libraries explicitly named on the command line | ||
| 1182 | for( std::list<std::string>::iterator i_dl = named_dls.begin(); | ||
| 1183 | i_dl != named_dls.end(); i_dl++ ) | ||
| 1184 | { | ||
| 1185 | // get chugin name | ||
| 1186 | std::string & dl_path = *i_dl; | ||
| 1187 | // check extension, append if no match | ||
| 1188 | if( !extension_matches(dl_path.c_str(), extension) ) | ||
| 1189 | dl_path += extension; | ||
| 1190 | // load the module | ||
| 1191 | probe_external_module_at_path( dl_path.c_str(), dl_path.c_str() ); | ||
| 1192 | } | ||
| 1193 | |||
| 1194 | // check | ||
| 1195 | if( named_dls.size() == 0 ) | ||
| 1196 | EM_log( CK_LOG_SYSTEM, "(none specified)" ); | ||
| 1197 | |||
| 1198 | // pop | ||
| 1199 | EM_poplog(); | ||
| 1200 | |||
| 1201 | EM_log( CK_LOG_SYSTEM, "probing chugins in search paths..." ); | ||
| 1202 | // push | ||
| 1203 | EM_pushlog(); | ||
| 1204 | |||
| 1205 | // now recurse through search paths and load any DLs or .ck files found | ||
| 1206 | for( std::list<std::string>::iterator i_sp = chugin_search_paths.begin(); | ||
| 1207 | i_sp != chugin_search_paths.end(); i_sp++ ) | ||
| 1208 | { | ||
| 1209 | // search directory and load contents | ||
| 1210 | probe_external_modules_in_directory( (*i_sp).c_str(), extension, recursiveSearch, ck_libs ); | ||
| 1211 | } | ||
| 1212 | |||
| 1213 | // pop | ||
| 1214 | EM_poplog(); | ||
| 1215 | |||
| 1216 | return TRUE; | ||
| 992 | } | 1217 | } |
| @@ -123,10 +123,19 @@ public: // replace-dac | added 1.4.1.0 (jack) · 122 unmodified lines | |||
| 123 | // of a new sample sucker. | 123 | // of a new sample sucker. |
| 124 | void setReplaceDac( t_CKBOOL shouldReplaceDac, const std::string & replacement ); | 124 | void setReplaceDac( t_CKBOOL shouldReplaceDac, const std::string & replacement ); |
| 125 | 125 | ||
| 126 | public: // chugin load | refactored 1.4.1.0 (ge) | 126 | public: |
| 127 | // chugin load | 1.4.1.0 (ge) refactored | ||
| 127 | t_CKBOOL load_external_modules( const char * extension, | 128 | t_CKBOOL load_external_modules( const char * extension, |
| 128 | std::list<std::string> & chugin_search_paths, | 129 | std::list<std::string> & chugin_search_paths, |
| 129 | std::list<std::string> & named_dls ); | 130 | std::list<std::string> & named_dls, |
| 131 | t_CKBOOL recursiveSearch ); | ||
| 132 | |||
| 133 | // chugin probe | 1.5.0.4 (ge) added | ||
| 134 | static t_CKBOOL probe_external_modules( const char * extension, | ||
| 135 | std::list<std::string> & chugin_search_paths, | ||
| 136 | std::list<std::string> & named_dls, | ||
| 137 | t_CKBOOL recursiveSearch, | ||
| 138 | std::list<std::string> & ck_libs ); | ||
| 130 | 139 | ||
| 131 | protected: // internal | 140 | protected: // internal |
| 132 | // do entire file | 141 | // do entire file |
| @@ -719,7 +719,7 @@ t_CKBOOL Chuck_DLL::good() const · 718 unmodified lines | |||
| 719 | // name: query() | 719 | // name: query() |
| 720 | // desc: ... | 720 | // desc: ... |
| 721 | //----------------------------------------------------------------------------- | 721 | //----------------------------------------------------------------------------- |
| 722 | const Chuck_DL_Query * Chuck_DLL::query( ) | 722 | const Chuck_DL_Query * Chuck_DLL::query() |
| 723 | { | 723 | { |
| 724 | if( !m_handle && !m_query_func ) | 724 | if( !m_handle && !m_query_func ) |
| 725 | { | 725 | { |
| @@ -738,38 +738,38 @@ const Chuck_DL_Query * Chuck_DLL::query( ) · 12 unmodified lines | |||
| 738 | m_version_func = (f_ck_declversion)this->get_addr( (string("_")+CK_DECLVERSION_FUNC).c_str() ); | 738 | m_version_func = (f_ck_declversion)this->get_addr( (string("_")+CK_DECLVERSION_FUNC).c_str() ); |
| 739 | if( !m_version_func ) | 739 | if( !m_version_func ) |
| 740 | { | 740 | { |
| 741 | m_last_error = string("no version function found in dll '") | 741 | m_last_error = string("no version function found in dll '") + m_filename + string("'"); |
| 742 | + m_filename + string("'"); | ||
| 743 | return NULL; | 742 | return NULL; |
| 744 | } | 743 | } |
| 745 | 744 | ||
| 746 | // check version | 745 | // check version |
| 747 | t_CKUINT dll_version = m_version_func(); | 746 | t_CKUINT dll_version = m_version_func(); |
| 747 | // get major and minor version numbers | ||
| 748 | m_versionMajor = CK_DLL_VERSION_GETMAJOR(dll_version); | ||
| 749 | m_versionMinor = CK_DLL_VERSION_GETMINOR(dll_version); | ||
| 750 | // is version ok | ||
| 748 | t_CKBOOL version_ok = FALSE; | 751 | t_CKBOOL version_ok = FALSE; |
| 749 | // major version must be same | 752 | // major version must be same; minor version must less than or equal |
| 750 | // minor version must less than or equal | 753 | if( m_versionMajor == CK_DLL_VERSION_MAJOR && m_versionMinor <= CK_DLL_VERSION_MINOR) |
| 751 | if(CK_DLL_VERSION_GETMAJOR(dll_version) == CK_DLL_VERSION_MAJOR && | ||
| 752 | CK_DLL_VERSION_GETMINOR(dll_version) <= CK_DLL_VERSION_MINOR) | ||
| 753 | version_ok = TRUE; | 754 | version_ok = TRUE; |
| 754 | 755 | ||
| 755 | if(!version_ok) | 756 | // if version not okay |
| 756 | // SPENCERTODO: do they need to be equal, or can dll_version be < ? | 757 | if( !version_ok ) |
| 757 | { | 758 | { |
| 759 | // construct error string | ||
| 758 | ostringstream oss; | 760 | ostringstream oss; |
| 759 | oss << "chugin version mismatch:" << endl | 761 | oss << "chugin version mismatch:" << endl |
| 760 | << "filename: " | 762 | << "filename: " |
| 761 | << m_filename << "'" << endl | 763 | << m_filename << "'" << endl |
| 762 | << "versions: chugin: " | 764 | << "versions: chugin: " |
| 763 | << CK_DLL_VERSION_GETMAJOR(dll_version) | 765 | << CK_DLL_VERSION_GETMAJOR(dll_version) |
| 764 | << "." | 766 | << "." |
| 765 | << CK_DLL_VERSION_GETMINOR(dll_version) | 767 | << CK_DLL_VERSION_GETMINOR(dll_version) |
| 766 | << " vs. chuck host: " | 768 | << " vs. chuck host: " |
| 767 | << CK_DLL_VERSION_MAJOR | 769 | << CK_DLL_VERSION_MAJOR |
| 768 | << "." | 770 | << "." |
| 769 | << CK_DLL_VERSION_MINOR; | 771 | << CK_DLL_VERSION_MINOR; |
| 770 | |||
| 771 | m_last_error = oss.str(); | 772 | m_last_error = oss.str(); |
| 772 | |||
| 773 | return NULL; | 773 | return NULL; |
| 774 | } | 774 | } |
| 775 | 775 | ||
| @@ -780,8 +780,7 @@ const Chuck_DL_Query * Chuck_DLL::query( ) · 4 unmodified lines | |||
| 780 | m_query_func = (f_ck_query)this->get_addr( (string("_")+m_func).c_str() ); | 780 | m_query_func = (f_ck_query)this->get_addr( (string("_")+m_func).c_str() ); |
| 781 | if( !m_query_func ) | 781 | if( !m_query_func ) |
| 782 | { | 782 | { |
| 783 | m_last_error = string("no query function found in dll '") | 783 | m_last_error = string("no query function found in dll '") + m_filename + string("'"); |
| 784 | + m_filename + string("'"); | ||
| 785 | return NULL; | 784 | return NULL; |
| 786 | } | 785 | } |
| 787 | 786 | ||
| @@ -861,6 +860,41 @@ const Chuck_DL_Query * Chuck_DLL::query( ) · 73 unmodified lines | |||
| 861 | 860 | ||
| 862 | 861 | ||
| 863 | 862 | ||
| 863 | //----------------------------------------------------------------------------- | ||
| 864 | // name: probe() | ||
| 865 | // desc: probe the dll without fully loading its content | ||
| 866 | //----------------------------------------------------------------------------- | ||
| 867 | t_CKBOOL Chuck_DLL::probe() | ||
| 868 | { | ||
| 869 | if( !m_handle && !m_query_func ) | ||
| 870 | { | ||
| 871 | m_last_error = "dynamic link library not loaded for query..."; | ||
| 872 | return FALSE; | ||
| 873 | } | ||
| 874 | |||
| 875 | // get the address of the DL version function from the DLL | ||
| 876 | if( !m_version_func ) | ||
| 877 | m_version_func = (f_ck_declversion)this->get_addr( CK_DECLVERSION_FUNC ); | ||
| 878 | if( !m_version_func ) | ||
| 879 | m_version_func = (f_ck_declversion)this->get_addr( (string("_")+CK_DECLVERSION_FUNC).c_str() ); | ||
| 880 | if( !m_version_func ) | ||
| 881 | { | ||
| 882 | m_last_error = string("no version function found in dll '") + m_filename + string("'"); | ||
| 883 | return FALSE; | ||
| 884 | } | ||
| 885 | |||
| 886 | // check version | ||
| 887 | t_CKUINT dll_version = m_version_func(); | ||
| 888 | // get major and minor version numbers | ||
| 889 | m_versionMajor = CK_DLL_VERSION_GETMAJOR(dll_version); | ||
| 890 | m_versionMinor = CK_DLL_VERSION_GETMINOR(dll_version); | ||
| 891 | |||
| 892 | return TRUE; | ||
| 893 | } | ||
| 894 | |||
| 895 | |||
| 896 | |||
| 897 | |||
| 864 | //----------------------------------------------------------------------------- | 898 | //----------------------------------------------------------------------------- |
| 865 | // name: unload() | 899 | // name: unload() |
| 866 | // desc: ... | 900 | // desc: ... |
| @@ -921,7 +955,7 @@ const char * Chuck_DLL::last_error() const · 54 unmodified lines | |||
| 921 | 955 | ||
| 922 | //----------------------------------------------------------------------------- | 956 | //----------------------------------------------------------------------------- |
| 923 | // name: name() | 957 | // name: name() |
| 924 | // desc: ... | 958 | // desc: return name given to dll |
| 925 | //----------------------------------------------------------------------------- | 959 | //----------------------------------------------------------------------------- |
| 926 | const char * Chuck_DLL::name() const | 960 | const char * Chuck_DLL::name() const |
| 927 | { | 961 | { |
| @@ -929,7 +963,53 @@ const char * Chuck_DLL::name() const · 1 unmodified line | |||
| 929 | } | 963 | } |
| 930 | 964 | ||
| 931 | 965 | ||
| 932 | //const t_CKUINT Chuck_DL_Query::RESERVED_SIZE; | 966 | |
| 967 | |||
| 968 | //----------------------------------------------------------------------------- | ||
| 969 | // name: versionMajor() | ||
| 970 | // desc: get version major | ||
| 971 | //----------------------------------------------------------------------------- | ||
| 972 | t_CKUINT Chuck_DLL::versionMajor() | ||
| 973 | { | ||
| 974 | // probe dll | ||
| 975 | if( !this->probe() ) return 0; | ||
| 976 | // return | ||
| 977 | return m_versionMajor; | ||
| 978 | } | ||
| 979 | |||
| 980 | |||
| 981 | |||
| 982 | |||
| 983 | //----------------------------------------------------------------------------- | ||
| 984 | // name: versionMinor() | ||
| 985 | // desc: get version minor | ||
| 986 | //----------------------------------------------------------------------------- | ||
| 987 | t_CKUINT Chuck_DLL::versionMinor() | ||
| 988 | { | ||
| 989 | // probe dll | ||
| 990 | if( !this->probe() ) return 0; | ||
| 991 | // return | ||
| 992 | return m_versionMinor; | ||
| 993 | } | ||
| 994 | |||
| 995 | |||
| 996 | |||
| 997 | |||
| 998 | //----------------------------------------------------------------------------- | ||
| 999 | // name: compatible() | ||
| 1000 | // desc: if version compatible between chugin and host | ||
| 1001 | //----------------------------------------------------------------------------- | ||
| 1002 | t_CKBOOL Chuck_DLL::compatible() | ||
| 1003 | { | ||
| 1004 | // probe dll | ||
| 1005 | if( !this->probe() ) return FALSE; | ||
| 1006 | // major version must be same between chugin and host | ||
| 1007 | // chugin minor version must less than or equal host minor version | ||
| 1008 | return ( m_versionMajor == CK_DLL_VERSION_MAJOR && m_versionMinor <= CK_DLL_VERSION_MINOR ); | ||
| 1009 | } | ||
| 1010 | |||
| 1011 | |||
| 1012 | |||
| 933 | 1013 | ||
| 934 | //----------------------------------------------------------------------------- | 1014 | //----------------------------------------------------------------------------- |
| 935 | // name: Chuck_DL_Query | 1015 | // name: Chuck_DL_Query |
| @@ -604,20 +604,30 @@ public: · 603 unmodified lines | |||
| 604 | // get last error | 604 | // get last error |
| 605 | const char * last_error() const; | 605 | const char * last_error() const; |
| 606 | // unload the ckx | 606 | // unload the ckx |
| 607 | t_CKBOOL unload( ); | 607 | t_CKBOOL unload(); |
| 608 | // query the content of the dll | 608 | // query the content of the dll |
| 609 | const Chuck_DL_Query * query( ); | 609 | const Chuck_DL_Query * query(); |
| 610 | // probe information about dll without fully loading it | ||
| 611 | t_CKBOOL probe(); | ||
| 610 | // is good | 612 | // is good |
| 611 | t_CKBOOL good() const; | 613 | t_CKBOOL good() const; |
| 612 | // name | 614 | // name |
| 613 | const char * name() const; | 615 | const char * name() const; |
| 616 | // get version major | ||
| 617 | t_CKUINT versionMajor(); | ||
| 618 | // get version minor | ||
| 619 | t_CKUINT versionMinor(); | ||
| 620 | // is version compatible between dll and host | ||
| 621 | // major version must be same between chugin and host | ||
| 622 | // chugin minor version must less than or equal host minor version | ||
| 623 | t_CKBOOL compatible(); | ||
| 614 | 624 | ||
| 615 | public: | 625 | public: |
| 616 | // constructor | 626 | // constructor |
| 617 | Chuck_DLL( Chuck_Carrier * carrier, const char * xid = NULL ) | 627 | Chuck_DLL( Chuck_Carrier * carrier, const char * xid = NULL ) |
| 618 | : m_handle(NULL), m_id(xid ? xid : ""), | 628 | : m_handle(NULL), m_id(xid ? xid : ""), |
| 619 | m_query( carrier ), | 629 | m_query( carrier ), m_done_query(FALSE), m_query_func(NULL), |
| 620 | m_done_query(FALSE), m_query_func(NULL), m_version_func(NULL) | 630 | m_version_func(NULL), m_versionMajor(0), m_versionMinor(0) |
| 621 | { } | 631 | { } |
| 622 | // destructor | 632 | // destructor |
| 623 | ~Chuck_DLL() { this->unload(); } | 633 | ~Chuck_DLL() { this->unload(); } |
| @@ -634,6 +644,10 @@ protected: · 10 unmodified lines | |||
| 634 | f_ck_declversion m_version_func; | 644 | f_ck_declversion m_version_func; |
| 635 | f_ck_query m_query_func; | 645 | f_ck_query m_query_func; |
| 636 | Chuck_DL_Query m_query; | 646 | Chuck_DL_Query m_query; |
| 647 | |||
| 648 | protected: // addition info 1.5.0.4 (ge) added | ||
| 649 | t_CKUINT m_versionMajor; | ||
| 650 | t_CKUINT m_versionMinor; | ||
| 637 | }; | 651 | }; |
| 638 | 652 | ||
| 639 | 653 | ||
| @@ -613,7 +613,7 @@ void EM_setlog( t_CKINT level ) · 612 unmodified lines | |||
| 613 | g_loglevel = level; | 613 | g_loglevel = level; |
| 614 | 614 | ||
| 615 | // log this | 615 | // log this |
| 616 | EM_log( CK_LOG_SYSTEM, "setting log level to: %li (%s)...", level, g_str[level] ); | 616 | EM_log( CK_LOG_INFO, "setting log level to: %li (%s)...", level, g_str[level] ); |
| 617 | } | 617 | } |
| 618 | 618 | ||
| 619 | // push log | 619 | // push log |
| @@ -221,7 +221,8 @@ void usage() · 220 unmodified lines | |||
| 221 | CK_FPRINTF_STDERR( " srate:<N>|bufsize:<N>|bufnum:<N>|shell|empty|\n" ); | 221 | CK_FPRINTF_STDERR( " srate:<N>|bufsize:<N>|bufnum:<N>|shell|empty|\n" ); |
| 222 | CK_FPRINTF_STDERR( " remote:<hostname>|port:<N>|verbose:<N>|level:<N>|\n" ); | 222 | CK_FPRINTF_STDERR( " remote:<hostname>|port:<N>|verbose:<N>|level:<N>|\n" ); |
| 223 | CK_FPRINTF_STDERR( " callback|deprecate:{stop|warn|ignore}|\n" ); | 223 | CK_FPRINTF_STDERR( " callback|deprecate:{stop|warn|ignore}|\n" ); |
| 224 | CK_FPRINTF_STDERR( " chugin-load:{on|off}|chugin-path:<path>|chugin:<name>\n" ); | 224 | CK_FPRINTF_STDERR( " chugin-load:{on|off}|chugin-path:<path>|chugin:<name>|\n" ); |
| 225 | CK_FPRINTF_STDERR( " chugin-probe\n" ); | ||
| 225 | CK_FPRINTF_STDERR( " [commands] = add|remove|replace|remove.all|status|time|kill\n" ); | 226 | CK_FPRINTF_STDERR( " [commands] = add|remove|replace|remove.all|status|time|kill\n" ); |
| 226 | CK_FPRINTF_STDERR( " [+-=^] = shortcuts for add, remove, replace, status\n" ); | 227 | CK_FPRINTF_STDERR( " [+-=^] = shortcuts for add, remove, replace, status\n" ); |
| 227 | version(); | 228 | version(); |
| @@ -471,6 +472,7 @@ bool go( int argc, const char ** argv ) · 243 unmodified lines | |||
| 471 | t_CKINT adc_chans_before_rtaudio = adc_chans; // added 1.5.0.0 | 472 | t_CKINT adc_chans_before_rtaudio = adc_chans; // added 1.5.0.0 |
| 472 | t_CKBOOL dump = FALSE; | 473 | t_CKBOOL dump = FALSE; |
| 473 | t_CKBOOL probe = FALSE; | 474 | t_CKBOOL probe = FALSE; |
| 475 | t_CKBOOL probe_chugs = FALSE; | ||
| 474 | t_CKBOOL set_priority = FALSE; | 476 | t_CKBOOL set_priority = FALSE; |
| 475 | t_CKBOOL auto_depend = FALSE; | 477 | t_CKBOOL auto_depend = FALSE; |
| 476 | t_CKBOOL block = FALSE; | 478 | t_CKBOOL block = FALSE; |
| @@ -767,6 +769,8 @@ bool go( int argc, const char ** argv ) · 290 unmodified lines | |||
| 767 | } | 769 | } |
| 768 | else if( !strcmp( argv[i], "--probe" ) ) | 770 | else if( !strcmp( argv[i], "--probe" ) ) |
| 769 | probe = TRUE; | 771 | probe = TRUE; |
| 772 | else if( !strcmp( argv[i], "--chugin-probe" ) ) | ||
| 773 | probe_chugs = TRUE; | ||
| 770 | else if( !strcmp( argv[i], "--poop" ) ) | 774 | else if( !strcmp( argv[i], "--poop" ) ) |
| 771 | uh(); | 775 | uh(); |
| 772 | else if( !strcmp( argv[i], "--caution-to-the-wind" ) ) | 776 | else if( !strcmp( argv[i], "--caution-to-the-wind" ) ) |
| @@ -832,9 +836,8 @@ bool go( int argc, const char ** argv ) · 59 unmodified lines | |||
| 832 | // probe HID devices | 836 | // probe HID devices |
| 833 | HidInManager::probeHidIn(); | 837 | HidInManager::probeHidIn(); |
| 834 | 838 | ||
| 835 | // don't exit, wait to probe chugins, which needs a ChucK instance | 1.5.0.4 | 839 | // done probe |
| 836 | // exit | 840 | exit( 0 ); |
| 837 | // exit( 0 ); | ||
| 838 | } | 841 | } |
| 839 | 842 | ||
| 840 | // set caution to wind | 843 | // set caution to wind |
| @@ -854,7 +857,7 @@ bool go( int argc, const char ** argv ) · 13 unmodified lines | |||
| 854 | // set adaptive size | 857 | // set adaptive size |
| 855 | if( adaptive_size < 0 ) adaptive_size = buffer_size; | 858 | if( adaptive_size < 0 ) adaptive_size = buffer_size; |
| 856 | 859 | ||
| 857 | if( !files && vm_halt && !g_enable_shell ) | 860 | if( !files && vm_halt && !g_enable_shell && !probe_chugs ) |
| 858 | { | 861 | { |
| 859 | CK_FPRINTF_STDERR( "[chuck]: no input files... (try --help)\n" ); | 862 | CK_FPRINTF_STDERR( "[chuck]: no input files... (try --help)\n" ); |
| 860 | exit( 1 ); | 863 | exit( 1 ); |
| @@ -884,7 +887,7 @@ bool go( int argc, const char ** argv ) · 23 unmodified lines | |||
| 884 | } | 887 | } |
| 885 | 888 | ||
| 886 | // find dac_name if appropriate (added 1.3.0.0) | 889 | // find dac_name if appropriate (added 1.3.0.0) |
| 887 | if( dac_name.size() > 0 ) | 890 | if( !probe_chugs && dac_name.size() > 0 ) |
| 888 | { | 891 | { |
| 889 | // check with RtAudio | 892 | // check with RtAudio |
| 890 | t_CKINT dev = ChuckAudio::device_named( audioDriver, dac_name, TRUE, FALSE ); | 893 | t_CKINT dev = ChuckAudio::device_named( audioDriver, dac_name, TRUE, FALSE ); |
| @@ -901,7 +904,7 @@ bool go( int argc, const char ** argv ) · 10 unmodified lines | |||
| 901 | } | 904 | } |
| 902 | 905 | ||
| 903 | // find adc_name if appropriate (added 1.3.0.0) | 906 | // find adc_name if appropriate (added 1.3.0.0) |
| 904 | if( adc_name.size() > 0 ) | 907 | if( !probe_chugs && adc_name.size() > 0 ) |
| 905 | { | 908 | { |
| 906 | // check with RtAudio | 909 | // check with RtAudio |
| 907 | t_CKINT dev = ChuckAudio::device_named( audioDriver, adc_name, FALSE, TRUE ); | 910 | t_CKINT dev = ChuckAudio::device_named( audioDriver, adc_name, FALSE, TRUE ); |
| @@ -917,16 +920,11 @@ bool go( int argc, const char ** argv ) · 9 unmodified lines | |||
| 917 | } | 920 | } |
| 918 | } | 921 | } |
| 919 | 922 | ||
| 920 | |||
| 921 | //-------------------- VIRTUAL MACHINE SETUP (PART 1) ------------------------- | 923 | //-------------------- VIRTUAL MACHINE SETUP (PART 1) ------------------------- |
| 922 | // instantiate a ChucK! | 924 | // instantiate a ChucK! |
| 923 | the_chuck = new ChucK(); | 925 | the_chuck = new ChucK(); |
| 924 | // set log level so things can start logging | 926 | // set log level so things can start logging |
| 925 | the_chuck->setLogLevel( log_level ); | 927 | the_chuck->setLogLevel( log_level ); |
| 926 | // log | ||
| 927 | EM_log( CK_LOG_SYSTEM, "booting up ChucK instance..." ); | ||
| 928 | // push | ||
| 929 | EM_pushlog(); | ||
| 930 | 928 | ||
| 931 | // set chugins parameters | 929 | // set chugins parameters |
| 932 | the_chuck->setParam( CHUCK_PARAM_CHUGIN_ENABLE, chugin_load ); | 930 | the_chuck->setParam( CHUCK_PARAM_CHUGIN_ENABLE, chugin_load ); |
| @@ -934,7 +932,7 @@ bool go( int argc, const char ** argv ) · 1 unmodified line | |||
| 934 | the_chuck->setParam( CHUCK_PARAM_USER_CHUGIN_DIRECTORIES, dl_search_path ); | 932 | the_chuck->setParam( CHUCK_PARAM_USER_CHUGIN_DIRECTORIES, dl_search_path ); |
| 935 | 933 | ||
| 936 | // probe chugins | 1.5.0.4 (ge) added | 934 | // probe chugins | 1.5.0.4 (ge) added |
| 937 | if( probe ) | 935 | if( probe_chugs ) |
| 938 | { | 936 | { |
| 939 | // ensure log level is at least SYSTEM | 937 | // ensure log level is at least SYSTEM |
| 940 | if( the_chuck->getLogLevel() < CK_LOG_SYSTEM ) | 938 | if( the_chuck->getLogLevel() < CK_LOG_SYSTEM ) |
| @@ -948,6 +946,11 @@ bool go( int argc, const char ** argv ) · 7 unmodified lines | |||
| 948 | exit( 0 ); | 946 | exit( 0 ); |
| 949 | } | 947 | } |
| 950 | 948 | ||
| 949 | // log | ||
| 950 | EM_log( CK_LOG_SYSTEM, "booting up ChucK instance..." ); | ||
| 951 | // push | ||
| 952 | EM_pushlog(); | ||
| 953 | |||
| 951 | //--------------------------- AUDIO I/O SETUP --------------------------------- | 954 | //--------------------------- AUDIO I/O SETUP --------------------------------- |
| 952 | // log | 955 | // log |
| 953 | EM_log( CK_LOG_SYSTEM, "initializing audio subsystem..." ); | 956 | EM_log( CK_LOG_SYSTEM, "initializing audio subsystem..." ); |