bpo-32030: Rewrite calculate_path() (#4521)

* calculate_path() rewritten in Modules/getpath.c and PC/getpathp.c
* Move global variables into a new PyPathConfig structure.
* calculate_path():

  * Split the huge calculate_path() function into subfunctions.
  * Add PyCalculatePath structure to pass data between subfunctions.
  * Document PyCalculatePath fields.
  * Move cleanup code into a new calculate_free() subfunction
  * calculate_init() now handles Py_DecodeLocale() failures properly
  * calculate_path() is now atomic: only replace PyPathConfig
    (path_config) at once on success.

* _Py_GetPythonHomeWithConfig() now returns an error on failure
* Add _Py_INIT_NO_MEMORY() helper: report a memory allocation failure
* Coding style fixes (PEP 7)
This commit is contained in:
Victor Stinner 2017-11-23 17:03:20 +01:00 committed by GitHub
parent bdb8315c21
commit 0327bde9da
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 970 additions and 605 deletions

View file

@ -1477,8 +1477,9 @@ Py_SetPythonHome(wchar_t *home)
default_home = home;
}
wchar_t *
_Py_GetPythonHomeWithConfig(const _PyMainInterpreterConfig *config)
_PyInitError
_Py_GetPythonHomeWithConfig(const _PyMainInterpreterConfig *config, wchar_t **homep)
{
/* Use a static buffer to avoid heap memory allocation failure.
Py_GetPythonHome() doesn't allow to report error, and the caller
@ -1486,32 +1487,40 @@ _Py_GetPythonHomeWithConfig(const _PyMainInterpreterConfig *config)
static wchar_t buffer[MAXPATHLEN+1];
if (default_home) {
return default_home;
*homep = default_home;
return _Py_INIT_OK();
}
if (config) {
return config->pythonhome;
*homep = config->pythonhome;
return _Py_INIT_OK();
}
char *home = Py_GETENV("PYTHONHOME");
if (!home) {
return NULL;
*homep = NULL;
return _Py_INIT_OK();
}
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;
*homep = NULL;
return _Py_INIT_ERR("failed to decode PYTHONHOME environment variable");
}
return buffer;
*homep = buffer;
return _Py_INIT_OK();
}
wchar_t *
Py_GetPythonHome(void)
{
return _Py_GetPythonHomeWithConfig(NULL);
wchar_t *home;
/* Ignore error */
(void)_Py_GetPythonHomeWithConfig(NULL, &home);
return home;
}
/* Add the __main__ module */