@@ -59,9 +59,13 @@ extern "C" {
5959static void flush_io (void );
6060static PyObject * run_mod (mod_ty , PyObject * , PyObject * , PyObject * ,
6161 PyCompilerFlags * , PyArena * );
62- static PyObject * run_pyc_file (FILE * , const char * , PyObject * , PyObject * ,
62+ static PyObject * run_pyc_file (FILE * , PyObject * , PyObject * ,
6363 PyCompilerFlags * );
6464static int PyRun_InteractiveOneObjectEx (FILE * , PyObject * , PyCompilerFlags * );
65+ static PyObject * pyrun_file (FILE * fp , PyObject * filename , int start ,
66+ PyObject * globals , PyObject * locals , int closeit ,
67+ PyCompilerFlags * flags );
68+
6569
6670/* Parse input from a file and execute it */
6771int
@@ -269,82 +273,89 @@ PyRun_InteractiveOneFlags(FILE *fp, const char *filename_str, PyCompilerFlags *f
269273 the file type, and, if we may close it, at the first few bytes. */
270274
271275static int
272- maybe_pyc_file (FILE * fp , const char * filename , const char * ext , int closeit )
276+ maybe_pyc_file (FILE * fp , PyObject * filename , int closeit )
273277{
274- if (strcmp (ext , ".pyc" ) == 0 )
278+ PyObject * ext = PyUnicode_FromString (".pyc" );
279+ if (ext == NULL ) {
280+ return -1 ;
281+ }
282+ Py_ssize_t endswith = PyUnicode_Tailmatch (filename , ext , 0 , PY_SSIZE_T_MAX , +1 );
283+ Py_DECREF (ext );
284+ if (endswith ) {
275285 return 1 ;
286+ }
276287
277288 /* Only look into the file if we are allowed to close it, since
278289 it then should also be seekable. */
279- if (closeit ) {
280- /* Read only two bytes of the magic. If the file was opened in
281- text mode, the bytes 3 and 4 of the magic (\r\n) might not
282- be read as they are on disk. */
283- unsigned int halfmagic = PyImport_GetMagicNumber () & 0xFFFF ;
284- unsigned char buf [2 ];
285- /* Mess: In case of -x, the stream is NOT at its start now,
286- and ungetc() was used to push back the first newline,
287- which makes the current stream position formally undefined,
288- and a x-platform nightmare.
289- Unfortunately, we have no direct way to know whether -x
290- was specified. So we use a terrible hack: if the current
291- stream position is not 0, we assume -x was specified, and
292- give up. Bug 132850 on SourceForge spells out the
293- hopelessness of trying anything else (fseek and ftell
294- don't work predictably x-platform for text-mode files).
295- */
296- int ispyc = 0 ;
297- if (ftell (fp ) == 0 ) {
298- if (fread (buf , 1 , 2 , fp ) == 2 &&
299- ((unsigned int )buf [1 ]<<8 | buf [0 ]) == halfmagic )
300- ispyc = 1 ;
301- rewind (fp );
302- }
303- return ispyc ;
290+ if (!closeit ) {
291+ return 0 ;
304292 }
305- return 0 ;
293+
294+ /* Read only two bytes of the magic. If the file was opened in
295+ text mode, the bytes 3 and 4 of the magic (\r\n) might not
296+ be read as they are on disk. */
297+ unsigned int halfmagic = PyImport_GetMagicNumber () & 0xFFFF ;
298+ unsigned char buf [2 ];
299+ /* Mess: In case of -x, the stream is NOT at its start now,
300+ and ungetc() was used to push back the first newline,
301+ which makes the current stream position formally undefined,
302+ and a x-platform nightmare.
303+ Unfortunately, we have no direct way to know whether -x
304+ was specified. So we use a terrible hack: if the current
305+ stream position is not 0, we assume -x was specified, and
306+ give up. Bug 132850 on SourceForge spells out the
307+ hopelessness of trying anything else (fseek and ftell
308+ don't work predictably x-platform for text-mode files).
309+ */
310+ int ispyc = 0 ;
311+ if (ftell (fp ) == 0 ) {
312+ if (fread (buf , 1 , 2 , fp ) == 2 &&
313+ ((unsigned int )buf [1 ]<<8 | buf [0 ]) == halfmagic )
314+ ispyc = 1 ;
315+ rewind (fp );
316+ }
317+ return ispyc ;
306318}
307319
320+
308321static int
309- set_main_loader (PyObject * d , const char * filename , const char * loader_name )
322+ set_main_loader (PyObject * d , PyObject * filename , const char * loader_name )
310323{
311- PyObject * filename_obj , * bootstrap , * loader_type = NULL , * loader ;
312- int result = 0 ;
313-
314- filename_obj = PyUnicode_DecodeFSDefault (filename );
315- if (filename_obj == NULL )
316- return -1 ;
317324 PyInterpreterState * interp = _PyInterpreterState_GET ();
318- bootstrap = PyObject_GetAttrString (interp -> importlib ,
319- "_bootstrap_external" );
320- if (bootstrap != NULL ) {
321- loader_type = PyObject_GetAttrString (bootstrap , loader_name );
322- Py_DECREF (bootstrap );
325+ PyObject * bootstrap = PyObject_GetAttrString (interp -> importlib ,
326+ "_bootstrap_external" );
327+ if (bootstrap == NULL ) {
328+ return -1 ;
323329 }
330+
331+ PyObject * loader_type = PyObject_GetAttrString (bootstrap , loader_name );
332+ Py_DECREF (bootstrap );
324333 if (loader_type == NULL ) {
325- Py_DECREF (filename_obj );
326334 return -1 ;
327335 }
328- loader = PyObject_CallFunction (loader_type , "sN" , "__main__" , filename_obj );
336+
337+ PyObject * loader = PyObject_CallFunction (loader_type ,
338+ "sO" , "__main__" , filename );
329339 Py_DECREF (loader_type );
330340 if (loader == NULL ) {
331341 return -1 ;
332342 }
343+
333344 if (PyDict_SetItemString (d , "__loader__" , loader ) < 0 ) {
334- result = -1 ;
345+ Py_DECREF (loader );
346+ return -1 ;
335347 }
336348 Py_DECREF (loader );
337- return result ;
349+ return 0 ;
338350}
339351
340- int
341- PyRun_SimpleFileExFlags (FILE * fp , const char * filename , int closeit ,
342- PyCompilerFlags * flags )
352+
353+ static int
354+ pyrun_simple_file (FILE * fp , PyObject * filename , int closeit ,
355+ PyCompilerFlags * flags )
343356{
344357 PyObject * m , * d , * v ;
345- const char * ext ;
346358 int set_file_name = 0 , ret = -1 ;
347- size_t len ;
348359
349360 m = PyImport_AddModule ("__main__" );
350361 if (m == NULL )
@@ -355,29 +366,29 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit,
355366 if (PyErr_Occurred ()) {
356367 goto done ;
357368 }
358- PyObject * f ;
359- f = PyUnicode_DecodeFSDefault (filename );
360- if (f == NULL )
361- goto done ;
362- if (PyDict_SetItemString (d , "__file__" , f ) < 0 ) {
363- Py_DECREF (f );
369+ if (PyDict_SetItemString (d , "__file__" , filename ) < 0 ) {
364370 goto done ;
365371 }
366372 if (PyDict_SetItemString (d , "__cached__" , Py_None ) < 0 ) {
367- Py_DECREF (f );
368373 goto done ;
369374 }
370375 set_file_name = 1 ;
371- Py_DECREF (f );
372376 }
373- len = strlen (filename );
374- ext = filename + len - (len > 4 ? 4 : 0 );
375- if (maybe_pyc_file (fp , filename , ext , closeit )) {
377+
378+ int pyc = maybe_pyc_file (fp , filename , closeit );
379+ if (pyc < 0 ) {
380+ goto done ;
381+ }
382+
383+ if (pyc ) {
376384 FILE * pyc_fp ;
377385 /* Try to run a pyc file. First, re-open in binary */
378- if (closeit )
386+ if (closeit ) {
379387 fclose (fp );
380- if ((pyc_fp = _Py_fopen (filename , "rb" )) == NULL ) {
388+ }
389+
390+ pyc_fp = _Py_fopen_obj (filename , "rb" );
391+ if (pyc_fp == NULL ) {
381392 fprintf (stderr , "python: Can't reopen .pyc file\n" );
382393 goto done ;
383394 }
@@ -388,17 +399,17 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit,
388399 fclose (pyc_fp );
389400 goto done ;
390401 }
391- v = run_pyc_file (pyc_fp , filename , d , d , flags );
402+ v = run_pyc_file (pyc_fp , d , d , flags );
392403 } else {
393404 /* When running from stdin, leave __main__.__loader__ alone */
394- if (strcmp (filename , "<stdin>" ) != 0 &&
405+ if (PyUnicode_CompareWithASCIIString (filename , "<stdin>" ) != 0 &&
395406 set_main_loader (d , filename , "SourceFileLoader" ) < 0 ) {
396407 fprintf (stderr , "python: failed to set __main__.__loader__\n" );
397408 ret = -1 ;
398409 goto done ;
399410 }
400- v = PyRun_FileExFlags (fp , filename , Py_file_input , d , d ,
401- closeit , flags );
411+ v = pyrun_file (fp , filename , Py_file_input , d , d ,
412+ closeit , flags );
402413 }
403414 flush_io ();
404415 if (v == NULL ) {
@@ -421,6 +432,21 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit,
421432 return ret ;
422433}
423434
435+
436+ int
437+ PyRun_SimpleFileExFlags (FILE * fp , const char * filename , int closeit ,
438+ PyCompilerFlags * flags )
439+ {
440+ PyObject * filename_obj = PyUnicode_DecodeFSDefault (filename );
441+ if (filename_obj == NULL ) {
442+ return -1 ;
443+ }
444+ int res = pyrun_simple_file (fp , filename_obj , closeit , flags );
445+ Py_DECREF (filename_obj );
446+ return res ;
447+ }
448+
449+
424450int
425451PyRun_SimpleStringFlags (const char * command , PyCompilerFlags * flags )
426452{
@@ -1039,40 +1065,54 @@ PyRun_StringFlags(const char *str, int start, PyObject *globals,
10391065 return ret ;
10401066}
10411067
1042- PyObject *
1043- PyRun_FileExFlags (FILE * fp , const char * filename_str , int start , PyObject * globals ,
1044- PyObject * locals , int closeit , PyCompilerFlags * flags )
1045- {
1046- PyObject * ret = NULL ;
1047- mod_ty mod ;
1048- PyArena * arena = NULL ;
1049- PyObject * filename ;
1050-
1051- filename = PyUnicode_DecodeFSDefault (filename_str );
1052- if (filename == NULL )
1053- goto exit ;
10541068
1055- arena = PyArena_New ();
1056- if (arena == NULL )
1057- goto exit ;
1069+ static PyObject *
1070+ pyrun_file (FILE * fp , PyObject * filename , int start , PyObject * globals ,
1071+ PyObject * locals , int closeit , PyCompilerFlags * flags )
1072+ {
1073+ PyArena * arena = PyArena_New ();
1074+ if (arena == NULL ) {
1075+ return NULL ;
1076+ }
10581077
1078+ mod_ty mod ;
10591079 mod = PyParser_ASTFromFileObject (fp , filename , NULL , start , NULL , NULL ,
10601080 flags , NULL , arena );
10611081
1062- if (closeit )
1082+ if (closeit ) {
10631083 fclose (fp );
1064- if (mod == NULL ) {
1065- goto exit ;
10661084 }
1067- ret = run_mod (mod , filename , globals , locals , flags , arena );
10681085
1069- exit :
1070- Py_XDECREF (filename );
1071- if (arena != NULL )
1072- PyArena_Free (arena );
1086+ PyObject * ret ;
1087+ if (mod != NULL ) {
1088+ ret = run_mod (mod , filename , globals , locals , flags , arena );
1089+ }
1090+ else {
1091+ ret = NULL ;
1092+ }
1093+ PyArena_Free (arena );
1094+
10731095 return ret ;
10741096}
10751097
1098+
1099+ PyObject *
1100+ PyRun_FileExFlags (FILE * fp , const char * filename , int start , PyObject * globals ,
1101+ PyObject * locals , int closeit , PyCompilerFlags * flags )
1102+ {
1103+ PyObject * filename_obj = PyUnicode_DecodeFSDefault (filename );
1104+ if (filename_obj == NULL ) {
1105+ return NULL ;
1106+ }
1107+
1108+ PyObject * res = pyrun_file (fp , filename_obj , start , globals ,
1109+ locals , closeit , flags );
1110+ Py_DECREF (filename_obj );
1111+ return res ;
1112+
1113+ }
1114+
1115+
10761116static void
10771117flush_io (void )
10781118{
@@ -1155,8 +1195,8 @@ run_mod(mod_ty mod, PyObject *filename, PyObject *globals, PyObject *locals,
11551195}
11561196
11571197static PyObject *
1158- run_pyc_file (FILE * fp , const char * filename , PyObject * globals ,
1159- PyObject * locals , PyCompilerFlags * flags )
1198+ run_pyc_file (FILE * fp , PyObject * globals , PyObject * locals ,
1199+ PyCompilerFlags * flags )
11601200{
11611201 PyThreadState * tstate = _PyThreadState_GET ();
11621202 PyCodeObject * co ;
0 commit comments