You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

764 lines
19 KiB

  1. /* Path configuration like module_search_path (sys.path) */
  2. #include "Python.h"
  3. #include "osdefs.h"
  4. #include "pycore_coreconfig.h"
  5. #include "pycore_fileutils.h"
  6. #include "pycore_pathconfig.h"
  7. #include "pycore_pymem.h"
  8. #include "pycore_pystate.h"
  9. #include <wchar.h>
  10. #ifdef __cplusplus
  11. extern "C" {
  12. #endif
  13. _PyPathConfig _Py_path_config = _PyPathConfig_INIT;
  14. static int
  15. copy_wstr(wchar_t **dst, const wchar_t *src)
  16. {
  17. if (src != NULL) {
  18. *dst = _PyMem_RawWcsdup(src);
  19. if (*dst == NULL) {
  20. return -1;
  21. }
  22. }
  23. else {
  24. *dst = NULL;
  25. }
  26. return 0;
  27. }
  28. static void
  29. _PyPathConfig_Clear(_PyPathConfig *config)
  30. {
  31. /* _PyMem_SetDefaultAllocator() is needed to get a known memory allocator,
  32. since Py_SetPath(), Py_SetPythonHome() and Py_SetProgramName() can be
  33. called before Py_Initialize() which can changes the memory allocator. */
  34. PyMemAllocatorEx old_alloc;
  35. _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
  36. #define CLEAR(ATTR) \
  37. do { \
  38. PyMem_RawFree(ATTR); \
  39. ATTR = NULL; \
  40. } while (0)
  41. CLEAR(config->prefix);
  42. CLEAR(config->program_full_path);
  43. CLEAR(config->exec_prefix);
  44. #ifdef MS_WINDOWS
  45. CLEAR(config->dll_path);
  46. #endif
  47. CLEAR(config->module_search_path);
  48. CLEAR(config->home);
  49. CLEAR(config->program_name);
  50. #undef CLEAR
  51. PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
  52. }
  53. /* Calculate the path configuration: initialize path_config from core_config */
  54. static _PyInitError
  55. _PyPathConfig_Calculate(_PyPathConfig *path_config,
  56. const _PyCoreConfig *core_config)
  57. {
  58. _PyInitError err;
  59. _PyPathConfig new_config = _PyPathConfig_INIT;
  60. PyMemAllocatorEx old_alloc;
  61. _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
  62. /* Calculate program_full_path, prefix, exec_prefix,
  63. dll_path (Windows), and module_search_path */
  64. err = _PyPathConfig_Calculate_impl(&new_config, core_config);
  65. if (_Py_INIT_FAILED(err)) {
  66. goto err;
  67. }
  68. /* Copy home and program_name from core_config */
  69. if (copy_wstr(&new_config.home, core_config->home) < 0) {
  70. err = _Py_INIT_NO_MEMORY();
  71. goto err;
  72. }
  73. if (copy_wstr(&new_config.program_name, core_config->program_name) < 0) {
  74. err = _Py_INIT_NO_MEMORY();
  75. goto err;
  76. }
  77. _PyPathConfig_Clear(path_config);
  78. *path_config = new_config;
  79. err = _Py_INIT_OK();
  80. goto done;
  81. err:
  82. _PyPathConfig_Clear(&new_config);
  83. done:
  84. PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
  85. return err;
  86. }
  87. _PyInitError
  88. _PyPathConfig_SetGlobal(const _PyPathConfig *config)
  89. {
  90. _PyInitError err;
  91. _PyPathConfig new_config = _PyPathConfig_INIT;
  92. PyMemAllocatorEx old_alloc;
  93. _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
  94. #define COPY_ATTR(ATTR) \
  95. do { \
  96. if (copy_wstr(&new_config.ATTR, config->ATTR) < 0) { \
  97. _PyPathConfig_Clear(&new_config); \
  98. err = _Py_INIT_NO_MEMORY(); \
  99. goto done; \
  100. } \
  101. } while (0)
  102. COPY_ATTR(program_full_path);
  103. COPY_ATTR(prefix);
  104. COPY_ATTR(exec_prefix);
  105. #ifdef MS_WINDOWS
  106. COPY_ATTR(dll_path);
  107. #endif
  108. COPY_ATTR(module_search_path);
  109. COPY_ATTR(program_name);
  110. COPY_ATTR(home);
  111. _PyPathConfig_Clear(&_Py_path_config);
  112. /* Steal new_config strings; don't clear new_config */
  113. _Py_path_config = new_config;
  114. err = _Py_INIT_OK();
  115. done:
  116. PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
  117. return err;
  118. }
  119. void
  120. _PyPathConfig_ClearGlobal(void)
  121. {
  122. PyMemAllocatorEx old_alloc;
  123. _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
  124. _PyPathConfig_Clear(&_Py_path_config);
  125. PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
  126. }
  127. static wchar_t*
  128. _PyWstrList_Join(const _PyWstrList *list, wchar_t sep)
  129. {
  130. size_t len = 1; /* NUL terminator */
  131. for (Py_ssize_t i=0; i < list->length; i++) {
  132. if (i != 0) {
  133. len++;
  134. }
  135. len += wcslen(list->items[i]);
  136. }
  137. wchar_t *text = PyMem_RawMalloc(len * sizeof(wchar_t));
  138. if (text == NULL) {
  139. return NULL;
  140. }
  141. wchar_t *str = text;
  142. for (Py_ssize_t i=0; i < list->length; i++) {
  143. wchar_t *path = list->items[i];
  144. if (i != 0) {
  145. *str++ = SEP;
  146. }
  147. len = wcslen(path);
  148. memcpy(str, path, len * sizeof(wchar_t));
  149. str += len;
  150. }
  151. *str = L'\0';
  152. return text;
  153. }
  154. /* Set the global path configuration from core_config. */
  155. _PyInitError
  156. _PyCoreConfig_SetPathConfig(const _PyCoreConfig *core_config)
  157. {
  158. PyMemAllocatorEx old_alloc;
  159. _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
  160. _PyInitError err;
  161. _PyPathConfig path_config = _PyPathConfig_INIT;
  162. path_config.module_search_path = _PyWstrList_Join(&core_config->module_search_paths, DELIM);
  163. if (path_config.module_search_path == NULL) {
  164. goto no_memory;
  165. }
  166. if (copy_wstr(&path_config.program_full_path, core_config->executable) < 0) {
  167. goto no_memory;
  168. }
  169. if (copy_wstr(&path_config.prefix, core_config->prefix) < 0) {
  170. goto no_memory;
  171. }
  172. if (copy_wstr(&path_config.exec_prefix, core_config->exec_prefix) < 0) {
  173. goto no_memory;
  174. }
  175. #ifdef MS_WINDOWS
  176. if (copy_wstr(&path_config.dll_path, core_config->dll_path) < 0) {
  177. goto no_memory;
  178. }
  179. #endif
  180. if (copy_wstr(&path_config.program_name, core_config->program_name) < 0) {
  181. goto no_memory;
  182. }
  183. if (copy_wstr(&path_config.home, core_config->home) < 0) {
  184. goto no_memory;
  185. }
  186. err = _PyPathConfig_SetGlobal(&path_config);
  187. if (_Py_INIT_FAILED(err)) {
  188. goto done;
  189. }
  190. err = _Py_INIT_OK();
  191. goto done;
  192. no_memory:
  193. err = _Py_INIT_NO_MEMORY();
  194. done:
  195. _PyPathConfig_Clear(&path_config);
  196. PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
  197. return err;
  198. }
  199. static _PyInitError
  200. core_config_init_module_search_paths(_PyCoreConfig *config,
  201. _PyPathConfig *path_config)
  202. {
  203. assert(!config->use_module_search_paths);
  204. _PyWstrList_Clear(&config->module_search_paths);
  205. const wchar_t *sys_path = path_config->module_search_path;
  206. const wchar_t delim = DELIM;
  207. const wchar_t *p = sys_path;
  208. while (1) {
  209. p = wcschr(sys_path, delim);
  210. if (p == NULL) {
  211. p = sys_path + wcslen(sys_path); /* End of string */
  212. }
  213. size_t path_len = (p - sys_path);
  214. wchar_t *path = PyMem_RawMalloc((path_len + 1) * sizeof(wchar_t));
  215. if (path == NULL) {
  216. return _Py_INIT_NO_MEMORY();
  217. }
  218. memcpy(path, sys_path, path_len * sizeof(wchar_t));
  219. path[path_len] = L'\0';
  220. int res = _PyWstrList_Append(&config->module_search_paths, path);
  221. PyMem_RawFree(path);
  222. if (res < 0) {
  223. return _Py_INIT_NO_MEMORY();
  224. }
  225. if (*p == '\0') {
  226. break;
  227. }
  228. sys_path = p + 1;
  229. }
  230. config->use_module_search_paths = 1;
  231. return _Py_INIT_OK();
  232. }
  233. static _PyInitError
  234. _PyCoreConfig_CalculatePathConfig(_PyCoreConfig *config)
  235. {
  236. _PyPathConfig path_config = _PyPathConfig_INIT;
  237. _PyInitError err;
  238. err = _PyPathConfig_Calculate(&path_config, config);
  239. if (_Py_INIT_FAILED(err)) {
  240. goto error;
  241. }
  242. if (!config->use_module_search_paths) {
  243. err = core_config_init_module_search_paths(config, &path_config);
  244. if (_Py_INIT_FAILED(err)) {
  245. goto error;
  246. }
  247. }
  248. if (config->executable == NULL) {
  249. if (copy_wstr(&config->executable,
  250. path_config.program_full_path) < 0) {
  251. goto no_memory;
  252. }
  253. }
  254. if (config->prefix == NULL) {
  255. if (copy_wstr(&config->prefix, path_config.prefix) < 0) {
  256. goto no_memory;
  257. }
  258. }
  259. if (config->exec_prefix == NULL) {
  260. if (copy_wstr(&config->exec_prefix,
  261. path_config.exec_prefix) < 0) {
  262. goto no_memory;
  263. }
  264. }
  265. #ifdef MS_WINDOWS
  266. if (config->dll_path == NULL) {
  267. if (copy_wstr(&config->dll_path, path_config.dll_path) < 0) {
  268. goto no_memory;
  269. }
  270. }
  271. #endif
  272. if (path_config.isolated != -1) {
  273. config->preconfig.isolated = path_config.isolated;
  274. }
  275. if (path_config.site_import != -1) {
  276. config->site_import = path_config.site_import;
  277. }
  278. _PyPathConfig_Clear(&path_config);
  279. return _Py_INIT_OK();
  280. no_memory:
  281. err = _Py_INIT_NO_MEMORY();
  282. error:
  283. _PyPathConfig_Clear(&path_config);
  284. return err;
  285. }
  286. _PyInitError
  287. _PyCoreConfig_InitPathConfig(_PyCoreConfig *config)
  288. {
  289. /* Do we need to calculate the path? */
  290. if (!config->use_module_search_paths
  291. || (config->executable == NULL)
  292. || (config->prefix == NULL)
  293. #ifdef MS_WINDOWS
  294. || (config->dll_path == NULL)
  295. #endif
  296. || (config->exec_prefix == NULL))
  297. {
  298. _PyInitError err = _PyCoreConfig_CalculatePathConfig(config);
  299. if (_Py_INIT_FAILED(err)) {
  300. return err;
  301. }
  302. }
  303. if (config->base_prefix == NULL) {
  304. if (copy_wstr(&config->base_prefix, config->prefix) < 0) {
  305. return _Py_INIT_NO_MEMORY();
  306. }
  307. }
  308. if (config->base_exec_prefix == NULL) {
  309. if (copy_wstr(&config->base_exec_prefix,
  310. config->exec_prefix) < 0) {
  311. return _Py_INIT_NO_MEMORY();
  312. }
  313. }
  314. return _Py_INIT_OK();
  315. }
  316. static void
  317. pathconfig_global_init(void)
  318. {
  319. if (_Py_path_config.module_search_path != NULL) {
  320. /* Already initialized */
  321. return;
  322. }
  323. _PyInitError err;
  324. _PyCoreConfig config = _PyCoreConfig_INIT;
  325. err = _PyCoreConfig_Read(&config, NULL);
  326. if (_Py_INIT_FAILED(err)) {
  327. goto error;
  328. }
  329. err = _PyCoreConfig_SetPathConfig(&config);
  330. if (_Py_INIT_FAILED(err)) {
  331. goto error;
  332. }
  333. _PyCoreConfig_Clear(&config);
  334. return;
  335. error:
  336. _PyCoreConfig_Clear(&config);
  337. _Py_ExitInitError(err);
  338. }
  339. /* External interface */
  340. void
  341. Py_SetPath(const wchar_t *path)
  342. {
  343. if (path == NULL) {
  344. _PyPathConfig_Clear(&_Py_path_config);
  345. return;
  346. }
  347. PyMemAllocatorEx old_alloc;
  348. _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
  349. _PyPathConfig new_config;
  350. new_config.program_full_path = _PyMem_RawWcsdup(Py_GetProgramName());
  351. int alloc_error = (new_config.program_full_path == NULL);
  352. new_config.prefix = _PyMem_RawWcsdup(L"");
  353. alloc_error |= (new_config.prefix == NULL);
  354. new_config.exec_prefix = _PyMem_RawWcsdup(L"");
  355. alloc_error |= (new_config.exec_prefix == NULL);
  356. #ifdef MS_WINDOWS
  357. new_config.dll_path = _PyMem_RawWcsdup(L"");
  358. alloc_error |= (new_config.dll_path == NULL);
  359. #endif
  360. new_config.module_search_path = _PyMem_RawWcsdup(path);
  361. alloc_error |= (new_config.module_search_path == NULL);
  362. /* steal the home and program_name values (to leave them unchanged) */
  363. new_config.home = _Py_path_config.home;
  364. _Py_path_config.home = NULL;
  365. new_config.program_name = _Py_path_config.program_name;
  366. _Py_path_config.program_name = NULL;
  367. _PyPathConfig_Clear(&_Py_path_config);
  368. _Py_path_config = new_config;
  369. PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
  370. if (alloc_error) {
  371. Py_FatalError("Py_SetPath() failed: out of memory");
  372. }
  373. }
  374. void
  375. Py_SetPythonHome(const wchar_t *home)
  376. {
  377. if (home == NULL) {
  378. return;
  379. }
  380. PyMemAllocatorEx old_alloc;
  381. _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
  382. PyMem_RawFree(_Py_path_config.home);
  383. _Py_path_config.home = _PyMem_RawWcsdup(home);
  384. PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
  385. if (_Py_path_config.home == NULL) {
  386. Py_FatalError("Py_SetPythonHome() failed: out of memory");
  387. }
  388. }
  389. void
  390. Py_SetProgramName(const wchar_t *program_name)
  391. {
  392. if (program_name == NULL || program_name[0] == L'\0') {
  393. return;
  394. }
  395. PyMemAllocatorEx old_alloc;
  396. _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
  397. PyMem_RawFree(_Py_path_config.program_name);
  398. _Py_path_config.program_name = _PyMem_RawWcsdup(program_name);
  399. PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
  400. if (_Py_path_config.program_name == NULL) {
  401. Py_FatalError("Py_SetProgramName() failed: out of memory");
  402. }
  403. }
  404. void
  405. _Py_SetProgramFullPath(const wchar_t *program_full_path)
  406. {
  407. if (program_full_path == NULL || program_full_path[0] == L'\0') {
  408. return;
  409. }
  410. PyMemAllocatorEx old_alloc;
  411. _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
  412. PyMem_RawFree(_Py_path_config.program_full_path);
  413. _Py_path_config.program_full_path = _PyMem_RawWcsdup(program_full_path);
  414. PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
  415. if (_Py_path_config.program_full_path == NULL) {
  416. Py_FatalError("_Py_SetProgramFullPath() failed: out of memory");
  417. }
  418. }
  419. wchar_t *
  420. Py_GetPath(void)
  421. {
  422. pathconfig_global_init();
  423. return _Py_path_config.module_search_path;
  424. }
  425. wchar_t *
  426. Py_GetPrefix(void)
  427. {
  428. pathconfig_global_init();
  429. return _Py_path_config.prefix;
  430. }
  431. wchar_t *
  432. Py_GetExecPrefix(void)
  433. {
  434. pathconfig_global_init();
  435. return _Py_path_config.exec_prefix;
  436. }
  437. wchar_t *
  438. Py_GetProgramFullPath(void)
  439. {
  440. pathconfig_global_init();
  441. return _Py_path_config.program_full_path;
  442. }
  443. wchar_t*
  444. Py_GetPythonHome(void)
  445. {
  446. pathconfig_global_init();
  447. return _Py_path_config.home;
  448. }
  449. wchar_t *
  450. Py_GetProgramName(void)
  451. {
  452. pathconfig_global_init();
  453. return _Py_path_config.program_name;
  454. }
  455. /* Compute module search path from argv[0] or the current working
  456. directory ("-m module" case) which will be prepended to sys.argv:
  457. sys.path[0].
  458. Return 1 if the path is correctly resolved, but *path0_p can be NULL
  459. if the Unicode object fail to be created.
  460. Return 0 if it fails to resolve the full path (and *path0_p will be NULL).
  461. For example, return 0 if the current working directory has been removed
  462. (bpo-36236) or if argv is empty.
  463. */
  464. int
  465. _PyPathConfig_ComputeSysPath0(const _PyWstrList *argv, PyObject **path0_p)
  466. {
  467. assert(_PyWstrList_CheckConsistency(argv));
  468. assert(*path0_p == NULL);
  469. if (argv->length == 0) {
  470. /* Leave sys.path unchanged if sys.argv is empty */
  471. return 0;
  472. }
  473. wchar_t *argv0 = argv->items[0];
  474. int have_module_arg = (wcscmp(argv0, L"-m") == 0);
  475. int have_script_arg = (!have_module_arg && (wcscmp(argv0, L"-c") != 0));
  476. wchar_t *path0 = argv0;
  477. Py_ssize_t n = 0;
  478. #ifdef HAVE_REALPATH
  479. wchar_t fullpath[MAXPATHLEN];
  480. #elif defined(MS_WINDOWS)
  481. wchar_t fullpath[MAX_PATH];
  482. #endif
  483. if (have_module_arg) {
  484. #if defined(HAVE_REALPATH) || defined(MS_WINDOWS)
  485. if (!_Py_wgetcwd(fullpath, Py_ARRAY_LENGTH(fullpath))) {
  486. return 0;
  487. }
  488. path0 = fullpath;
  489. #else
  490. path0 = L".";
  491. #endif
  492. n = wcslen(path0);
  493. }
  494. #ifdef HAVE_READLINK
  495. wchar_t link[MAXPATHLEN + 1];
  496. int nr = 0;
  497. if (have_script_arg) {
  498. nr = _Py_wreadlink(path0, link, Py_ARRAY_LENGTH(link));
  499. }
  500. if (nr > 0) {
  501. /* It's a symlink */
  502. link[nr] = '\0';
  503. if (link[0] == SEP) {
  504. path0 = link; /* Link to absolute path */
  505. }
  506. else if (wcschr(link, SEP) == NULL) {
  507. /* Link without path */
  508. }
  509. else {
  510. /* Must join(dirname(path0), link) */
  511. wchar_t *q = wcsrchr(path0, SEP);
  512. if (q == NULL) {
  513. /* path0 without path */
  514. path0 = link;
  515. }
  516. else {
  517. /* Must make a copy, path0copy has room for 2 * MAXPATHLEN */
  518. wchar_t path0copy[2 * MAXPATHLEN + 1];
  519. wcsncpy(path0copy, path0, MAXPATHLEN);
  520. q = wcsrchr(path0copy, SEP);
  521. wcsncpy(q+1, link, MAXPATHLEN);
  522. q[MAXPATHLEN + 1] = L'\0';
  523. path0 = path0copy;
  524. }
  525. }
  526. }
  527. #endif /* HAVE_READLINK */
  528. wchar_t *p = NULL;
  529. #if SEP == '\\'
  530. /* Special case for Microsoft filename syntax */
  531. if (have_script_arg) {
  532. wchar_t *q;
  533. #if defined(MS_WINDOWS)
  534. /* Replace the first element in argv with the full path. */
  535. wchar_t *ptemp;
  536. if (GetFullPathNameW(path0,
  537. Py_ARRAY_LENGTH(fullpath),
  538. fullpath,
  539. &ptemp)) {
  540. path0 = fullpath;
  541. }
  542. #endif
  543. p = wcsrchr(path0, SEP);
  544. /* Test for alternate separator */
  545. q = wcsrchr(p ? p : path0, '/');
  546. if (q != NULL)
  547. p = q;
  548. if (p != NULL) {
  549. n = p + 1 - path0;
  550. if (n > 1 && p[-1] != ':')
  551. n--; /* Drop trailing separator */
  552. }
  553. }
  554. #else
  555. /* All other filename syntaxes */
  556. if (have_script_arg) {
  557. #if defined(HAVE_REALPATH)
  558. if (_Py_wrealpath(path0, fullpath, Py_ARRAY_LENGTH(fullpath))) {
  559. path0 = fullpath;
  560. }
  561. #endif
  562. p = wcsrchr(path0, SEP);
  563. }
  564. if (p != NULL) {
  565. n = p + 1 - path0;
  566. #if SEP == '/' /* Special case for Unix filename syntax */
  567. if (n > 1) {
  568. /* Drop trailing separator */
  569. n--;
  570. }
  571. #endif /* Unix */
  572. }
  573. #endif /* All others */
  574. *path0_p = PyUnicode_FromWideChar(path0, n);
  575. return 1;
  576. }
  577. #ifdef MS_WINDOWS
  578. #define WCSTOK wcstok_s
  579. #else
  580. #define WCSTOK wcstok
  581. #endif
  582. /* Search for a prefix value in an environment file (pyvenv.cfg).
  583. If found, copy it into the provided buffer. */
  584. int
  585. _Py_FindEnvConfigValue(FILE *env_file, const wchar_t *key,
  586. wchar_t *value, size_t value_size)
  587. {
  588. int result = 0; /* meaning not found */
  589. char buffer[MAXPATHLEN * 2 + 1]; /* allow extra for key, '=', etc. */
  590. buffer[Py_ARRAY_LENGTH(buffer)-1] = '\0';
  591. fseek(env_file, 0, SEEK_SET);
  592. while (!feof(env_file)) {
  593. char * p = fgets(buffer, Py_ARRAY_LENGTH(buffer) - 1, env_file);
  594. if (p == NULL) {
  595. break;
  596. }
  597. size_t n = strlen(p);
  598. if (p[n - 1] != '\n') {
  599. /* line has overflowed - bail */
  600. break;
  601. }
  602. if (p[0] == '#') {
  603. /* Comment - skip */
  604. continue;
  605. }
  606. wchar_t *tmpbuffer = _Py_DecodeUTF8_surrogateescape(buffer, n, NULL);
  607. if (tmpbuffer) {
  608. wchar_t * state;
  609. wchar_t * tok = WCSTOK(tmpbuffer, L" \t\r\n", &state);
  610. if ((tok != NULL) && !wcscmp(tok, key)) {
  611. tok = WCSTOK(NULL, L" \t", &state);
  612. if ((tok != NULL) && !wcscmp(tok, L"=")) {
  613. tok = WCSTOK(NULL, L"\r\n", &state);
  614. if (tok != NULL) {
  615. wcsncpy(value, tok, value_size - 1);
  616. value[value_size - 1] = L'\0';
  617. result = 1;
  618. PyMem_RawFree(tmpbuffer);
  619. break;
  620. }
  621. }
  622. }
  623. PyMem_RawFree(tmpbuffer);
  624. }
  625. }
  626. return result;
  627. }
  628. #ifdef __cplusplus
  629. }
  630. #endif