summaryrefslogtreecommitdiffstats
path: root/Modules/main.c
diff options
context:
space:
mode:
authorMartin v. Löwis <martin@v.loewis.de>2008-04-05 20:41:37 (GMT)
committerMartin v. Löwis <martin@v.loewis.de>2008-04-05 20:41:37 (GMT)
commit790465fd90e8a72590386465f518db9e67ab843f (patch)
tree62e3e47f6f97120dfdfc94a87dc1a06414d95a13 /Modules/main.c
parentb9279bc88f867d9d3b6606502a678b137329b54d (diff)
downloadcpython-790465fd90e8a72590386465f518db9e67ab843f.zip
cpython-790465fd90e8a72590386465f518db9e67ab843f.tar.gz
cpython-790465fd90e8a72590386465f518db9e67ab843f.tar.bz2
Change command line processing API to use wchar_t.
Fixes #2128.
Diffstat (limited to 'Modules/main.c')
-rw-r--r--Modules/main.c82
1 files changed, 61 insertions, 21 deletions
diff --git a/Modules/main.c b/Modules/main.c
index 9f0b01c..81a3d46 100644
--- a/Modules/main.c
+++ b/Modules/main.c
@@ -12,6 +12,7 @@
#include <windows.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
+#define PATH_MAX MAXPATHLEN
#endif
#endif
@@ -40,17 +41,17 @@ extern "C" {
#endif
/* For Py_GetArgcArgv(); set by main() */
-static char **orig_argv;
+static wchar_t **orig_argv;
static int orig_argc;
/* command line options */
-#define BASE_OPTS "bBc:dEhim:OStuvVW:xX?"
+#define BASE_OPTS L"bBc:dEhim:OStuvVW:xX?"
#define PROGRAM_OPTS BASE_OPTS
/* Short usage message (with %s for argv0) */
static char *usage_line =
-"usage: %s [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
+"usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
/* Long usage message, split into parts < 512 bytes */
static char *usage_1 = "\
@@ -96,9 +97,30 @@ PYTHONHOME : alternate <prefix> directory (or <prefix>%c<exec_prefix>).\n\
PYTHONCASEOK : ignore case in 'import' statements (Windows).\n\
";
+#ifndef MS_WINDOWS
+static FILE*
+_wfopen(const wchar_t *path, const wchar_t *mode)
+{
+ char cpath[PATH_MAX];
+ char cmode[10];
+ size_t r;
+ r = wcstombs(cpath, path, PATH_MAX);
+ if (r == (size_t)-1 || r >= PATH_MAX) {
+ errno = EINVAL;
+ return NULL;
+ }
+ r = wcstombs(cmode, mode, 10);
+ if (r == (size_t)-1 || r >= 10) {
+ errno = EINVAL;
+ return NULL;
+ }
+ return fopen(cpath, cmode);
+}
+#endif
+
static int
-usage(int exitcode, char* program)
+usage(int exitcode, wchar_t* program)
{
FILE *f = exitcode ? stderr : stdout;
@@ -187,11 +209,11 @@ static int RunModule(char *module, int set_argv0)
return 0;
}
-static int RunMainFromImporter(char *filename)
+static int RunMainFromImporter(wchar_t *filename)
{
PyObject *argv0 = NULL, *importer = NULL;
- if ((argv0 = PyUnicode_DecodeFSDefault(filename)) &&
+ if ((argv0 = PyUnicode_FromWideChar(filename,wcslen(filename))) &&
(importer = PyImport_GetImporter(argv0)) &&
(importer->ob_type != &PyNullImporter_Type))
{
@@ -249,12 +271,12 @@ WaitForThreadShutdown(void)
/* Main program */
int
-Py_Main(int argc, char **argv)
+Py_Main(int argc, wchar_t **argv)
{
int c;
int sts;
char *command = NULL;
- char *filename = NULL;
+ wchar_t *filename = NULL;
char *module = NULL;
FILE *fp = stdin;
char *p;
@@ -275,14 +297,19 @@ Py_Main(int argc, char **argv)
while ((c = _PyOS_GetOpt(argc, argv, PROGRAM_OPTS)) != EOF) {
if (c == 'c') {
+ size_t r1 = wcslen(_PyOS_optarg) + 2;
+ size_t r2;
/* -c is the last option; following arguments
that look like options are left for the
command to interpret. */
- command = (char *)malloc(strlen(_PyOS_optarg) + 2);
+ command = (char *)malloc(r1);
if (command == NULL)
Py_FatalError(
"not enough memory to copy -c argument");
- strcpy(command, _PyOS_optarg);
+ r2 = wcstombs(command, _PyOS_optarg, r1);
+ if (r2 > r1-2)
+ Py_FatalError(
+ "not enough memory to copy -c argument");
strcat(command, "\n");
break;
}
@@ -291,11 +318,16 @@ Py_Main(int argc, char **argv)
/* -m is the last option; following arguments
that look like options are left for the
module to interpret. */
- module = (char *)malloc(strlen(_PyOS_optarg) + 2);
+ size_t r1 = wcslen(_PyOS_optarg) + 1;
+ size_t r2;
+ module = (char *)malloc(r1);
if (module == NULL)
Py_FatalError(
"not enough memory to copy -m argument");
- strcpy(module, _PyOS_optarg);
+ r2 = wcstombs(module, _PyOS_optarg, r1);
+ if (r2 >= r1)
+ Py_FatalError(
+ "not enough memory to copy -m argument");
break;
}
@@ -355,7 +387,7 @@ Py_Main(int argc, char **argv)
version++;
break;
- case 'W':
+ case 'W':
PySys_AddWarnOption(_PyOS_optarg);
break;
@@ -384,7 +416,7 @@ Py_Main(int argc, char **argv)
unbuffered = 1;
if (command == NULL && module == NULL && _PyOS_optind < argc &&
- strcmp(argv[_PyOS_optind], "-") != 0)
+ wcscmp(argv[_PyOS_optind], L"-") != 0)
{
#ifdef __VMS
filename = decc$translate_vms(argv[_PyOS_optind]);
@@ -462,14 +494,14 @@ Py_Main(int argc, char **argv)
if (command != NULL) {
/* Backup _PyOS_optind and force sys.argv[0] = '-c' */
_PyOS_optind--;
- argv[_PyOS_optind] = "-c";
+ argv[_PyOS_optind] = L"-c";
}
if (module != NULL) {
/* Backup _PyOS_optind and force sys.argv[0] = '-c'
so that PySys_SetArgv correctly sets sys.path[0] to ''*/
_PyOS_optind--;
- argv[_PyOS_optind] = "-c";
+ argv[_PyOS_optind] = L"-c";
}
PySys_SetArgv(argc-_PyOS_optind, argv+_PyOS_optind);
@@ -506,8 +538,8 @@ Py_Main(int argc, char **argv)
}
if (sts==-1 && filename!=NULL) {
- if ((fp = fopen(filename, "r")) == NULL) {
- fprintf(stderr, "%s: can't open file '%s': [Errno %d] %s\n",
+ if ((fp = _wfopen(filename, L"r")) == NULL) {
+ fprintf(stderr, "%s: can't open file '%ls': [Errno %d] %s\n",
argv[0], filename, errno, strerror(errno));
return 2;
@@ -528,7 +560,7 @@ Py_Main(int argc, char **argv)
struct stat sb;
if (fstat(fileno(fp), &sb) == 0 &&
S_ISDIR(sb.st_mode)) {
- fprintf(stderr, "%s: '%s' is a directory, cannot continue\n", argv[0], filename);
+ fprintf(stderr, "%ls: '%ls' is a directory, cannot continue\n", argv[0], filename);
fclose(fp);
return 1;
}
@@ -536,9 +568,17 @@ Py_Main(int argc, char **argv)
}
if (sts==-1) {
+ char cfilename[PATH_MAX];
+ char *p_cfilename = "<stdin>";
+ if (filename) {
+ size_t r = wcstombs(cfilename, filename, PATH_MAX);
+ p_cfilename = cfilename;
+ if (r == (size_t)-1 || r >= PATH_MAX)
+ p_cfilename = "<decoding error>";
+ }
sts = PyRun_AnyFileExFlags(
fp,
- filename == NULL ? "<stdin>" : filename,
+ p_cfilename,
filename != NULL, &cf) != 0;
}
@@ -589,7 +629,7 @@ Py_Main(int argc, char **argv)
This is rare, but it is needed by the secureware extension. */
void
-Py_GetArgcArgv(int *argc, char ***argv)
+Py_GetArgcArgv(int *argc, wchar_t ***argv)
{
*argc = orig_argc;
*argv = orig_argv;