comparison Python/sysmodule.c @ 46318:22a74eaf6b22

Change command line processing API to use wchar_t. Fixes #2128.
author Martin v. Löwis <martin@v.loewis.de>
date Sat, 05 Apr 2008 20:41:37 +0000
parents 3d7b84daa34a
children 47d9bbe10897
comparison
equal deleted inserted replaced
46316:4352d41affb0 46318:22a74eaf6b22
880 return; 880 return;
881 PyList_SetSlice(warnoptions, 0, PyList_GET_SIZE(warnoptions), NULL); 881 PyList_SetSlice(warnoptions, 0, PyList_GET_SIZE(warnoptions), NULL);
882 } 882 }
883 883
884 void 884 void
885 PySys_AddWarnOption(const char *s) 885 PySys_AddWarnOption(const wchar_t *s)
886 { 886 {
887 PyObject *str; 887 PyObject *str;
888 888
889 if (warnoptions == NULL || !PyList_Check(warnoptions)) { 889 if (warnoptions == NULL || !PyList_Check(warnoptions)) {
890 Py_XDECREF(warnoptions); 890 Py_XDECREF(warnoptions);
891 warnoptions = PyList_New(0); 891 warnoptions = PyList_New(0);
892 if (warnoptions == NULL) 892 if (warnoptions == NULL)
893 return; 893 return;
894 } 894 }
895 str = PyUnicode_FromString(s); 895 str = PyUnicode_FromWideChar(s, -1);
896 if (str != NULL) { 896 if (str != NULL) {
897 PyList_Append(warnoptions, str); 897 PyList_Append(warnoptions, str);
898 Py_DECREF(str); 898 Py_DECREF(str);
899 } 899 }
900 } 900 }
1220 SET_SYS_FROM_STRING("copyright", 1220 SET_SYS_FROM_STRING("copyright",
1221 PyUnicode_FromString(Py_GetCopyright())); 1221 PyUnicode_FromString(Py_GetCopyright()));
1222 SET_SYS_FROM_STRING("platform", 1222 SET_SYS_FROM_STRING("platform",
1223 PyUnicode_FromString(Py_GetPlatform())); 1223 PyUnicode_FromString(Py_GetPlatform()));
1224 SET_SYS_FROM_STRING("executable", 1224 SET_SYS_FROM_STRING("executable",
1225 PyUnicode_DecodeFSDefault( 1225 PyUnicode_FromWideChar(
1226 Py_GetProgramFullPath())); 1226 Py_GetProgramFullPath(), -1));
1227 SET_SYS_FROM_STRING("prefix", 1227 SET_SYS_FROM_STRING("prefix",
1228 PyUnicode_DecodeFSDefault(Py_GetPrefix())); 1228 PyUnicode_FromWideChar(Py_GetPrefix(), -1));
1229 SET_SYS_FROM_STRING("exec_prefix", 1229 SET_SYS_FROM_STRING("exec_prefix",
1230 PyUnicode_DecodeFSDefault(Py_GetExecPrefix())); 1230 PyUnicode_FromWideChar(Py_GetExecPrefix(), -1));
1231 SET_SYS_FROM_STRING("maxsize", 1231 SET_SYS_FROM_STRING("maxsize",
1232 PyLong_FromSsize_t(PY_SSIZE_T_MAX)); 1232 PyLong_FromSsize_t(PY_SSIZE_T_MAX));
1233 SET_SYS_FROM_STRING("float_info", 1233 SET_SYS_FROM_STRING("float_info",
1234 PyFloat_GetInfo()); 1234 PyFloat_GetInfo());
1235 SET_SYS_FROM_STRING("maxunicode", 1235 SET_SYS_FROM_STRING("maxunicode",
1278 return NULL; 1278 return NULL;
1279 return m; 1279 return m;
1280 } 1280 }
1281 1281
1282 static PyObject * 1282 static PyObject *
1283 makepathobject(const char *path, int delim) 1283 makepathobject(const wchar_t *path, wchar_t delim)
1284 { 1284 {
1285 int i, n; 1285 int i, n;
1286 const char *p; 1286 const wchar_t *p;
1287 PyObject *v, *w; 1287 PyObject *v, *w;
1288 1288
1289 n = 1; 1289 n = 1;
1290 p = path; 1290 p = path;
1291 while ((p = strchr(p, delim)) != NULL) { 1291 while ((p = wcschr(p, delim)) != NULL) {
1292 n++; 1292 n++;
1293 p++; 1293 p++;
1294 } 1294 }
1295 v = PyList_New(n); 1295 v = PyList_New(n);
1296 if (v == NULL) 1296 if (v == NULL)
1297 return NULL; 1297 return NULL;
1298 for (i = 0; ; i++) { 1298 for (i = 0; ; i++) {
1299 p = strchr(path, delim); 1299 p = wcschr(path, delim);
1300 if (p == NULL) 1300 if (p == NULL)
1301 p = strchr(path, '\0'); /* End of string */ 1301 p = wcschr(path, L'\0'); /* End of string */
1302 w = PyUnicode_DecodeFSDefaultAndSize(path, (Py_ssize_t) (p - path)); 1302 w = PyUnicode_FromWideChar(path, (Py_ssize_t)(p - path));
1303 if (w == NULL) { 1303 if (w == NULL) {
1304 Py_DECREF(v); 1304 Py_DECREF(v);
1305 return NULL; 1305 return NULL;
1306 } 1306 }
1307 PyList_SetItem(v, i, w); 1307 PyList_SetItem(v, i, w);
1311 } 1311 }
1312 return v; 1312 return v;
1313 } 1313 }
1314 1314
1315 void 1315 void
1316 PySys_SetPath(const char *path) 1316 PySys_SetPath(const wchar_t *path)
1317 { 1317 {
1318 PyObject *v; 1318 PyObject *v;
1319 if ((v = makepathobject(path, DELIM)) == NULL) 1319 if ((v = makepathobject(path, DELIM)) == NULL)
1320 Py_FatalError("can't create sys.path"); 1320 Py_FatalError("can't create sys.path");
1321 if (PySys_SetObject("path", v) != 0) 1321 if (PySys_SetObject("path", v) != 0)
1322 Py_FatalError("can't assign sys.path"); 1322 Py_FatalError("can't assign sys.path");
1323 Py_DECREF(v); 1323 Py_DECREF(v);
1324 } 1324 }
1325 1325
1326 static PyObject * 1326 static PyObject *
1327 makeargvobject(int argc, char **argv) 1327 makeargvobject(int argc, wchar_t **argv)
1328 { 1328 {
1329 PyObject *av; 1329 PyObject *av;
1330 if (argc <= 0 || argv == NULL) { 1330 if (argc <= 0 || argv == NULL) {
1331 /* Ensure at least one (empty) argument is seen */ 1331 /* Ensure at least one (empty) argument is seen */
1332 static char *empty_argv[1] = {""}; 1332 static wchar_t *empty_argv[1] = {L""};
1333 argv = empty_argv; 1333 argv = empty_argv;
1334 argc = 1; 1334 argc = 1;
1335 } 1335 }
1336 av = PyList_New(argc); 1336 av = PyList_New(argc);
1337 if (av != NULL) { 1337 if (av != NULL) {
1349 v = PyUnicode_FromString( 1349 v = PyUnicode_FromString(
1350 decc$translate_vms(argv[0])); 1350 decc$translate_vms(argv[0]));
1351 } else 1351 } else
1352 v = PyUnicode_FromString(argv[i]); 1352 v = PyUnicode_FromString(argv[i]);
1353 #else 1353 #else
1354 PyObject *v = PyUnicode_FromString(argv[i]); 1354 PyObject *v = PyUnicode_FromWideChar(argv[i], -1);
1355 #endif 1355 #endif
1356 if (v == NULL) { 1356 if (v == NULL) {
1357 Py_DECREF(av); 1357 Py_DECREF(av);
1358 av = NULL; 1358 av = NULL;
1359 break; 1359 break;
1362 } 1362 }
1363 } 1363 }
1364 return av; 1364 return av;
1365 } 1365 }
1366 1366
1367 #ifdef HAVE_REALPATH
1368 static wchar_t*
1369 _wrealpath(const wchar_t *path, wchar_t *resolved_path)
1370 {
1371 char cpath[PATH_MAX];
1372 char cresolved_path[PATH_MAX];
1373 char *res;
1374 size_t r;
1375 r = wcstombs(cpath, path, PATH_MAX);
1376 if (r == (size_t)-1 || r >= PATH_MAX) {
1377 errno = EINVAL;
1378 return NULL;
1379 }
1380 res = realpath(cpath, cresolved_path);
1381 if (res == NULL)
1382 return NULL;
1383 r = mbstowcs(resolved_path, cresolved_path, PATH_MAX);
1384 if (r == (size_t)-1 || r >= PATH_MAX) {
1385 errno = EINVAL;
1386 return NULL;
1387 }
1388 return resolved_path;
1389 }
1390 #endif
1391
1367 void 1392 void
1368 PySys_SetArgv(int argc, char **argv) 1393 PySys_SetArgv(int argc, wchar_t **argv)
1369 { 1394 {
1370 #if defined(HAVE_REALPATH) 1395 #if defined(HAVE_REALPATH)
1371 char fullpath[MAXPATHLEN]; 1396 wchar_t fullpath[MAXPATHLEN];
1372 #elif defined(MS_WINDOWS) 1397 #elif defined(MS_WINDOWS)
1373 char fullpath[MAX_PATH]; 1398 wchar_t fullpath[MAX_PATH];
1374 #endif 1399 #endif
1375 PyObject *av = makeargvobject(argc, argv); 1400 PyObject *av = makeargvobject(argc, argv);
1376 PyObject *path = PySys_GetObject("path"); 1401 PyObject *path = PySys_GetObject("path");
1377 if (av == NULL) 1402 if (av == NULL)
1378 Py_FatalError("no mem for sys.argv"); 1403 Py_FatalError("no mem for sys.argv");
1379 if (PySys_SetObject("argv", av) != 0) 1404 if (PySys_SetObject("argv", av) != 0)
1380 Py_FatalError("can't assign sys.argv"); 1405 Py_FatalError("can't assign sys.argv");
1381 if (path != NULL) { 1406 if (path != NULL) {
1382 char *argv0 = argv[0]; 1407 wchar_t *argv0 = argv[0];
1383 char *p = NULL; 1408 wchar_t *p = NULL;
1384 Py_ssize_t n = 0; 1409 Py_ssize_t n = 0;
1385 PyObject *a; 1410 PyObject *a;
1411 extern int _Py_wreadlink(const wchar_t *, wchar_t *, size_t);
1386 #ifdef HAVE_READLINK 1412 #ifdef HAVE_READLINK
1387 char link[MAXPATHLEN+1]; 1413 wchar_t link[MAXPATHLEN+1];
1388 char argv0copy[2*MAXPATHLEN+1]; 1414 wchar_t argv0copy[2*MAXPATHLEN+1];
1389 int nr = 0; 1415 int nr = 0;
1390 if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0) 1416 if (argc > 0 && argv0 != NULL && wcscmp(argv0, L"-c") != 0)
1391 nr = readlink(argv0, link, MAXPATHLEN); 1417 nr = _Py_wreadlink(argv0, link, MAXPATHLEN);
1392 if (nr > 0) { 1418 if (nr > 0) {
1393 /* It's a symlink */ 1419 /* It's a symlink */
1394 link[nr] = '\0'; 1420 link[nr] = '\0';
1395 if (link[0] == SEP) 1421 if (link[0] == SEP)
1396 argv0 = link; /* Link to absolute path */ 1422 argv0 = link; /* Link to absolute path */
1397 else if (strchr(link, SEP) == NULL) 1423 else if (wcschr(link, SEP) == NULL)
1398 ; /* Link without path */ 1424 ; /* Link without path */
1399 else { 1425 else {
1400 /* Must join(dirname(argv0), link) */ 1426 /* Must join(dirname(argv0), link) */
1401 char *q = strrchr(argv0, SEP); 1427 wchar_t *q = wcsrchr(argv0, SEP);
1402 if (q == NULL) 1428 if (q == NULL)
1403 argv0 = link; /* argv0 without path */ 1429 argv0 = link; /* argv0 without path */
1404 else { 1430 else {
1405 /* Must make a copy */ 1431 /* Must make a copy */
1406 strcpy(argv0copy, argv0); 1432 wcscpy(argv0copy, argv0);
1407 q = strrchr(argv0copy, SEP); 1433 q = wcsrchr(argv0copy, SEP);
1408 strcpy(q+1, link); 1434 wcscpy(q+1, link);
1409 argv0 = argv0copy; 1435 argv0 = argv0copy;
1410 } 1436 }
1411 } 1437 }
1412 } 1438 }
1413 #endif /* HAVE_READLINK */ 1439 #endif /* HAVE_READLINK */
1414 #if SEP == '\\' /* Special case for MS filename syntax */ 1440 #if SEP == '\\' /* Special case for MS filename syntax */
1415 if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0) { 1441 if (argc > 0 && argv0 != NULL && wcscmp(argv0, L"-c") != 0) {
1416 char *q; 1442 wchar_t *q;
1417 #ifdef MS_WINDOWS 1443 #ifdef MS_WINDOWS
1418 char *ptemp; 1444 wchar_t *ptemp;
1419 if (GetFullPathName(argv0, 1445 if (GetFullPathNameW(argv0,
1420 sizeof(fullpath), 1446 sizeof(fullpath)/sizeof(fullpath[0]),
1421 fullpath, 1447 fullpath,
1422 &ptemp)) { 1448 &ptemp)) {
1423 argv0 = fullpath; 1449 argv0 = fullpath;
1424 } 1450 }
1425 #endif 1451 #endif
1426 p = strrchr(argv0, SEP); 1452 p = wcsrchr(argv0, SEP);
1427 /* Test for alternate separator */ 1453 /* Test for alternate separator */
1428 q = strrchr(p ? p : argv0, '/'); 1454 q = wcsrchr(p ? p : argv0, '/');
1429 if (q != NULL) 1455 if (q != NULL)
1430 p = q; 1456 p = q;
1431 if (p != NULL) { 1457 if (p != NULL) {
1432 n = p + 1 - argv0; 1458 n = p + 1 - argv0;
1433 if (n > 1 && p[-1] != ':') 1459 if (n > 1 && p[-1] != ':')
1434 n--; /* Drop trailing separator */ 1460 n--; /* Drop trailing separator */
1435 } 1461 }
1436 } 1462 }
1437 #else /* All other filename syntaxes */ 1463 #else /* All other filename syntaxes */
1438 if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0) { 1464 if (argc > 0 && argv0 != NULL && wcscmp(argv0, L"-c") != 0) {
1439 #if defined(HAVE_REALPATH) 1465 #if defined(HAVE_REALPATH)
1440 if (realpath(argv0, fullpath)) { 1466 if (_wrealpath(argv0, fullpath)) {
1441 argv0 = fullpath; 1467 argv0 = fullpath;
1442 } 1468 }
1443 #endif 1469 #endif
1444 p = strrchr(argv0, SEP); 1470 p = wcsrchr(argv0, SEP);
1445 } 1471 }
1446 if (p != NULL) { 1472 if (p != NULL) {
1447 n = p + 1 - argv0; 1473 n = p + 1 - argv0;
1448 #if SEP == '/' /* Special case for Unix filename syntax */ 1474 #if SEP == '/' /* Special case for Unix filename syntax */
1449 if (n > 1) 1475 if (n > 1)
1450 n--; /* Drop trailing separator */ 1476 n--; /* Drop trailing separator */
1451 #endif /* Unix */ 1477 #endif /* Unix */
1452 } 1478 }
1453 #endif /* All others */ 1479 #endif /* All others */
1454 a = PyUnicode_FromStringAndSize(argv0, n); 1480 a = PyUnicode_FromWideChar(argv0, n);
1455 if (a == NULL) 1481 if (a == NULL)
1456 Py_FatalError("no mem for sys.path insertion"); 1482 Py_FatalError("no mem for sys.path insertion");
1457 if (PyList_Insert(path, 0, a) < 0) 1483 if (PyList_Insert(path, 0, a) < 0)
1458 Py_FatalError("sys.path.insert(0) failed"); 1484 Py_FatalError("sys.path.insert(0) failed");
1459 Py_DECREF(a); 1485 Py_DECREF(a);