bpo-34170: Add _Py_InitializeFromConfig() (GH-8454)

* If _Py_InitializeCore() is called twice, the second call now copies
  and apply (partially) the new configuration.
* Rename _Py_CommandLineDetails to _PyCmdline
* Move more code into pymain_init(). The core configuration created
  by Py_Main() is new destroyed before running Python to reduce the
  memory footprint.
* _Py_InitializeCore() now returns the created interpreter.
  _Py_InitializeMainInterpreter() now expects an interpreter.
* Remove _Py_InitializeEx_Private(): _freeze_importlib now uses
  _Py_InitializeFromConfig()
* _PyCoreConfig_InitPathConfig() now only computes the path
  configuration if needed.
diff --git a/Python/pathconfig.c b/Python/pathconfig.c
index 509ea8e..4e0830f 100644
--- a/Python/pathconfig.c
+++ b/Python/pathconfig.c
@@ -282,8 +282,8 @@
 }
 
 
-_PyInitError
-_PyCoreConfig_InitPathConfig(_PyCoreConfig *config)
+static _PyInitError
+_PyCoreConfig_CalculatePathConfig(_PyCoreConfig *config)
 {
     _PyPathConfig path_config = _PyPathConfig_INIT;
     _PyInitError err;
@@ -332,18 +332,6 @@
     }
 #endif
 
-    if (config->base_prefix == NULL) {
-        if (copy_wstr(&config->base_prefix, config->prefix) < 0) {
-            goto no_memory;
-        }
-    }
-
-    if (config->base_exec_prefix == NULL) {
-        if (copy_wstr(&config->base_exec_prefix, config->exec_prefix) < 0) {
-            goto no_memory;
-        }
-    }
-
     if (path_config.isolated != -1) {
         config->isolated = path_config.isolated;
     }
@@ -363,6 +351,39 @@
 }
 
 
+_PyInitError
+_PyCoreConfig_InitPathConfig(_PyCoreConfig *config)
+{
+    /* Do we need to calculate the path? */
+    if ((config->nmodule_search_path < 0)
+        || (config->executable == NULL)
+        || (config->prefix == NULL)
+#ifdef MS_WINDOWS
+        || (config->dll_path == NULL)
+#endif
+        || (config->exec_prefix == NULL))
+    {
+        _PyInitError err = _PyCoreConfig_CalculatePathConfig(config);
+        if (_Py_INIT_FAILED(err)) {
+            return err;
+        }
+    }
+
+    if (config->base_prefix == NULL) {
+        if (copy_wstr(&config->base_prefix, config->prefix) < 0) {
+            return _Py_INIT_NO_MEMORY();
+        }
+    }
+
+    if (config->base_exec_prefix == NULL) {
+        if (copy_wstr(&config->base_exec_prefix, config->exec_prefix) < 0) {
+            return _Py_INIT_NO_MEMORY();
+        }
+    }
+    return _Py_INIT_OK();
+}
+
+
 static void
 pathconfig_global_init(void)
 {