/* Path configuration like module_search_path (sys.path) */ #include "Python.h" #include "osdefs.h" #include "internal/pystate.h" #ifdef __cplusplus extern "C" { #endif _PyPathConfig _Py_path_config = _PyPathConfig_INIT; #ifdef MS_WINDOWS static wchar_t *progname = L"python"; #else static wchar_t *progname = L"python3"; #endif static wchar_t *default_home = NULL; void _PyPathConfig_Clear(_PyPathConfig *config) { #define CLEAR(ATTR) \ do { \ PyMem_RawFree(ATTR); \ ATTR = NULL; \ } while (0) CLEAR(config->prefix); CLEAR(config->program_full_path); #ifdef MS_WINDOWS CLEAR(config->dll_path); #else CLEAR(config->exec_prefix); #endif CLEAR(config->module_search_path); #undef CLEAR } void Py_SetProgramName(wchar_t *pn) { if (pn && *pn) progname = pn; } wchar_t * Py_GetProgramName(void) { return progname; } void Py_SetPythonHome(wchar_t *home) { default_home = home; } wchar_t* Py_GetPythonHome(void) { /* Use a static buffer to avoid heap memory allocation failure. Py_GetPythonHome() doesn't allow to report error, and the caller doesn't release memory. */ static wchar_t buffer[MAXPATHLEN+1]; if (default_home) { return default_home; } char *home = Py_GETENV("PYTHONHOME"); if (!home) { return NULL; } size_t size = Py_ARRAY_LENGTH(buffer); size_t r = mbstowcs(buffer, home, size); if (r == (size_t)-1 || r >= size) { /* conversion failed or the static buffer is too small */ return NULL; } return buffer; } static void pathconfig_global_init(void) { if (_Py_path_config.module_search_path) { /* Already initialized */ return; } _PyInitError err; _PyMainInterpreterConfig config = _PyMainInterpreterConfig_INIT; err = _PyMainInterpreterConfig_ReadEnv(&config); if (_Py_INIT_FAILED(err)) { goto error; } err = _PyMainInterpreterConfig_Read(&config); if (_Py_INIT_FAILED(err)) { goto error; } err = _PyPathConfig_Init(&config); if (_Py_INIT_FAILED(err)) { goto error; } _PyMainInterpreterConfig_Clear(&config); return; error: _PyMainInterpreterConfig_Clear(&config); _Py_FatalInitError(err); } /* External interface */ void Py_SetPath(const wchar_t *path) { if (path == NULL) { _PyPathConfig_Clear(&_Py_path_config); return; } _PyPathConfig new_config; new_config.program_full_path = _PyMem_RawWcsdup(Py_GetProgramName()); new_config.prefix = _PyMem_RawWcsdup(L""); #ifdef MS_WINDOWS new_config.dll_path = _PyMem_RawWcsdup(L""); #else new_config.exec_prefix = _PyMem_RawWcsdup(L""); #endif new_config.module_search_path = _PyMem_RawWcsdup(path); _PyPathConfig_Clear(&_Py_path_config); _Py_path_config = new_config; } wchar_t * Py_GetPath(void) { pathconfig_global_init(); return _Py_path_config.module_search_path; } wchar_t * Py_GetPrefix(void) { pathconfig_global_init(); return _Py_path_config.prefix; } wchar_t * Py_GetExecPrefix(void) { #ifdef MS_WINDOWS return Py_GetPrefix(); #else pathconfig_global_init(); return _Py_path_config.exec_prefix; #endif } wchar_t * Py_GetProgramFullPath(void) { pathconfig_global_init(); return _Py_path_config.program_full_path; } #ifdef __cplusplus } #endif