diff options
author | Daryl McDaniel <edk2-lists@mc2research.org> | 2015-11-07 19:43:57 +0000 |
---|---|---|
committer | darylm503 <darylm503@Edk2> | 2015-11-07 19:43:57 +0000 |
commit | 3ec97ca490009ed5604ccd7f2653e5a9ecbf3474 (patch) | |
tree | 509aac1ca86fe15cfb8f796c089a8cf49195aeab | |
parent | 3257aa99321d745773a6bd1bd4ce7f6fafe74411 (diff) | |
download | edk2-platforms-3ec97ca490009ed5604ccd7f2653e5a9ecbf3474.tar.xz |
AppPkg/Applications/Python/Python-2.7.10: Initial Checkin part 5/5.
These files are candidates for modification during the port to EDK II.
The following files were copied, unchanged, from the Python 2.7.2 port.
Ia32/pyconfig.h
X64/pyconfig.h
PyMod-2.7.10/Modules/config.c
PyMod-2.7.10/Modules/edk2module.c
Py2710ReadMe.txt // Copied from PythonReadMe.txt
Python2710.inf // Copied from PythonCore.inf
The remaining files were copied, unchanged, from the cPython 2.7.10 distribution.
These files are unchanged and set the baseline for subsequent commits.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Daryl McDaniel <edk2-lists@mc2research.org>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18741 6f19259b-4bc3-4df7-8a09-765794883524
27 files changed, 31435 insertions, 0 deletions
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Ia32/pyconfig.h b/AppPkg/Applications/Python/Python-2.7.10/Ia32/pyconfig.h new file mode 100644 index 0000000000..7970f14430 --- /dev/null +++ b/AppPkg/Applications/Python/Python-2.7.10/Ia32/pyconfig.h @@ -0,0 +1,1262 @@ +/** @file
+ Manually generated Python Configuration file for EDK II.
+
+ Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#ifndef Py_PYCONFIG_H
+#define Py_PYCONFIG_H
+
+#include <Uefi.h>
+
+#define PLATFORM "uefi"
+
+/* Define if building universal (internal helper macro) */
+#undef AC_APPLE_UNIVERSAL_BUILD
+
+/* Define for AIX if your compiler is a genuine IBM xlC/xlC_r and you want
+ support for AIX C++ shared extension modules. */
+#undef AIX_GENUINE_CPLUSPLUS
+
+/* Define this if you have AtheOS threads. */
+#undef ATHEOS_THREADS
+
+/* Define this if you have BeOS threads. */
+#undef BEOS_THREADS
+
+/* Define if you have the Mach cthreads package */
+#undef C_THREADS
+
+/* Define if C doubles are 64-bit IEEE 754 binary format, stored in ARM
+ mixed-endian order (byte order 45670123) */
+#undef DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754
+
+/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the most
+ significant byte first */
+#undef DOUBLE_IS_BIG_ENDIAN_IEEE754
+
+/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the
+ least significant byte first */
+#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754
+
+/* Define if --enable-ipv6 is specified */
+#undef ENABLE_IPV6
+
+/* Define if flock needs to be linked with bsd library. */
+#undef FLOCK_NEEDS_LIBBSD
+
+/* Define if getpgrp() must be called as getpgrp(0). */
+#undef GETPGRP_HAVE_ARG
+
+/* Define if gettimeofday() does not have second (timezone) argument This is
+ the case on Motorola V4 (R40V4.2) */
+#undef GETTIMEOFDAY_NO_TZ
+
+/* Define to 1 if you have the 'acosh' function. */
+#undef HAVE_ACOSH
+
+/* struct addrinfo (netdb.h) */
+#undef HAVE_ADDRINFO
+
+/* Define to 1 if you have the 'alarm' function. */
+#undef HAVE_ALARM
+
+/* Define this if your time.h defines altzone. */
+#undef HAVE_ALTZONE
+
+/* Define to 1 if you have the 'asinh' function. */
+#undef HAVE_ASINH
+
+/* Define to 1 if you have the <asm/types.h> header file. */
+#undef HAVE_ASM_TYPES_H
+
+/* Define to 1 if you have the 'atanh' function. */
+#undef HAVE_ATANH
+
+/* Define if GCC supports __attribute__((format(PyArg_ParseTuple, 2, 3))) */
+#undef HAVE_ATTRIBUTE_FORMAT_PARSETUPLE
+
+/* Define to 1 if you have the 'bind_textdomain_codeset' function. */
+#undef HAVE_BIND_TEXTDOMAIN_CODESET
+
+/* Define to 1 if you have the <bluetooth/bluetooth.h> header file. */
+#undef HAVE_BLUETOOTH_BLUETOOTH_H
+
+/* Define to 1 if you have the <bluetooth.h> header file. */
+#undef HAVE_BLUETOOTH_H
+
+/* Define if nice() returns success/failure instead of the new priority. */
+#undef HAVE_BROKEN_NICE
+
+/* Define if the system reports an invalid PIPE_BUF value. */
+#undef HAVE_BROKEN_PIPE_BUF
+
+/* Define if poll() sets errno on invalid file descriptors. */
+#undef HAVE_BROKEN_POLL
+
+/* Define if the Posix semaphores do not work on your system */
+#define HAVE_BROKEN_POSIX_SEMAPHORES 1
+
+/* Define if pthread_sigmask() does not work on your system. */
+#define HAVE_BROKEN_PTHREAD_SIGMASK 1
+
+/* define to 1 if your sem_getvalue is broken. */
+#define HAVE_BROKEN_SEM_GETVALUE 1
+
+/* Define this if you have the type _Bool. */
+#define HAVE_C99_BOOL 1
+
+/* Define to 1 if you have the 'chflags' function. */
+#undef HAVE_CHFLAGS
+
+/* Define to 1 if you have the 'chown' function. */
+#undef HAVE_CHOWN
+
+/* Define if you have the 'chroot' function. */
+#undef HAVE_CHROOT
+
+/* Define to 1 if you have the 'clock' function. */
+#define HAVE_CLOCK 1
+
+/* Define to 1 if you have the 'confstr' function. */
+#undef HAVE_CONFSTR
+
+/* Define to 1 if you have the <conio.h> header file. */
+#undef HAVE_CONIO_H
+
+/* Define to 1 if you have the 'copysign' function. */
+#undef HAVE_COPYSIGN
+
+/* Define to 1 if you have the 'ctermid' function. */
+#undef HAVE_CTERMID
+
+/* Define if you have the 'ctermid_r' function. */
+#undef HAVE_CTERMID_R
+
+/* Define to 1 if you have the <curses.h> header file. */
+#undef HAVE_CURSES_H
+
+/* Define if you have the 'is_term_resized' function. */
+#undef HAVE_CURSES_IS_TERM_RESIZED
+
+/* Define if you have the 'resizeterm' function. */
+#undef HAVE_CURSES_RESIZETERM
+
+/* Define if you have the 'resize_term' function. */
+#undef HAVE_CURSES_RESIZE_TERM
+
+/* Define to 1 if you have the declaration of 'isfinite', and to 0 if you
+ don't. */
+#define HAVE_DECL_ISFINITE 0
+
+/* Define to 1 if you have the declaration of 'isinf', and to 0 if you don't.
+ */
+#define HAVE_DECL_ISINF 1
+
+/* Define to 1 if you have the declaration of 'isnan', and to 0 if you don't.
+ */
+#define HAVE_DECL_ISNAN 1
+
+/* Define to 1 if you have the declaration of 'tzname', and to 0 if you don't.
+ */
+#define HAVE_DECL_TZNAME 0
+
+/* Define to 1 if you have the device macros. */
+#undef HAVE_DEVICE_MACROS
+
+/* Define if we have /dev/ptc. */
+#undef HAVE_DEV_PTC
+
+/* Define if we have /dev/ptmx. */
+#undef HAVE_DEV_PTMX
+
+/* Define to 1 if you have the <direct.h> header file. */
+#undef HAVE_DIRECT_H
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines 'DIR'.
+ */
+#define HAVE_DIRENT_H 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the 'dlopen' function. */
+#undef HAVE_DLOPEN
+
+/* Define to 1 if you have the 'dup2' function. */
+#define HAVE_DUP2 1
+
+/* Defined when any dynamic module loading is enabled. */
+#undef HAVE_DYNAMIC_LOADING
+
+/* Define if you have the 'epoll' functions. */
+#undef HAVE_EPOLL
+
+/* Define to 1 if you have the 'erf' function. */
+#undef HAVE_ERF
+
+/* Define to 1 if you have the 'erfc' function. */
+#undef HAVE_ERFC
+
+/* Define to 1 if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if you have the 'execv' function. */
+#undef HAVE_EXECV
+
+/* Define to 1 if you have the 'expm1' function. */
+#undef HAVE_EXPM1
+
+/* Define if you have the 'fchdir' function. */
+#undef HAVE_FCHDIR
+
+/* Define to 1 if you have the 'fchmod' function. */
+#undef HAVE_FCHMOD
+
+/* Define to 1 if you have the 'fchown' function. */
+#undef HAVE_FCHOWN
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define if you have the 'fdatasync' function. */
+#undef HAVE_FDATASYNC
+
+/* Define to 1 if you have the 'finite' function. */
+#define HAVE_FINITE 1
+
+/* Define to 1 if you have the 'flock' function. */
+#undef HAVE_FLOCK
+
+/* Define to 1 if you have the 'fork' function. */
+#undef HAVE_FORK
+
+/* Define to 1 if you have the 'forkpty' function. */
+#undef HAVE_FORKPTY
+
+/* Define to 1 if you have the 'fpathconf' function. */
+#undef HAVE_FPATHCONF
+
+/* Define to 1 if you have the 'fseek64' function. */
+#undef HAVE_FSEEK64
+
+/* Define to 1 if you have the 'fseeko' function. */
+#define HAVE_FSEEKO 1
+
+/* Define to 1 if you have the 'fstatvfs' function. */
+#undef HAVE_FSTATVFS
+
+/* Define if you have the 'fsync' function. */
+#undef HAVE_FSYNC
+
+/* Define to 1 if you have the 'ftell64' function. */
+#undef HAVE_FTELL64
+
+/* Define to 1 if you have the 'ftello' function. */
+#define HAVE_FTELLO 1
+
+/* Define to 1 if you have the 'ftime' function. */
+#undef HAVE_FTIME
+
+/* Define to 1 if you have the 'ftruncate' function. */
+#undef HAVE_FTRUNCATE
+
+/* Define to 1 if you have the 'gai_strerror' function. */
+#undef HAVE_GAI_STRERROR
+
+/* Define to 1 if you have the 'gamma' function. */
+#undef HAVE_GAMMA
+
+/* Define if we can use gcc inline assembler to get and set x87 control word
+*/
+#if defined(__GNUC__)
+ #define HAVE_GCC_ASM_FOR_X87 1
+#else
+ #undef HAVE_GCC_ASM_FOR_X87
+#endif
+
+/* Define if you have the getaddrinfo function. */
+#undef HAVE_GETADDRINFO
+
+/* Define to 1 if you have the 'getcwd' function. */
+#define HAVE_GETCWD 1
+
+/* Define this if you have flockfile(), getc_unlocked(), and funlockfile() */
+#undef HAVE_GETC_UNLOCKED
+
+/* Define to 1 if you have the 'getgroups' function. */
+#undef HAVE_GETGROUPS
+
+/* Define to 1 if you have the 'gethostbyname' function. */
+#undef HAVE_GETHOSTBYNAME
+
+/* Define this if you have some version of gethostbyname_r() */
+#undef HAVE_GETHOSTBYNAME_R
+
+/* Define this if you have the 3-arg version of gethostbyname_r(). */
+#undef HAVE_GETHOSTBYNAME_R_3_ARG
+
+/* Define this if you have the 5-arg version of gethostbyname_r(). */
+#undef HAVE_GETHOSTBYNAME_R_5_ARG
+
+/* Define this if you have the 6-arg version of gethostbyname_r(). */
+#undef HAVE_GETHOSTBYNAME_R_6_ARG
+
+/* Define to 1 if you have the 'getitimer' function. */
+#undef HAVE_GETITIMER
+
+/* Define to 1 if you have the 'getloadavg' function. */
+#undef HAVE_GETLOADAVG
+
+/* Define to 1 if you have the 'getlogin' function. */
+#undef HAVE_GETLOGIN
+
+/* Define to 1 if you have the 'getnameinfo' function. */
+#undef HAVE_GETNAMEINFO
+
+/* Define if you have the 'getpagesize' function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define to 1 if you have the 'getpeername' function. */
+#define HAVE_GETPEERNAME 1
+
+/* Define to 1 if you have the 'getpgid' function. */
+#undef HAVE_GETPGID
+
+/* Define to 1 if you have the 'getpgrp' function. */
+#undef HAVE_GETPGRP
+
+/* Define to 1 if you have the 'getpid' function. */
+#undef HAVE_GETPID
+
+/* Define to 1 if you have the 'getpriority' function. */
+#undef HAVE_GETPRIORITY
+
+/* Define to 1 if you have the 'getpwent' function. */
+#undef HAVE_GETPWENT
+
+/* Define to 1 if you have the 'getresgid' function. */
+#undef HAVE_GETRESGID
+
+/* Define to 1 if you have the 'getresuid' function. */
+#undef HAVE_GETRESUID
+
+/* Define to 1 if you have the 'getsid' function. */
+#undef HAVE_GETSID
+
+/* Define to 1 if you have the 'getspent' function. */
+#undef HAVE_GETSPENT
+
+/* Define to 1 if you have the 'getspnam' function. */
+#undef HAVE_GETSPNAM
+
+/* Define to 1 if you have the 'gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Define to 1 if you have the 'getwd' function. */
+#undef HAVE_GETWD
+
+/* Define to 1 if you have the <grp.h> header file. */
+#undef HAVE_GRP_H
+
+/* Define if you have the 'hstrerror' function. */
+#undef HAVE_HSTRERROR
+
+/* Define to 1 if you have the 'hypot' function. */
+#undef HAVE_HYPOT
+
+/* Define to 1 if you have the <ieeefp.h> header file. */
+#undef HAVE_IEEEFP_H
+
+/* Define if you have the 'inet_aton' function. */
+#define HAVE_INET_ATON 1
+
+/* Define if you have the 'inet_pton' function. */
+#define HAVE_INET_PTON 1
+
+/* Define to 1 if you have the 'initgroups' function. */
+#undef HAVE_INITGROUPS
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <io.h> header file. */
+#undef HAVE_IO_H
+
+/* Define to 1 if you have the 'kill' function. */
+#undef HAVE_KILL
+
+/* Define to 1 if you have the 'killpg' function. */
+#undef HAVE_KILLPG
+
+/* Define if you have the 'kqueue' functions. */
+#undef HAVE_KQUEUE
+
+/* Define to 1 if you have the <langinfo.h> header file. */
+#undef HAVE_LANGINFO_H /* non-functional in EFI. */
+
+/* Defined to enable large file support when an off_t is bigger than a long
+ and long long is available and at least as big as an off_t. You may need to
+ add some flags for configuration and compilation to enable this mode. (For
+ Solaris and Linux, the necessary defines are already defined.) */
+#undef HAVE_LARGEFILE_SUPPORT
+
+/* Define to 1 if you have the 'lchflags' function. */
+#undef HAVE_LCHFLAGS
+
+/* Define to 1 if you have the 'lchmod' function. */
+#undef HAVE_LCHMOD
+
+/* Define to 1 if you have the 'lchown' function. */
+#undef HAVE_LCHOWN
+
+/* Define to 1 if you have the 'lgamma' function. */
+#undef HAVE_LGAMMA
+
+/* Define to 1 if you have the 'dl' library (-ldl). */
+#undef HAVE_LIBDL
+
+/* Define to 1 if you have the 'dld' library (-ldld). */
+#undef HAVE_LIBDLD
+
+/* Define to 1 if you have the 'ieee' library (-lieee). */
+#undef HAVE_LIBIEEE
+
+/* Define to 1 if you have the <libintl.h> header file. */
+#undef HAVE_LIBINTL_H
+
+/* Define if you have the readline library (-lreadline). */
+#undef HAVE_LIBREADLINE
+
+/* Define to 1 if you have the 'resolv' library (-lresolv). */
+#undef HAVE_LIBRESOLV
+
+/* Define to 1 if you have the <libutil.h> header file. */
+#undef HAVE_LIBUTIL_H
+
+/* Define if you have the 'link' function. */
+#undef HAVE_LINK
+
+/* Define to 1 if you have the <linux/netlink.h> header file. */
+#undef HAVE_LINUX_NETLINK_H
+
+/* Define to 1 if you have the <linux/tipc.h> header file. */
+#undef HAVE_LINUX_TIPC_H
+
+/* Define to 1 if you have the 'log1p' function. */
+#undef HAVE_LOG1P
+
+/* Define this if you have the type long double. */
+#undef HAVE_LONG_DOUBLE
+
+/* Define this if you have the type long long. */
+#define HAVE_LONG_LONG 1
+
+/* Define to 1 if you have the 'lstat' function. */
+#define HAVE_LSTAT 1
+
+/* Define this if you have the makedev macro. */
+#undef HAVE_MAKEDEV
+
+/* Define to 1 if you have the 'memmove' function. */
+#define HAVE_MEMMOVE 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the 'mkfifo' function. */
+#undef HAVE_MKFIFO
+
+/* Define to 1 if you have the 'mknod' function. */
+#undef HAVE_MKNOD
+
+/* Define to 1 if you have the 'mktime' function. */
+#define HAVE_MKTIME 1
+
+/* Define to 1 if you have the 'mremap' function. */
+#undef HAVE_MREMAP
+
+/* Define to 1 if you have the <ncurses.h> header file. */
+#undef HAVE_NCURSES_H
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines 'DIR'. */
+#undef HAVE_NDIR_H
+
+/* Define to 1 if you have the <netpacket/packet.h> header file. */
+#undef HAVE_NETPACKET_PACKET_H
+
+/* Define to 1 if you have the 'nice' function. */
+#undef HAVE_NICE
+
+/* Define to 1 if you have the 'openpty' function. */
+#undef HAVE_OPENPTY
+
+/* Define if compiling using MacOS X 10.5 SDK or later. */
+#undef HAVE_OSX105_SDK
+
+/* Define to 1 if you have the 'pathconf' function. */
+#undef HAVE_PATHCONF
+
+/* Define to 1 if you have the 'pause' function. */
+#undef HAVE_PAUSE
+
+/* Define to 1 if you have the 'plock' function. */
+#undef HAVE_PLOCK
+
+/* Define to 1 if you have the 'poll' function. */
+#define HAVE_POLL 1
+
+/* Define to 1 if you have the <poll.h> header file. */
+#undef HAVE_POLL_H
+
+/* Define to 1 if you have the <process.h> header file. */
+#undef HAVE_PROCESS_H
+
+/* Define if your compiler supports function prototype */
+#define HAVE_PROTOTYPES 1
+
+/* Define if you have GNU PTH threads. */
+#undef HAVE_PTH
+
+/* Defined for Solaris 2.6 bug in pthread header. */
+#undef HAVE_PTHREAD_DESTRUCTOR
+
+/* Define to 1 if you have the <pthread.h> header file. */
+#undef HAVE_PTHREAD_H
+
+/* Define to 1 if you have the 'pthread_init' function. */
+#undef HAVE_PTHREAD_INIT
+
+/* Define to 1 if you have the 'pthread_sigmask' function. */
+#undef HAVE_PTHREAD_SIGMASK
+
+/* Define to 1 if you have the <pty.h> header file. */
+#undef HAVE_PTY_H
+
+/* Define to 1 if you have the 'putenv' function. */
+#undef HAVE_PUTENV
+
+/* Define to 1 if you have the 'readlink' function. */
+#undef HAVE_READLINK
+
+/* Define to 1 if you have the 'realpath' function. */
+#define HAVE_REALPATH 1
+
+/* Define if you have readline 2.1 */
+#undef HAVE_RL_CALLBACK
+
+/* Define if you can turn off readline's signal handling. */
+#undef HAVE_RL_CATCH_SIGNAL
+
+/* Define if you have readline 2.2 */
+#undef HAVE_RL_COMPLETION_APPEND_CHARACTER
+
+/* Define if you have readline 4.0 */
+#undef HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK
+
+/* Define if you have readline 4.2 */
+#undef HAVE_RL_COMPLETION_MATCHES
+
+/* Define if you have rl_completion_suppress_append */
+#undef HAVE_RL_COMPLETION_SUPPRESS_APPEND
+
+/* Define if you have readline 4.0 */
+#undef HAVE_RL_PRE_INPUT_HOOK
+
+/* Define to 1 if you have the 'round' function. */
+#undef HAVE_ROUND
+
+/* Define to 1 if you have the 'select' function. */
+#define HAVE_SELECT 1
+
+/* Define to 1 if you have the 'sem_getvalue' function. */
+#undef HAVE_SEM_GETVALUE
+
+/* Define to 1 if you have the 'sem_open' function. */
+#undef HAVE_SEM_OPEN
+
+/* Define to 1 if you have the 'sem_timedwait' function. */
+#undef HAVE_SEM_TIMEDWAIT
+
+/* Define to 1 if you have the 'sem_unlink' function. */
+#undef HAVE_SEM_UNLINK
+
+/* Define to 1 if you have the 'setegid' function. */
+#undef HAVE_SETEGID
+
+/* Define to 1 if you have the 'seteuid' function. */
+#undef HAVE_SETEUID
+
+/* Define to 1 if you have the 'setgid' function. */
+#undef HAVE_SETGID
+
+/* Define if you have the 'setgroups' function. */
+#undef HAVE_SETGROUPS
+
+/* Define to 1 if you have the 'setitimer' function. */
+#undef HAVE_SETITIMER
+
+/* Define to 1 if you have the 'setlocale' function. */
+#define HAVE_SETLOCALE 1
+
+/* Define to 1 if you have the 'setpgid' function. */
+#undef HAVE_SETPGID
+
+/* Define to 1 if you have the 'setpgrp' function. */
+#undef HAVE_SETPGRP
+
+/* Define to 1 if you have the 'setregid' function. */
+#undef HAVE_SETREGID
+
+/* Define to 1 if you have the 'setresgid' function. */
+#undef HAVE_SETRESGID
+
+/* Define to 1 if you have the 'setresuid' function. */
+#undef HAVE_SETRESUID
+
+/* Define to 1 if you have the 'setreuid' function. */
+#undef HAVE_SETREUID
+
+/* Define to 1 if you have the 'setsid' function. */
+#undef HAVE_SETSID
+
+/* Define to 1 if you have the 'setuid' function. */
+#undef HAVE_SETUID
+
+/* Define to 1 if you have the 'setvbuf' function. */
+#define HAVE_SETVBUF 1
+
+/* Define to 1 if you have the <shadow.h> header file. */
+#undef HAVE_SHADOW_H
+
+/* Define to 1 if you have the 'sigaction' function. */
+#undef HAVE_SIGACTION
+
+/* Define to 1 if you have the 'siginterrupt' function. */
+#undef HAVE_SIGINTERRUPT
+
+/* Define to 1 if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H 1
+
+/* Define to 1 if you have the 'sigrelse' function. */
+#undef HAVE_SIGRELSE
+
+/* Define to 1 if you have the 'snprintf' function. */
+#define HAVE_SNPRINTF 1
+
+/* Define if sockaddr has sa_len member */
+#undef HAVE_SOCKADDR_SA_LEN
+
+/* struct sockaddr_storage (sys/socket.h) */
+#undef HAVE_SOCKADDR_STORAGE
+
+/* Define if you have the 'socketpair' function. */
+#undef HAVE_SOCKETPAIR
+
+/* Define to 1 if you have the <spawn.h> header file. */
+#undef HAVE_SPAWN_H
+
+/* Define if your compiler provides ssize_t */
+#define HAVE_SSIZE_T 1
+
+/* Define to 1 if you have the 'statvfs' function. */
+#undef HAVE_STATVFS
+
+/* Define if you have struct stat.st_mtim.tv_nsec */
+#undef HAVE_STAT_TV_NSEC
+
+/* Define if you have struct stat.st_mtimensec */
+#undef HAVE_STAT_TV_NSEC2
+
+/* Define if your compiler supports variable length function prototypes (e.g.
+ void fprintf(FILE *, char *, ...);) *and* <stdarg.h> */
+#define HAVE_STDARG_PROTOTYPES 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the 'strdup' function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the 'strftime' function. */
+#define HAVE_STRFTIME 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <stropts.h> header file. */
+#undef HAVE_STROPTS_H
+
+/* Define to 1 if 'st_birthtime' is a member of 'struct stat'. */
+#define HAVE_STRUCT_STAT_ST_BIRTHTIME 1
+
+/* Define to 1 if 'st_blksize' is a member of 'struct stat'. */
+#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
+
+/* Define to 1 if 'st_blocks' is a member of 'struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_BLOCKS
+
+/* Define to 1 if 'st_flags' is a member of 'struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_FLAGS
+
+/* Define to 1 if 'st_gen' is a member of 'struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_GEN
+
+/* Define to 1 if 'st_rdev' is a member of 'struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_RDEV
+
+/* Define to 1 if 'tm_zone' is a member of 'struct tm'. */
+#undef HAVE_STRUCT_TM_TM_ZONE
+
+/* Define to 1 if your 'struct stat' has 'st_blocks'. Deprecated, use
+ 'HAVE_STRUCT_STAT_ST_BLOCKS' instead. */
+#undef HAVE_ST_BLOCKS
+
+/* Define if you have the 'symlink' function. */
+#undef HAVE_SYMLINK
+
+/* Define to 1 if you have the 'sysconf' function. */
+#undef HAVE_SYSCONF
+
+/* Define to 1 if you have the <sysexits.h> header file. */
+#undef HAVE_SYSEXITS_H
+
+/* Define to 1 if you have the <sys/audioio.h> header file. */
+#undef HAVE_SYS_AUDIOIO_H
+
+/* Define to 1 if you have the <sys/bsdtty.h> header file. */
+#undef HAVE_SYS_BSDTTY_H
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines 'DIR'.
+ */
+#undef HAVE_SYS_DIR_H
+
+/* Define to 1 if you have the <sys/epoll.h> header file. */
+#undef HAVE_SYS_EPOLL_H
+
+/* Define to 1 if you have the <sys/event.h> header file. */
+#undef HAVE_SYS_EVENT_H
+
+/* Define to 1 if you have the <sys/file.h> header file. */
+#undef HAVE_SYS_FILE_H
+
+/* Define to 1 if you have the <sys/loadavg.h> header file. */
+#undef HAVE_SYS_LOADAVG_H
+
+/* Define to 1 if you have the <sys/lock.h> header file. */
+#undef HAVE_SYS_LOCK_H
+
+/* Define to 1 if you have the <sys/mkdev.h> header file. */
+#undef HAVE_SYS_MKDEV_H
+
+/* Define to 1 if you have the <sys/modem.h> header file. */
+#undef HAVE_SYS_MODEM_H
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines 'DIR'.
+ */
+#undef HAVE_SYS_NDIR_H
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/poll.h> header file. */
+#define HAVE_SYS_POLL_H 1
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#define HAVE_SYS_RESOURCE_H 1
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#define HAVE_SYS_SELECT_H 1
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
+
+/* Define to 1 if you have the <sys/statvfs.h> header file. */
+#undef HAVE_SYS_STATVFS_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/termio.h> header file. */
+#undef HAVE_SYS_TERMIO_H
+
+/* Define to 1 if you have the <sys/times.h> header file. */
+#undef HAVE_SYS_TIMES_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/un.h> header file. */
+#undef HAVE_SYS_UN_H
+
+/* Define to 1 if you have the <sys/utsname.h> header file. */
+#undef HAVE_SYS_UTSNAME_H
+
+/* Define to 1 if you have the <sys/wait.h> header file. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define to 1 if you have the system() command. */
+#define HAVE_SYSTEM 1
+
+/* Define to 1 if you have the 'tcgetpgrp' function. */
+#undef HAVE_TCGETPGRP
+
+/* Define to 1 if you have the 'tcsetpgrp' function. */
+#undef HAVE_TCSETPGRP
+
+/* Define to 1 if you have the 'tempnam' function. */
+#define HAVE_TEMPNAM 1
+
+/* Define to 1 if you have the <termios.h> header file. */
+#undef HAVE_TERMIOS_H
+
+/* Define to 1 if you have the <term.h> header file. */
+#undef HAVE_TERM_H
+
+/* Define to 1 if you have the 'tgamma' function. */
+#undef HAVE_TGAMMA
+
+/* Define to 1 if you have the <thread.h> header file. */
+#undef HAVE_THREAD_H
+
+/* Define to 1 if you have the 'timegm' function. */
+#undef HAVE_TIMEGM
+
+/* Define to 1 if you have the 'times' function. */
+#undef HAVE_TIMES
+
+/* Define to 1 if you have the 'tmpfile' function. */
+#define HAVE_TMPFILE 1
+
+/* Define to 1 if you have the 'tmpnam' function. */
+#define HAVE_TMPNAM 1
+
+/* Define to 1 if you have the 'tmpnam_r' function. */
+#undef HAVE_TMPNAM_R
+
+/* Define to 1 if your 'struct tm' has 'tm_zone'. Deprecated, use
+ 'HAVE_STRUCT_TM_TM_ZONE' instead. */
+#undef HAVE_TM_ZONE
+
+/* Define to 1 if you have the 'truncate' function. */
+#undef HAVE_TRUNCATE
+
+/* Define to 1 if you don't have 'tm_zone' but do have the external array
+ 'tzname'. */
+#undef HAVE_TZNAME
+
+/* Define this if you have tcl and TCL_UTF_MAX==6 */
+#undef HAVE_UCS4_TCL
+
+/* Define to 1 if the system has the type 'uintptr_t'. */
+#define HAVE_UINTPTR_T 1
+
+/* Define to 1 if you have the 'uname' function. */
+#undef HAVE_UNAME
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the 'unsetenv' function. */
+#undef HAVE_UNSETENV
+
+/* Define if you have a useable wchar_t type defined in wchar.h; useable means
+ wchar_t must be an unsigned type with at least 16 bits. (see
+ Include/unicodeobject.h). */
+#define HAVE_USABLE_WCHAR_T 1
+
+/* Define to 1 if you have the <util.h> header file. */
+#undef HAVE_UTIL_H
+
+/* Define to 1 if you have the 'utimes' function. */
+#undef HAVE_UTIMES
+
+/* Define to 1 if you have the <utime.h> header file. */
+#define HAVE_UTIME_H 1
+
+/* Define to 1 if you have the 'wait3' function. */
+#undef HAVE_WAIT3
+
+/* Define to 1 if you have the 'wait4' function. */
+#undef HAVE_WAIT4
+
+/* Define to 1 if you have the 'waitpid' function. */
+#undef HAVE_WAITPID
+
+/* Define if the compiler provides a wchar.h header file. */
+#define HAVE_WCHAR_H 1
+
+/* Define to 1 if you have the 'wcscoll' function. */
+#define HAVE_WCSCOLL 1
+
+/* Define if tzset() actually switches the local timezone in a meaningful way.
+ */
+#undef HAVE_WORKING_TZSET
+
+/* Define if the zlib library has inflateCopy */
+#undef HAVE_ZLIB_COPY
+
+/* Define to 1 if you have the '_getpty' function. */
+#undef HAVE__GETPTY
+
+/* Define if you are using Mach cthreads directly under /include */
+#undef HURD_C_THREADS
+
+/* Define if you are using Mach cthreads under mach / */
+#undef MACH_C_THREADS
+
+/* Define to 1 if 'major', 'minor', and 'makedev' are declared in <mkdev.h>.
+ */
+#undef MAJOR_IN_MKDEV
+
+/* Define to 1 if 'major', 'minor', and 'makedev' are declared in
+ <sysmacros.h>. */
+#undef MAJOR_IN_SYSMACROS
+
+/* Define if mvwdelch in curses.h is an expression. */
+#undef MVWDELCH_IS_EXPRESSION
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "edk2-devel@lists.sourceforge.net"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "EDK II Python Package"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "EDK II Python Package V0.8"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "EADK_Python"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL "http://edk2.tianocore.org/toolkit/python"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "V0.8"
+
+/* Define if POSIX semaphores aren't enabled on your system */
+#define POSIX_SEMAPHORES_NOT_ENABLED 1
+
+/* Defined if PTHREAD_SCOPE_SYSTEM supported. */
+#undef PTHREAD_SYSTEM_SCHED_SUPPORTED
+
+/* Define as the preferred size in bits of long digits */
+#undef PYLONG_BITS_IN_DIGIT
+
+/* Define to printf format modifier for long long type */
+#define PY_FORMAT_LONG_LONG "ll"
+
+/* Define to printf format modifier for Py_ssize_t */
+#define PY_FORMAT_SIZE_T "z"
+
+/* Define as the integral type used for Unicode representation. */
+#define PY_UNICODE_TYPE wchar_t
+
+/* Define if you want to build an interpreter with many run-time checks. */
+#undef Py_DEBUG
+
+/* Defined if Python is built as a shared library. */
+#undef Py_ENABLE_SHARED
+
+/* Define as the size of the unicode type. */
+#define Py_UNICODE_SIZE 2
+
+/* Define if you want to have a Unicode type. */
+#define Py_USING_UNICODE
+
+/* assume C89 semantics that RETSIGTYPE is always void */
+#undef RETSIGTYPE
+
+/* Define if setpgrp() must be called as setpgrp(0, 0). */
+#undef SETPGRP_HAVE_ARG
+
+/* Define this to be extension of shared libraries (including the dot!). */
+#undef SHLIB_EXT
+
+/* Define if i>>j for signed int i does not extend the sign bit when i < 0 */
+#undef SIGNED_RIGHT_SHIFT_ZERO_FILLS
+
+/* The size of 'double', as computed by sizeof. */
+#define SIZEOF_DOUBLE 8
+
+/* The size of 'float', as computed by sizeof. */
+#define SIZEOF_FLOAT 4
+
+/* The size of 'fpos_t', as computed by sizeof. */
+#define SIZEOF_FPOS_T 8
+
+/* The size of 'int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* The size of 'long', as computed by sizeof. */
+#define SIZEOF_LONG 4
+
+/* The size of 'long double', as computed by sizeof. */
+#undef SIZEOF_LONG_DOUBLE
+
+/* The size of 'long long', as computed by sizeof. */
+#define SIZEOF_LONG_LONG 8
+
+/* The size of 'off_t', as computed by sizeof. */
+#define SIZEOF_OFF_T 4
+
+/* The size of 'pid_t', as computed by sizeof. */
+#define SIZEOF_PID_T 4
+
+/* The size of 'pthread_t', as computed by sizeof. */
+#undef SIZEOF_PTHREAD_T
+
+/* The size of 'short', as computed by sizeof. */
+#define SIZEOF_SHORT 2
+
+/* The size of 'size_t', as computed by sizeof. */
+#define SIZEOF_SIZE_T 4
+
+/* The size of 'time_t', as computed by sizeof. */
+#define SIZEOF_TIME_T 4
+
+/* The size of 'uintptr_t', as computed by sizeof. */
+#define SIZEOF_UINTPTR_T 4
+
+/* The size of 'void *', as computed by sizeof. */
+#define SIZEOF_VOID_P 4
+
+/* The size of 'wchar_t', as computed by sizeof. */
+#define SIZEOF_WCHAR_T 2
+
+/* The size of '_Bool', as computed by sizeof. */
+#define SIZEOF__BOOL 1
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define if you can safely include both <sys/select.h> and <sys/time.h>
+ (which you can't on SCO ODT 3.0). */
+#undef SYS_SELECT_WITH_SYS_TIME
+
+/* Define if tanh(-0.) is -0., or if platform doesn't have signed zeros */
+#undef TANH_PRESERVES_ZERO_SIGN
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Define to 1 if your <sys/time.h> declares 'struct tm'. */
+#undef TM_IN_SYS_TIME
+
+/* Enable extensions on AIX 3, Interix. */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif
+/* Enable threading extensions on Solaris. */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# undef _POSIX_PTHREAD_SEMANTICS
+#endif
+/* Enable extensions on HP NonStop. */
+#ifndef _TANDEM_SOURCE
+# undef _TANDEM_SOURCE
+#endif
+/* Enable general extensions on Solaris. */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+
+
+/* Define if you want to use MacPython modules on MacOSX in unix-Python. */
+#undef USE_TOOLBOX_OBJECT_GLUE
+
+/* Define if a va_list is an array of some kind */
+#undef VA_LIST_IS_ARRAY
+
+/* Define if you want SIGFPE handled (see Include/pyfpe.h). */
+#undef WANT_SIGFPE_HANDLER
+
+/* Define if you want wctype.h functions to be used instead of the one
+ supplied by Python itself. (see Include/unicodectype.h). */
+#define WANT_WCTYPE_FUNCTIONS 1
+
+/* Define if WINDOW in curses.h offers a field _flags. */
+#undef WINDOW_HAS_FLAGS
+
+/* Define if you want documentation strings in extension modules */
+#undef WITH_DOC_STRINGS
+
+/* Define if you want to use the new-style (Openstep, Rhapsody, MacOS) dynamic
+ linker (dyld) instead of the old-style (NextStep) dynamic linker (rld).
+ Dyld is necessary to support frameworks. */
+#undef WITH_DYLD
+
+/* Define to 1 if libintl is needed for locale functions. */
+#undef WITH_LIBINTL
+
+/* Define if you want to produce an OpenStep/Rhapsody framework (shared
+ library plus accessory files). */
+#undef WITH_NEXT_FRAMEWORK
+
+/* Define if you want to compile in Python-specific mallocs */
+#undef WITH_PYMALLOC
+
+/* Define if you want to compile in rudimentary thread support */
+#undef WITH_THREAD
+
+/* Define to profile with the Pentium timestamp counter */
+#undef WITH_TSC
+
+/* Define if you want pymalloc to be disabled when running under valgrind */
+#undef WITH_VALGRIND
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+# undef WORDS_BIGENDIAN
+# endif
+#endif
+
+/* Define if arithmetic is subject to x87-style double rounding issue */
+#undef X87_DOUBLE_ROUNDING
+
+/* Define on OpenBSD to activate all library features */
+#undef _BSD_SOURCE
+
+/* Define on Irix to enable u_int */
+#undef _BSD_TYPES
+
+/* Define on Darwin to activate all library features */
+#undef _DARWIN_C_SOURCE
+
+/* This must be set to 64 on some systems to enable large file support. */
+#undef _FILE_OFFSET_BITS
+
+/* Define on Linux to activate all library features */
+#undef _GNU_SOURCE
+
+/* This must be defined on some systems to enable large file support. */
+#undef _LARGEFILE_SOURCE
+
+/* Define to 1 if on MINIX. */
+#undef _MINIX
+
+/* Define on NetBSD to activate all library features */
+#ifndef _NETBSD_SOURCE
+ #define _NETBSD_SOURCE 1
+#endif
+
+/* Define _OSF_SOURCE to get the makedev macro. */
+#undef _OSF_SOURCE
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+ this defined. */
+#undef _POSIX_1_SOURCE
+
+/* Define to activate features from IEEE Stds 1003.1-2001 */
+#undef _POSIX_C_SOURCE
+
+/* Define to 1 if you need to in order for 'stat' and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Define if you have POSIX threads, and your system does not define that. */
+#undef _POSIX_THREADS
+
+/* Define to force use of thread-safe errno, h_errno, and other functions */
+#undef _REENTRANT
+
+/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
+ #define below would cause a syntax error. */
+#undef _UINT32_T
+
+/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
+ #define below would cause a syntax error. */
+#undef _UINT64_T
+
+/* Define to the level of X/Open that your system supports */
+#undef _XOPEN_SOURCE
+
+/* Define to activate Unix95-and-earlier features */
+#undef _XOPEN_SOURCE_EXTENDED
+
+/* Define on FreeBSD to activate all library features */
+#undef __BSD_VISIBLE
+
+/* Define to 1 if type 'char' is unsigned and you are not using gcc. */
+#ifndef __CHAR_UNSIGNED__
+# undef __CHAR_UNSIGNED__
+#endif
+
+/* Defined on Solaris to see additional function prototypes. */
+#undef __EXTENSIONS__
+
+/* Define to 'long' if <time.h> doesn't define. */
+//#undef clock_t
+
+/* Define to empty if 'const' does not conform to ANSI C. */
+//#undef const
+
+/* Define to 'int' if <sys/types.h> doesn't define. */
+//#undef gid_t
+
+/* Define to the type of a signed integer type of width exactly 32 bits if
+ such a type exists and the standard includes do not define it. */
+//#undef int32_t
+
+/* Define to the type of a signed integer type of width exactly 64 bits if
+ such a type exists and the standard includes do not define it. */
+//#undef int64_t
+
+/* Define to 'int' if <sys/types.h> does not define. */
+//#undef mode_t
+
+/* Define to 'long int' if <sys/types.h> does not define. */
+//#undef off_t
+
+/* Define to 'int' if <sys/types.h> does not define. */
+//#undef pid_t
+
+/* Define to empty if the keyword does not work. */
+//#undef signed
+
+/* Define to 'unsigned int' if <sys/types.h> does not define. */
+//#undef size_t
+
+/* Define to 'int' if <sys/socket.h> does not define. */
+//#undef socklen_t
+
+/* Define to 'int' if <sys/types.h> doesn't define. */
+//#undef uid_t
+
+/* Define to the type of an unsigned integer type of width exactly 32 bits if
+ such a type exists and the standard includes do not define it. */
+//#undef uint32_t
+
+/* Define to the type of an unsigned integer type of width exactly 64 bits if
+ such a type exists and the standard includes do not define it. */
+//#undef uint64_t
+
+/* Define to empty if the keyword does not work. */
+//#undef volatile
+
+#endif /*Py_PYCONFIG_H*/
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Py2710ReadMe.txt b/AppPkg/Applications/Python/Python-2.7.10/Py2710ReadMe.txt new file mode 100644 index 0000000000..7d8b31f74b --- /dev/null +++ b/AppPkg/Applications/Python/Python-2.7.10/Py2710ReadMe.txt @@ -0,0 +1,198 @@ + EDK II Python
+ ReadMe
+ Release 1.02
+ 18 Jan. 2013
+
+
+1. OVERVIEW
+===========
+This document is devoted to general information on building and setup of the
+Python environment for UEFI 2.3, the invocation of the interpreter, and things
+that make working with Python easier.
+
+It is assumed that you already have either UDK2010 or a current snapshot of
+the EDK II sources from www.tianocore.org, and that you can successfully build
+packages within that distribution.
+
+2. Release Notes
+================
+ 1) All C extension modules must be statically linked (built in)
+ 2) The site and os modules must exist as discrete files in ...\lib\python.27
+ 3) User-specific configurations are not supported.
+ 4) Environment variables are not supported.
+
+3. Getting and Building Python
+======================================================
+ 3.1 Getting Python
+ ==================
+ Currently only version 2.7.2 of the CPython distribution is supported. For development
+ ease, a subset of the Python 2.7.2 distribution has been included in the AppPkg source
+ tree. If a full distribution is desired, the Python-2.7.2 directory can be removed or
+ renamed and the full source code downloaded from http://www.python.org/ftp/python/2.7.2/.
+
+ A. Within your EDK II development tree, extract the Python distribution into
+ AppPkg/Applications/Python. This should create the
+ AppPkg/Applications/Python/Python-2.7.2 directory.
+
+ B. Copy the files from PyMod-2.7.2 into the corresponding directories within
+ the Python-2.7.2 tree. This will overwrite existing files with files
+ modified for UEFI usage.
+
+ 3.2 Building Python
+ ===================
+ A. Edit Efi/config.c to enable the built-in modules you need.
+ Mandatory Built-in Modules:
+ edk2 errno imp marshal
+
+ Additional built-in modules which are required to use the help()
+ functionality provided by PyDoc, are:
+ _codecs _collections _functools _random
+ _sre _struct _weakref binascii
+ cStringIO gc itertools math
+ operator time
+
+ B. Edit AppPkg/AppPkg.dsc to enable (uncomment) the PythonCore.inf line
+ within the [Components] section.
+
+ C. Build AppPkg, which includes Python, using the standard "build" command:
+ For example, to build Python for an X64 CPU architecture:
+ build -a X64 -p AppPkg\AppPkg.dsc
+
+4. Python-related paths and files
+=================================
+Python depends upon the existence of several directories and files on the
+target system.
+
+ \EFI Root of the UEFI system area.
+ |- \Tools Location of the Python.efi executable.
+ |- \Boot UEFI specified Boot directory.
+ |- \StdLib Root of the Standard Libraries sub-tree.
+ |- \etc Configuration files used by libraries.
+ |- \tmp Temporary files created by tmpfile(), etc.
+ |- \lib Root of the libraries tree.
+ |- \python.27 Directory containing the Python library modules.
+ |- \lib-dynload Dynamically loadable Python extensions.
+ |- \site-packages Site-specific packages and modules.
+
+
+5. Installing Python
+====================
+These directories, on the target system, are populated from the development
+system as follows:
+
+ * \Efi\Tools receives a copy of Build/AppPkg/DEBUG_VS2005/X64/Python.efi.
+ ^^^^^ ^^^^^^
+ Modify the host path to match the your build type and compiler.
+
+ * The \Efi\StdLib\etc directory is populated from the StdLib/Efi/StdLib/etc
+ source directory.
+
+ * Directory \Efi\StdLib\lib\python.27 is populated with packages and modules
+ from the AppPkg/Applications/Python/Python-2.7.2/Lib directory.
+ The recommended minimum set of modules (.py, .pyc, and/or .pyo):
+ os stat ntpath warnings traceback
+ site types copy_reg linecache genericpath
+
+ * Python C Extension Modules built as dynamically loadable extensions go into
+ the \Efi\StdLib\lib\python.27\lib-dynload directory. This functionality is not
+ yet implemented.
+
+
+6. Example: Enabling socket support
+===================================
+ 1. enable {"_socket", init_socket}, in Efi\config.c
+ 2. enable Python-2.7.2/Modules/socketmodule.c in PythonCore.inf.
+ 3. copy socket.py over to /Efi/StdLib/lib/python.27 on your target system.
+ 4. Make sure dependent modules are present(.py) or built in(.c):
+ functools, types, os, sys, warnings, cStringIO, StringIO, errno
+
+ 5. build -a X64 -p AppPkg\AppPkg.dsc
+ 6. copy Build\AppPkg\DEBUG_VS2005\X64\Python.efi to \Efi\Tools on your target system.
+ ^^^^ Modify as needed
+
+
+7. Supported C Modules
+======================
+ Module Name C File(s)
+ =============== =============================================
+ _ast Python/Python-ast.c
+ _bisect Modules/_bisectmodule.c
+ _codecs Modules/_codecsmodule.c
+ _codecs_cn Modules/cjkcodecs/_codecs_cn.c
+ _codecs_hk Modules/cjkcodecs/_codecs_hk.c
+ _codecs_iso2022 Modules/cjkcodecs/_codecs_iso2022.c
+ _codecs_jp Modules/cjkcodecs/_codecs_jp
+ _codecs_kr Modules/cjkcodecs/_codecs_kr
+ _codecs_tw Modules/cjkcodecs/_codecs_tw
+ _collections Modules/_collectionsmodule.c
+ _csv Modules/_csv.c
+ _functools Modules/_functoolsmodule.c
+ _heapq Modules/_heapqmodule.c
+ _io Modules/_io/_iomodule.c Modules/_io/*
+ _json Modules/_json.c
+ _md5 Modules/md5module.c Modules/md5.c
+ _multibytecodec Modules/cjkcodecs/_multibytecodec.c
+ _random Modules/_randommodule.c
+ _sha Modules/shamodule.c
+ _sha256 Modules/sha256module.c
+ _sha512 Modules/sha512module.c
+ _socket Modules/socketmodule.c
+ _sre Modules/_sre.c
+ _struct Modules/_struct.c
+ _symtable Modules/symtablemodule.c
+ _weakref Modules/_weakref.c
+ array Modules/arraymodule.c
+ binascii Modules/binascii.c
+ cmath Modules/cmathmodule.c
+ cPickle Modules/cPickle.c
+ cStringIO Modules/cStringIO.c
+ datetime Modules/datetimemodule.c
+ edk2 Modules/Efi/edk2module.c
+ errno Modules/errnomodule.c
+ future_builtins Modules/future_builtins.c
+ gc Modules/gcmodule.c
+ imp Python/import.c
+ itertools Modules/itertoolsmodule.c
+ marshal Python/marshal.c
+ math Modules/mathmodule.c Modules/_math.c
+ operator Modules/operator.c
+ parser Modules/parsermodule.c
+ select Modules/selectmodule.c
+ signal Modules/signalmodule.c
+ strop Modules/stropmodule.c
+ time Modules/timemodule.c
+ xxsubtype Modules/xxsubtype.c
+ zipimport Modules/zipimport.c
+ zlib Modules/zlibmodule.c Modules/zlib/*
+
+
+8. Tested Python Library Modules
+================================
+This is a partial list of the packages and modules of the Python Standard
+Library that have been tested or used in some manner.
+
+ encodings genericpath.py sha.py
+ importlib getopt.py SimpleHTTPServer.py
+ json hashlib.py site.py
+ pydoc_data heapq.py socket.py
+ xml HTMLParser.py SocketServer.py
+ abc.py inspect.py sre.py
+ argparse.py io.py sre_compile.py
+ ast.py keyword.py sre_constants.py
+ atexit.py linecache.py sre_parse.py
+ BaseHTTPServer.py locale.py stat.py
+ binhex.py md5.py string.py
+ bisect.py modulefinder.py StringIO.py
+ calendar.py ntpath.py struct.py
+ cmd.py numbers.py textwrap.py
+ codecs.py optparse.py token.py
+ collections.py os.py tokenize.py
+ copy.py platform.py traceback.py
+ copy_reg.py posixpath.py types.py
+ csv.py pydoc.py warnings.py
+ dummy_thread.py random.py weakref.py
+ fileinput.py re.py xmllib.py
+ formatter.py repr.py zipfile.py
+ functools.py runpy.py expat
+
+# # #
diff --git a/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Include/fileobject.h b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Include/fileobject.h new file mode 100644 index 0000000000..5007848cf7 --- /dev/null +++ b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Include/fileobject.h @@ -0,0 +1,108 @@ +/** @file
+ File object interface
+
+ Copyright (c) 2015, Daryl McDaniel. All rights reserved.<BR>
+ Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+#ifndef Py_FILEOBJECT_H
+#define Py_FILEOBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ PyObject_HEAD
+ FILE *f_fp;
+ PyObject *f_name;
+ PyObject *f_mode;
+ int (*f_close)(FILE *);
+ int f_softspace; /* Flag used by 'print' command */
+ int f_binary; /* Flag which indicates whether the file is
+ open in binary (1) or text (0) mode */
+ char* f_buf; /* Allocated readahead buffer */
+ char* f_bufend; /* Points after last occupied position */
+ char* f_bufptr; /* Current buffer position */
+ char *f_setbuf; /* Buffer for setbuf(3) and setvbuf(3) */
+ int f_univ_newline; /* Handle any newline convention */
+ int f_newlinetypes; /* Types of newlines seen */
+ int f_skipnextlf; /* Skip next \n */
+ PyObject *f_encoding;
+ PyObject *f_errors;
+ PyObject *weakreflist; /* List of weak references */
+ int unlocked_count; /* Num. currently running sections of code
+ using f_fp with the GIL released. */
+ int readable;
+ int writable;
+} PyFileObject;
+
+PyAPI_DATA(PyTypeObject) PyFile_Type;
+
+#define PyFile_Check(op) PyObject_TypeCheck(op, &PyFile_Type)
+#define PyFile_CheckExact(op) (Py_TYPE(op) == &PyFile_Type)
+
+PyAPI_FUNC(PyObject *) PyFile_FromString(char *, char *);
+PyAPI_FUNC(void) PyFile_SetBufSize(PyObject *, int);
+PyAPI_FUNC(int) PyFile_SetEncoding(PyObject *, const char *);
+PyAPI_FUNC(int) PyFile_SetEncodingAndErrors(PyObject *, const char *, char *errors);
+PyAPI_FUNC(PyObject *) PyFile_FromFile(FILE *, char *, char *,
+ int (*)(FILE *));
+PyAPI_FUNC(FILE *) PyFile_AsFile(PyObject *);
+PyAPI_FUNC(void) PyFile_IncUseCount(PyFileObject *);
+PyAPI_FUNC(void) PyFile_DecUseCount(PyFileObject *);
+PyAPI_FUNC(PyObject *) PyFile_Name(PyObject *);
+PyAPI_FUNC(PyObject *) PyFile_GetLine(PyObject *, int);
+PyAPI_FUNC(int) PyFile_WriteObject(PyObject *, PyObject *, int);
+PyAPI_FUNC(int) PyFile_SoftSpace(PyObject *, int);
+PyAPI_FUNC(int) PyFile_WriteString(const char *, PyObject *);
+PyAPI_FUNC(int) PyObject_AsFileDescriptor(PyObject *);
+
+/* The default encoding used by the platform file system APIs
+ If non-NULL, this is different than the default encoding for strings
+*/
+PyAPI_DATA(const char *) Py_FileSystemDefaultEncoding;
+
+/* Routines to replace fread() and fgets() which accept any of \r, \n
+ or \r\n as line terminators.
+*/
+#define PY_STDIOTEXTMODE "b"
+char *Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *);
+size_t Py_UniversalNewlineFread(char *, size_t, FILE *, PyObject *);
+
+/* A routine to do sanity checking on the file mode string. returns
+ non-zero on if an exception occurred
+*/
+int _PyFile_SanitizeMode(char *mode);
+
+//#if defined _MSC_VER && _MSC_VER >= 1400
+/* A routine to check if a file descriptor is valid on Windows. Returns 0
+ * and sets errno to EBADF if it isn't. This is to avoid Assertions
+ * from various functions in the Windows CRT beginning with
+ * Visual Studio 2005
+ */
+//int _PyVerify_fd(int fd);
+//#elif defined _MSC_VER && _MSC_VER >= 1200
+/* fdopen doesn't set errno EBADF and crashes for large fd on debug build */
+//#define _PyVerify_fd(fd) (_get_osfhandle(fd) >= 0)
+//#else
+#define _PyVerify_fd(A) (1) /* dummy */
+//#endif
+
+/* A routine to check if a file descriptor can be select()-ed. */
+#ifdef HAVE_SELECT
+ #define _PyIsSelectable_fd(FD) (((FD) >= 0) && ((FD) < FD_SETSIZE))
+#else
+ #define _PyIsSelectable_fd(FD) (1)
+#endif /* HAVE_SELECT */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_FILEOBJECT_H */
diff --git a/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Include/osdefs.h b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Include/osdefs.h new file mode 100644 index 0000000000..e01bd4903f --- /dev/null +++ b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Include/osdefs.h @@ -0,0 +1,81 @@ +/** @file
+ Operating system dependencies.
+
+ Copyright (c) 2015, Daryl McDaniel. All rights reserved.<BR>
+ Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+#ifndef Py_OSDEFS_H
+#define Py_OSDEFS_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Mod by chrish: QNX has WATCOM, but isn't DOS */
+#if !defined(__QNX__) && !defined(UEFI_C_SOURCE)
+#if defined(MS_WINDOWS) || defined(__BORLANDC__) || defined(__WATCOMC__) || defined(__DJGPP__) || defined(PYOS_OS2)
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+#define MAXPATHLEN 260
+#define SEP '/'
+#define ALTSEP '\\'
+#else
+#define SEP '\\'
+#define ALTSEP '/'
+#define MAXPATHLEN 256
+#endif
+#define DELIM ';'
+#endif
+#endif
+
+#ifdef RISCOS
+#define SEP '.'
+#define MAXPATHLEN 256
+#define DELIM ','
+#endif
+
+
+/* Filename separator */
+#ifndef SEP
+#define SEP '/'
+#define ALTSEP '\\'
+#endif
+
+/* Max pathname length */
+#ifdef __hpux
+# include <sys/param.h>
+# include <limits.h>
+# ifndef PATH_MAX
+# define PATH_MAX MAXPATHLEN
+# endif
+#endif
+
+#ifndef MAXPATHLEN
+#if defined(PATH_MAX) && PATH_MAX > 1024
+#define MAXPATHLEN PATH_MAX
+#else
+#define MAXPATHLEN 1024
+#endif
+#endif
+
+/* Search path entry delimiter */
+#ifndef DELIM
+# ifdef UEFI_C_SOURCE
+# define DELIM ';'
+# define DELIM_STR ";"
+# else
+# define DELIM ':'
+# endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_OSDEFS_H */
diff --git a/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Include/pyport.h b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Include/pyport.h new file mode 100644 index 0000000000..2858cdb1e1 --- /dev/null +++ b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Include/pyport.h @@ -0,0 +1,957 @@ +/** @file
+ Symbols and macros to supply platform-independent interfaces to basic
+ C language & library operations whose spellings vary across platforms.
+
+ Copyright (c) 2015, Daryl McDaniel. All rights reserved.<BR>
+ Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+#ifndef Py_PYPORT_H
+#define Py_PYPORT_H
+
+#include "pyconfig.h" /* include for defines */
+
+/* Some versions of HP-UX & Solaris need inttypes.h for int32_t,
+ INT32_MAX, etc. */
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+/**************************************************************************
+Symbols and macros to supply platform-independent interfaces to basic
+C language & library operations whose spellings vary across platforms.
+
+Please try to make documentation here as clear as possible: by definition,
+the stuff here is trying to illuminate C's darkest corners.
+
+Config #defines referenced here:
+
+SIGNED_RIGHT_SHIFT_ZERO_FILLS
+Meaning: To be defined iff i>>j does not extend the sign bit when i is a
+ signed integral type and i < 0.
+Used in: Py_ARITHMETIC_RIGHT_SHIFT
+
+Py_DEBUG
+Meaning: Extra checks compiled in for debug mode.
+Used in: Py_SAFE_DOWNCAST
+
+HAVE_UINTPTR_T
+Meaning: The C9X type uintptr_t is supported by the compiler
+Used in: Py_uintptr_t
+
+HAVE_LONG_LONG
+Meaning: The compiler supports the C type "long long"
+Used in: PY_LONG_LONG
+
+**************************************************************************/
+
+
+/* For backward compatibility only. Obsolete, do not use. */
+#ifdef HAVE_PROTOTYPES
+#define Py_PROTO(x) x
+#else
+#define Py_PROTO(x) ()
+#endif
+#ifndef Py_FPROTO
+#define Py_FPROTO(x) Py_PROTO(x)
+#endif
+
+/* typedefs for some C9X-defined synonyms for integral types.
+ *
+ * The names in Python are exactly the same as the C9X names, except with a
+ * Py_ prefix. Until C9X is universally implemented, this is the only way
+ * to ensure that Python gets reliable names that don't conflict with names
+ * in non-Python code that are playing their own tricks to define the C9X
+ * names.
+ *
+ * NOTE: don't go nuts here! Python has no use for *most* of the C9X
+ * integral synonyms. Only define the ones we actually need.
+ */
+
+#ifdef HAVE_LONG_LONG
+#ifndef PY_LONG_LONG
+#define PY_LONG_LONG long long
+#if defined(LLONG_MAX)
+/* If LLONG_MAX is defined in limits.h, use that. */
+#define PY_LLONG_MIN LLONG_MIN
+#define PY_LLONG_MAX LLONG_MAX
+#define PY_ULLONG_MAX ULLONG_MAX
+#elif defined(__LONG_LONG_MAX__)
+/* Otherwise, if GCC has a builtin define, use that. */
+#define PY_LLONG_MAX __LONG_LONG_MAX__
+#define PY_LLONG_MIN (-PY_LLONG_MAX-1)
+#define PY_ULLONG_MAX (__LONG_LONG_MAX__*2ULL + 1ULL)
+#else
+/* Otherwise, rely on two's complement. */
+#define PY_ULLONG_MAX (~0ULL)
+#define PY_LLONG_MAX ((long long)(PY_ULLONG_MAX>>1))
+#define PY_LLONG_MIN (-PY_LLONG_MAX-1)
+#endif /* LLONG_MAX */
+#endif
+#endif /* HAVE_LONG_LONG */
+
+/* a build with 30-bit digits for Python long integers needs an exact-width
+ * 32-bit unsigned integer type to store those digits. (We could just use
+ * type 'unsigned long', but that would be wasteful on a system where longs
+ * are 64-bits.) On Unix systems, the autoconf macro AC_TYPE_UINT32_T defines
+ * uint32_t to be such a type unless stdint.h or inttypes.h defines uint32_t.
+ * However, it doesn't set HAVE_UINT32_T, so we do that here.
+ */
+#ifdef uint32_t
+#define HAVE_UINT32_T 1
+#endif
+
+#ifdef HAVE_UINT32_T
+#ifndef PY_UINT32_T
+#define PY_UINT32_T uint32_t
+#endif
+#endif
+
+/* Macros for a 64-bit unsigned integer type; used for type 'twodigits' in the
+ * long integer implementation, when 30-bit digits are enabled.
+ */
+#ifdef uint64_t
+#define HAVE_UINT64_T 1
+#endif
+
+#ifdef HAVE_UINT64_T
+#ifndef PY_UINT64_T
+#define PY_UINT64_T uint64_t
+#endif
+#endif
+
+/* Signed variants of the above */
+#ifdef int32_t
+#define HAVE_INT32_T 1
+#endif
+
+#ifdef HAVE_INT32_T
+#ifndef PY_INT32_T
+#define PY_INT32_T int32_t
+#endif
+#endif
+
+#ifdef int64_t
+#define HAVE_INT64_T 1
+#endif
+
+#ifdef HAVE_INT64_T
+#ifndef PY_INT64_T
+#define PY_INT64_T int64_t
+#endif
+#endif
+
+/* If PYLONG_BITS_IN_DIGIT is not defined then we'll use 30-bit digits if all
+ the necessary integer types are available, and we're on a 64-bit platform
+ (as determined by SIZEOF_VOID_P); otherwise we use 15-bit digits. */
+
+#ifndef PYLONG_BITS_IN_DIGIT
+#if (defined HAVE_UINT64_T && defined HAVE_INT64_T && \
+ defined HAVE_UINT32_T && defined HAVE_INT32_T && SIZEOF_VOID_P >= 8)
+#define PYLONG_BITS_IN_DIGIT 30
+#else
+#define PYLONG_BITS_IN_DIGIT 15
+#endif
+#endif
+
+/* uintptr_t is the C9X name for an unsigned integral type such that a
+ * legitimate void* can be cast to uintptr_t and then back to void* again
+ * without loss of information. Similarly for intptr_t, wrt a signed
+ * integral type.
+ */
+#ifdef HAVE_UINTPTR_T
+typedef uintptr_t Py_uintptr_t;
+typedef intptr_t Py_intptr_t;
+
+#elif SIZEOF_VOID_P <= SIZEOF_INT
+typedef unsigned int Py_uintptr_t;
+typedef int Py_intptr_t;
+
+#elif SIZEOF_VOID_P <= SIZEOF_LONG
+typedef unsigned long Py_uintptr_t;
+typedef long Py_intptr_t;
+
+#elif defined(HAVE_LONG_LONG) && (SIZEOF_VOID_P <= SIZEOF_LONG_LONG)
+typedef unsigned PY_LONG_LONG Py_uintptr_t;
+typedef PY_LONG_LONG Py_intptr_t;
+
+#else
+# error "Python needs a typedef for Py_uintptr_t in pyport.h."
+#endif /* HAVE_UINTPTR_T */
+
+/* Py_ssize_t is a signed integral type such that sizeof(Py_ssize_t) ==
+ * sizeof(size_t). C99 doesn't define such a thing directly (size_t is an
+ * unsigned integral type). See PEP 353 for details.
+ */
+#ifdef HAVE_SSIZE_T
+typedef ssize_t Py_ssize_t;
+#elif SIZEOF_VOID_P == SIZEOF_SIZE_T
+typedef Py_intptr_t Py_ssize_t;
+#else
+# error "Python needs a typedef for Py_ssize_t in pyport.h."
+#endif
+
+/* Largest possible value of size_t.
+ SIZE_MAX is part of C99, so it might be defined on some
+ platforms. If it is not defined, (size_t)-1 is a portable
+ definition for C89, due to the way signed->unsigned
+ conversion is defined. */
+#ifdef SIZE_MAX
+#define PY_SIZE_MAX SIZE_MAX
+#else
+#define PY_SIZE_MAX ((size_t)-1)
+#endif
+
+/* Largest positive value of type Py_ssize_t. */
+#define PY_SSIZE_T_MAX ((Py_ssize_t)(((size_t)-1)>>1))
+/* Smallest negative value of type Py_ssize_t. */
+#define PY_SSIZE_T_MIN (-PY_SSIZE_T_MAX-1)
+
+#if SIZEOF_PID_T > SIZEOF_LONG
+# error "Python doesn't support sizeof(pid_t) > sizeof(long)"
+#endif
+
+/* PY_FORMAT_SIZE_T is a platform-specific modifier for use in a printf
+ * format to convert an argument with the width of a size_t or Py_ssize_t.
+ * C99 introduced "z" for this purpose, but not all platforms support that;
+ * e.g., MS compilers use "I" instead.
+ *
+ * These "high level" Python format functions interpret "z" correctly on
+ * all platforms (Python interprets the format string itself, and does whatever
+ * the platform C requires to convert a size_t/Py_ssize_t argument):
+ *
+ * PyString_FromFormat
+ * PyErr_Format
+ * PyString_FromFormatV
+ *
+ * Lower-level uses require that you interpolate the correct format modifier
+ * yourself (e.g., calling printf, fprintf, sprintf, PyOS_snprintf); for
+ * example,
+ *
+ * Py_ssize_t index;
+ * fprintf(stderr, "index %" PY_FORMAT_SIZE_T "d sucks\n", index);
+ *
+ * That will expand to %ld, or %Id, or to something else correct for a
+ * Py_ssize_t on the platform.
+ */
+#ifndef PY_FORMAT_SIZE_T
+# if SIZEOF_SIZE_T == SIZEOF_INT && !defined(__APPLE__)
+# define PY_FORMAT_SIZE_T ""
+# elif SIZEOF_SIZE_T == SIZEOF_LONG
+# define PY_FORMAT_SIZE_T "l"
+# elif defined(MS_WINDOWS)
+# define PY_FORMAT_SIZE_T "I"
+# else
+# error "This platform's pyconfig.h needs to define PY_FORMAT_SIZE_T"
+# endif
+#endif
+
+/* PY_FORMAT_LONG_LONG is analogous to PY_FORMAT_SIZE_T above, but for
+ * the long long type instead of the size_t type. It's only available
+ * when HAVE_LONG_LONG is defined. The "high level" Python format
+ * functions listed above will interpret "lld" or "llu" correctly on
+ * all platforms.
+ */
+#ifdef HAVE_LONG_LONG
+# ifndef PY_FORMAT_LONG_LONG
+# if defined(MS_WIN64) || defined(MS_WINDOWS)
+# define PY_FORMAT_LONG_LONG "I64"
+# else
+# error "This platform's pyconfig.h needs to define PY_FORMAT_LONG_LONG"
+# endif
+# endif
+#endif
+
+/* Py_LOCAL can be used instead of static to get the fastest possible calling
+ * convention for functions that are local to a given module.
+ *
+ * Py_LOCAL_INLINE does the same thing, and also explicitly requests inlining,
+ * for platforms that support that.
+ *
+ * If PY_LOCAL_AGGRESSIVE is defined before python.h is included, more
+ * "aggressive" inlining/optimizaion is enabled for the entire module. This
+ * may lead to code bloat, and may slow things down for those reasons. It may
+ * also lead to errors, if the code relies on pointer aliasing. Use with
+ * care.
+ *
+ * NOTE: You can only use this for functions that are entirely local to a
+ * module; functions that are exported via method tables, callbacks, etc,
+ * should keep using static.
+ */
+
+#undef USE_INLINE /* XXX - set via configure? */
+
+#if defined(_MSC_VER)
+#if defined(PY_LOCAL_AGGRESSIVE)
+/* enable more aggressive optimization for visual studio */
+//#pragma optimize("agtw", on)
+#pragma optimize("gt", on) // a and w are not legal for VS2005
+#endif
+/* ignore warnings if the compiler decides not to inline a function */
+#pragma warning(disable: 4710)
+/* fastest possible local call under MSVC */
+#define Py_LOCAL(type) static type __fastcall
+#define Py_LOCAL_INLINE(type) static __inline type __fastcall
+#elif defined(USE_INLINE)
+#define Py_LOCAL(type) static type
+#define Py_LOCAL_INLINE(type) static inline type
+#else
+#define Py_LOCAL(type) static type
+#define Py_LOCAL_INLINE(type) static type
+#endif
+
+/* Py_MEMCPY can be used instead of memcpy in cases where the copied blocks
+ * are often very short. While most platforms have highly optimized code for
+ * large transfers, the setup costs for memcpy are often quite high. MEMCPY
+ * solves this by doing short copies "in line".
+ */
+
+#if defined(_MSC_VER)
+#define Py_MEMCPY(target, source, length) do { \
+ size_t i_, n_ = (length); \
+ char *t_ = (void*) (target); \
+ const char *s_ = (void*) (source); \
+ if (n_ >= 16) \
+ memcpy(t_, s_, n_); \
+ else \
+ for (i_ = 0; i_ < n_; i_++) \
+ t_[i_] = s_[i_]; \
+ } while (0)
+#else
+#define Py_MEMCPY memcpy
+#endif
+
+#include <stdlib.h>
+
+#ifdef HAVE_IEEEFP_H
+#include <ieeefp.h> /* needed for 'finite' declaration on some platforms */
+#endif
+
+#include <math.h> /* Moved here from the math section, before extern "C" */
+
+/********************************************
+ * WRAPPER FOR <time.h> and/or <sys/time.h> *
+ ********************************************/
+
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else /* !TIME_WITH_SYS_TIME */
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else /* !HAVE_SYS_TIME_H */
+#include <time.h>
+#endif /* !HAVE_SYS_TIME_H */
+#endif /* !TIME_WITH_SYS_TIME */
+
+
+/******************************
+ * WRAPPER FOR <sys/select.h> *
+ ******************************/
+
+/* NB caller must include <sys/types.h> */
+
+#ifdef HAVE_SYS_SELECT_H
+
+#include <sys/select.h>
+
+#endif /* !HAVE_SYS_SELECT_H */
+
+/*******************************
+ * stat() and fstat() fiddling *
+ *******************************/
+
+/* We expect that stat and fstat exist on most systems.
+ * It's confirmed on Unix, Mac and Windows.
+ * If you don't have them, add
+ * #define DONT_HAVE_STAT
+ * and/or
+ * #define DONT_HAVE_FSTAT
+ * to your pyconfig.h. Python code beyond this should check HAVE_STAT and
+ * HAVE_FSTAT instead.
+ * Also
+ * #define HAVE_SYS_STAT_H
+ * if <sys/stat.h> exists on your platform, and
+ * #define HAVE_STAT_H
+ * if <stat.h> does.
+ */
+#ifndef DONT_HAVE_STAT
+#define HAVE_STAT
+#endif
+
+#ifndef DONT_HAVE_FSTAT
+#define HAVE_FSTAT
+#endif
+
+#ifdef RISCOS
+#include <sys/types.h>
+#include "unixstuff.h"
+#endif
+
+#ifdef HAVE_SYS_STAT_H
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+#include <sys/types.h>
+#endif
+#include <sys/stat.h>
+#elif defined(HAVE_STAT_H)
+#include <stat.h>
+#endif
+
+#if defined(PYCC_VACPP)
+/* VisualAge C/C++ Failed to Define MountType Field in sys/stat.h */
+#define S_IFMT (S_IFDIR|S_IFCHR|S_IFREG)
+#endif
+
+#ifndef S_ISREG
+#define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
+#endif
+
+#ifndef S_ISDIR
+#define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR)
+#endif
+
+
+#ifdef __cplusplus
+/* Move this down here since some C++ #include's don't like to be included
+ inside an extern "C" */
+extern "C" {
+#endif
+
+
+/* Py_ARITHMETIC_RIGHT_SHIFT
+ * C doesn't define whether a right-shift of a signed integer sign-extends
+ * or zero-fills. Here a macro to force sign extension:
+ * Py_ARITHMETIC_RIGHT_SHIFT(TYPE, I, J)
+ * Return I >> J, forcing sign extension. Arithmetically, return the
+ * floor of I/2**J.
+ * Requirements:
+ * I should have signed integer type. In the terminology of C99, this can
+ * be either one of the five standard signed integer types (signed char,
+ * short, int, long, long long) or an extended signed integer type.
+ * J is an integer >= 0 and strictly less than the number of bits in the
+ * type of I (because C doesn't define what happens for J outside that
+ * range either).
+ * TYPE used to specify the type of I, but is now ignored. It's been left
+ * in for backwards compatibility with versions <= 2.6 or 3.0.
+ * Caution:
+ * I may be evaluated more than once.
+ */
+#ifdef SIGNED_RIGHT_SHIFT_ZERO_FILLS
+#define Py_ARITHMETIC_RIGHT_SHIFT(TYPE, I, J) \
+ ((I) < 0 ? -1-((-1-(I)) >> (J)) : (I) >> (J))
+#else
+#define Py_ARITHMETIC_RIGHT_SHIFT(TYPE, I, J) ((I) >> (J))
+#endif
+
+/* Py_FORCE_EXPANSION(X)
+ * "Simply" returns its argument. However, macro expansions within the
+ * argument are evaluated. This unfortunate trickery is needed to get
+ * token-pasting to work as desired in some cases.
+ */
+#define Py_FORCE_EXPANSION(X) X
+
+/* Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW)
+ * Cast VALUE to type NARROW from type WIDE. In Py_DEBUG mode, this
+ * assert-fails if any information is lost.
+ * Caution:
+ * VALUE may be evaluated more than once.
+ */
+#ifdef Py_DEBUG
+#define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) \
+ (assert((WIDE)(NARROW)(VALUE) == (VALUE)), (NARROW)(VALUE))
+#else
+#define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) (NARROW)(VALUE)
+#endif
+
+/* Py_SET_ERRNO_ON_MATH_ERROR(x)
+ * If a libm function did not set errno, but it looks like the result
+ * overflowed or not-a-number, set errno to ERANGE or EDOM. Set errno
+ * to 0 before calling a libm function, and invoke this macro after,
+ * passing the function result.
+ * Caution:
+ * This isn't reliable. See Py_OVERFLOWED comments.
+ * X is evaluated more than once.
+ */
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || (defined(__hpux) && defined(__ia64))
+#define _Py_SET_EDOM_FOR_NAN(X) if (isnan(X)) errno = EDOM;
+#else
+#define _Py_SET_EDOM_FOR_NAN(X) ;
+#endif
+#define Py_SET_ERRNO_ON_MATH_ERROR(X) \
+ do { \
+ if (errno == 0) { \
+ if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL) \
+ errno = ERANGE; \
+ else _Py_SET_EDOM_FOR_NAN(X) \
+ } \
+ } while(0)
+
+/* Py_SET_ERANGE_ON_OVERFLOW(x)
+ * An alias of Py_SET_ERRNO_ON_MATH_ERROR for backward-compatibility.
+ */
+#define Py_SET_ERANGE_IF_OVERFLOW(X) Py_SET_ERRNO_ON_MATH_ERROR(X)
+
+/* Py_ADJUST_ERANGE1(x)
+ * Py_ADJUST_ERANGE2(x, y)
+ * Set errno to 0 before calling a libm function, and invoke one of these
+ * macros after, passing the function result(s) (Py_ADJUST_ERANGE2 is useful
+ * for functions returning complex results). This makes two kinds of
+ * adjustments to errno: (A) If it looks like the platform libm set
+ * errno=ERANGE due to underflow, clear errno. (B) If it looks like the
+ * platform libm overflowed but didn't set errno, force errno to ERANGE. In
+ * effect, we're trying to force a useful implementation of C89 errno
+ * behavior.
+ * Caution:
+ * This isn't reliable. See Py_OVERFLOWED comments.
+ * X and Y may be evaluated more than once.
+ */
+#define Py_ADJUST_ERANGE1(X) \
+ do { \
+ if (errno == 0) { \
+ if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL) \
+ errno = ERANGE; \
+ } \
+ else if (errno == ERANGE && (X) == 0.0) \
+ errno = 0; \
+ } while(0)
+
+#define Py_ADJUST_ERANGE2(X, Y) \
+ do { \
+ if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL || \
+ (Y) == Py_HUGE_VAL || (Y) == -Py_HUGE_VAL) { \
+ if (errno == 0) \
+ errno = ERANGE; \
+ } \
+ else if (errno == ERANGE) \
+ errno = 0; \
+ } while(0)
+
+/* The functions _Py_dg_strtod and _Py_dg_dtoa in Python/dtoa.c (which are
+ * required to support the short float repr introduced in Python 3.1) require
+ * that the floating-point unit that's being used for arithmetic operations
+ * on C doubles is set to use 53-bit precision. It also requires that the
+ * FPU rounding mode is round-half-to-even, but that's less often an issue.
+ *
+ * If your FPU isn't already set to 53-bit precision/round-half-to-even, and
+ * you want to make use of _Py_dg_strtod and _Py_dg_dtoa, then you should
+ *
+ * #define HAVE_PY_SET_53BIT_PRECISION 1
+ *
+ * and also give appropriate definitions for the following three macros:
+ *
+ * _PY_SET_53BIT_PRECISION_START : store original FPU settings, and
+ * set FPU to 53-bit precision/round-half-to-even
+ * _PY_SET_53BIT_PRECISION_END : restore original FPU settings
+ * _PY_SET_53BIT_PRECISION_HEADER : any variable declarations needed to
+ * use the two macros above.
+ *
+ * The macros are designed to be used within a single C function: see
+ * Python/pystrtod.c for an example of their use.
+ */
+
+/* get and set x87 control word for gcc/x86 */
+#ifdef HAVE_GCC_ASM_FOR_X87
+#define HAVE_PY_SET_53BIT_PRECISION 1
+/* _Py_get/set_387controlword functions are defined in Python/pymath.c */
+#define _Py_SET_53BIT_PRECISION_HEADER \
+ unsigned short old_387controlword, new_387controlword
+#define _Py_SET_53BIT_PRECISION_START \
+ do { \
+ old_387controlword = _Py_get_387controlword(); \
+ new_387controlword = (old_387controlword & ~0x0f00) | 0x0200; \
+ if (new_387controlword != old_387controlword) \
+ _Py_set_387controlword(new_387controlword); \
+ } while (0)
+#define _Py_SET_53BIT_PRECISION_END \
+ if (new_387controlword != old_387controlword) \
+ _Py_set_387controlword(old_387controlword)
+#endif
+
+/* get and set x87 control word for VisualStudio/x86 */
+#if defined(_MSC_VER) && !defined(_WIN64) && !defined(UEFI_C_SOURCE) /* x87 not supported in 64-bit */
+#define HAVE_PY_SET_53BIT_PRECISION 1
+#define _Py_SET_53BIT_PRECISION_HEADER \
+ unsigned int old_387controlword, new_387controlword, out_387controlword
+/* We use the __control87_2 function to set only the x87 control word.
+ The SSE control word is unaffected. */
+#define _Py_SET_53BIT_PRECISION_START \
+ do { \
+ __control87_2(0, 0, &old_387controlword, NULL); \
+ new_387controlword = \
+ (old_387controlword & ~(_MCW_PC | _MCW_RC)) | (_PC_53 | _RC_NEAR); \
+ if (new_387controlword != old_387controlword) \
+ __control87_2(new_387controlword, _MCW_PC | _MCW_RC, \
+ &out_387controlword, NULL); \
+ } while (0)
+#define _Py_SET_53BIT_PRECISION_END \
+ do { \
+ if (new_387controlword != old_387controlword) \
+ __control87_2(old_387controlword, _MCW_PC | _MCW_RC, \
+ &out_387controlword, NULL); \
+ } while (0)
+#endif
+
+/* default definitions are empty */
+#ifndef HAVE_PY_SET_53BIT_PRECISION
+#define _Py_SET_53BIT_PRECISION_HEADER
+#define _Py_SET_53BIT_PRECISION_START
+#define _Py_SET_53BIT_PRECISION_END
+#endif
+
+/* If we can't guarantee 53-bit precision, don't use the code
+ in Python/dtoa.c, but fall back to standard code. This
+ means that repr of a float will be long (17 sig digits).
+
+ Realistically, there are two things that could go wrong:
+
+ (1) doubles aren't IEEE 754 doubles, or
+ (2) we're on x86 with the rounding precision set to 64-bits
+ (extended precision), and we don't know how to change
+ the rounding precision.
+ */
+
+#if !defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754) && \
+ !defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) && \
+ !defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754)
+#define PY_NO_SHORT_FLOAT_REPR
+#endif
+
+/* double rounding is symptomatic of use of extended precision on x86. If
+ we're seeing double rounding, and we don't have any mechanism available for
+ changing the FPU rounding precision, then don't use Python/dtoa.c. */
+#if defined(X87_DOUBLE_ROUNDING) && !defined(HAVE_PY_SET_53BIT_PRECISION)
+#define PY_NO_SHORT_FLOAT_REPR
+#endif
+
+/* Py_DEPRECATED(version)
+ * Declare a variable, type, or function deprecated.
+ * Usage:
+ * extern int old_var Py_DEPRECATED(2.3);
+ * typedef int T1 Py_DEPRECATED(2.4);
+ * extern int x() Py_DEPRECATED(2.5);
+ */
+#if defined(__GNUC__) && ((__GNUC__ >= 4) || \
+ (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))
+#define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
+#else
+#define Py_DEPRECATED(VERSION_UNUSED)
+#endif
+
+/**************************************************************************
+Prototypes that are missing from the standard include files on some systems
+(and possibly only some versions of such systems.)
+
+Please be conservative with adding new ones, document them and enclose them
+in platform-specific #ifdefs.
+**************************************************************************/
+
+#ifdef SOLARIS
+/* Unchecked */
+extern int gethostname(char *, int);
+#endif
+
+#ifdef __BEOS__
+/* Unchecked */
+/* It's in the libs, but not the headers... - [cjh] */
+int shutdown( int, int );
+#endif
+
+#ifdef HAVE__GETPTY
+#include <sys/types.h> /* we need to import mode_t */
+extern char * _getpty(int *, int, mode_t, int);
+#endif
+
+/* On QNX 6, struct termio must be declared by including sys/termio.h
+ if TCGETA, TCSETA, TCSETAW, or TCSETAF are used. sys/termio.h must
+ be included before termios.h or it will generate an error. */
+#if defined(HAVE_SYS_TERMIO_H) && !defined(__hpux)
+#include <sys/termio.h>
+#endif
+
+#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
+#if !defined(HAVE_PTY_H) && !defined(HAVE_LIBUTIL_H) && !defined(HAVE_UTIL_H)
+/* BSDI does not supply a prototype for the 'openpty' and 'forkpty'
+ functions, even though they are included in libutil. */
+#include <termios.h>
+extern int openpty(int *, int *, char *, struct termios *, struct winsize *);
+extern pid_t forkpty(int *, char *, struct termios *, struct winsize *);
+#endif /* !defined(HAVE_PTY_H) && !defined(HAVE_LIBUTIL_H) */
+#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
+
+
+/* These are pulled from various places. It isn't obvious on what platforms
+ they are necessary, nor what the exact prototype should look like (which
+ is likely to vary between platforms!) If you find you need one of these
+ declarations, please move them to a platform-specific block and include
+ proper prototypes. */
+#if 0
+
+/* From Modules/resource.c */
+extern int getrusage();
+extern int getpagesize();
+
+/* From Python/sysmodule.c and Modules/posixmodule.c */
+extern int fclose(FILE *);
+
+/* From Modules/posixmodule.c */
+extern int fdatasync(int);
+#endif /* 0 */
+
+
+/* On 4.4BSD-descendants, ctype functions serves the whole range of
+ * wchar_t character set rather than single byte code points only.
+ * This characteristic can break some operations of string object
+ * including str.upper() and str.split() on UTF-8 locales. This
+ * workaround was provided by Tim Robbins of FreeBSD project.
+ */
+
+#ifdef __FreeBSD__
+#include <osreldate.h>
+#if __FreeBSD_version > 500039
+# define _PY_PORT_CTYPE_UTF8_ISSUE
+#endif
+#endif
+
+
+#if defined(__APPLE__)
+# define _PY_PORT_CTYPE_UTF8_ISSUE
+#endif
+
+#ifdef _PY_PORT_CTYPE_UTF8_ISSUE
+#include <ctype.h>
+#include <wctype.h>
+#undef isalnum
+#define isalnum(c) iswalnum(btowc(c))
+#undef isalpha
+#define isalpha(c) iswalpha(btowc(c))
+#undef islower
+#define islower(c) iswlower(btowc(c))
+#undef isspace
+#define isspace(c) iswspace(btowc(c))
+#undef isupper
+#define isupper(c) iswupper(btowc(c))
+#undef tolower
+#define tolower(c) towlower(btowc(c))
+#undef toupper
+#define toupper(c) towupper(btowc(c))
+#endif
+
+
+/* Declarations for symbol visibility.
+
+ PyAPI_FUNC(type): Declares a public Python API function and return type
+ PyAPI_DATA(type): Declares public Python data and its type
+ PyMODINIT_FUNC: A Python module init function. If these functions are
+ inside the Python core, they are private to the core.
+ If in an extension module, it may be declared with
+ external linkage depending on the platform.
+
+ As a number of platforms support/require "__declspec(dllimport/dllexport)",
+ we support a HAVE_DECLSPEC_DLL macro to save duplication.
+*/
+
+/*
+ All windows ports, except cygwin, are handled in PC/pyconfig.h.
+
+ BeOS and cygwin are the only other autoconf platform requiring special
+ linkage handling and both of these use __declspec().
+*/
+#if defined(__CYGWIN__) || defined(__BEOS__)
+# define HAVE_DECLSPEC_DLL
+#endif
+
+/* only get special linkage if built as shared or platform is Cygwin */
+#if defined(Py_ENABLE_SHARED) || defined(__CYGWIN__)
+# if defined(HAVE_DECLSPEC_DLL)
+# ifdef Py_BUILD_CORE
+# define PyAPI_FUNC(RTYPE) __declspec(dllexport) RTYPE
+# define PyAPI_DATA(RTYPE) extern __declspec(dllexport) RTYPE
+ /* module init functions inside the core need no external linkage */
+ /* except for Cygwin to handle embedding (FIXME: BeOS too?) */
+# if defined(__CYGWIN__)
+# define PyMODINIT_FUNC __declspec(dllexport) void
+# else /* __CYGWIN__ */
+# define PyMODINIT_FUNC void
+# endif /* __CYGWIN__ */
+# else /* Py_BUILD_CORE */
+ /* Building an extension module, or an embedded situation */
+ /* public Python functions and data are imported */
+ /* Under Cygwin, auto-import functions to prevent compilation */
+ /* failures similar to those described at the bottom of 4.1: */
+ /* http://docs.python.org/extending/windows.html#a-cookbook-approach */
+# if !defined(__CYGWIN__)
+# define PyAPI_FUNC(RTYPE) __declspec(dllimport) RTYPE
+# endif /* !__CYGWIN__ */
+# define PyAPI_DATA(RTYPE) extern __declspec(dllimport) RTYPE
+ /* module init functions outside the core must be exported */
+# if defined(__cplusplus)
+# define PyMODINIT_FUNC extern "C" __declspec(dllexport) void
+# else /* __cplusplus */
+# define PyMODINIT_FUNC __declspec(dllexport) void
+# endif /* __cplusplus */
+# endif /* Py_BUILD_CORE */
+# endif /* HAVE_DECLSPEC */
+#endif /* Py_ENABLE_SHARED */
+
+/* If no external linkage macros defined by now, create defaults */
+#ifndef PyAPI_FUNC
+# define PyAPI_FUNC(RTYPE) RTYPE
+#endif
+#ifndef PyAPI_DATA
+# define PyAPI_DATA(RTYPE) extern RTYPE
+#endif
+#ifndef PyMODINIT_FUNC
+# if defined(__cplusplus)
+# define PyMODINIT_FUNC extern "C" void
+# else /* __cplusplus */
+# define PyMODINIT_FUNC void
+# endif /* __cplusplus */
+#endif
+
+/* Deprecated DL_IMPORT and DL_EXPORT macros */
+#if defined(Py_ENABLE_SHARED) && defined (HAVE_DECLSPEC_DLL)
+# if defined(Py_BUILD_CORE)
+# define DL_IMPORT(RTYPE) __declspec(dllexport) RTYPE
+# define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE
+# else
+# define DL_IMPORT(RTYPE) __declspec(dllimport) RTYPE
+# define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE
+# endif
+#endif
+#ifndef DL_EXPORT
+# define DL_EXPORT(RTYPE) RTYPE
+#endif
+#ifndef DL_IMPORT
+# define DL_IMPORT(RTYPE) RTYPE
+#endif
+/* End of deprecated DL_* macros */
+
+/* If the fd manipulation macros aren't defined,
+ here is a set that should do the job */
+
+#if 0 /* disabled and probably obsolete */
+
+#ifndef FD_SETSIZE
+#define FD_SETSIZE 256
+#endif
+
+#ifndef FD_SET
+
+typedef long fd_mask;
+
+#define NFDBITS (sizeof(fd_mask) * NBBY) /* bits per mask */
+#ifndef howmany
+#define howmany(x, y) (((x)+((y)-1))/(y))
+#endif /* howmany */
+
+typedef struct fd_set {
+ fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
+} fd_set;
+
+#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p) memset((char *)(p), '\0', sizeof(*(p)))
+
+#endif /* FD_SET */
+
+#endif /* fd manipulation macros */
+
+
+/* limits.h constants that may be missing */
+
+#ifndef INT_MAX
+#define INT_MAX 2147483647
+#endif
+
+#ifndef LONG_MAX
+#if SIZEOF_LONG == 4
+#define LONG_MAX 0X7FFFFFFFL
+#elif SIZEOF_LONG == 8
+#define LONG_MAX 0X7FFFFFFFFFFFFFFFL
+#else
+#error "could not set LONG_MAX in pyport.h"
+#endif
+#endif
+
+#ifndef LONG_MIN
+#define LONG_MIN (-LONG_MAX-1)
+#endif
+
+#ifndef LONG_BIT
+#define LONG_BIT (8 * SIZEOF_LONG)
+#endif
+
+#if LONG_BIT != 8 * SIZEOF_LONG
+/* 04-Oct-2000 LONG_BIT is apparently (mis)defined as 64 on some recent
+ * 32-bit platforms using gcc. We try to catch that here at compile-time
+ * rather than waiting for integer multiplication to trigger bogus
+ * overflows.
+ */
+#error "LONG_BIT definition appears wrong for platform (bad gcc/glibc config?)."
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/*
+ * Hide GCC attributes from compilers that don't support them.
+ */
+#if (!defined(__GNUC__) || __GNUC__ < 2 || \
+ (__GNUC__ == 2 && __GNUC_MINOR__ < 7) ) && \
+ !defined(RISCOS)
+#define Py_GCC_ATTRIBUTE(x)
+#else
+#define Py_GCC_ATTRIBUTE(x) __attribute__(x)
+#endif
+
+/*
+ * Add PyArg_ParseTuple format where available.
+ */
+#ifdef HAVE_ATTRIBUTE_FORMAT_PARSETUPLE
+#define Py_FORMAT_PARSETUPLE(func,p1,p2) __attribute__((format(func,p1,p2)))
+#else
+#define Py_FORMAT_PARSETUPLE(func,p1,p2)
+#endif
+
+/*
+ * Specify alignment on compilers that support it.
+ */
+#if defined(__GNUC__) && __GNUC__ >= 3
+#define Py_ALIGNED(x) __attribute__((aligned(x)))
+#else
+#define Py_ALIGNED(x)
+#endif
+
+/* Eliminate end-of-loop code not reached warnings from SunPro C
+ * when using do{...}while(0) macros
+ */
+#ifdef __SUNPRO_C
+#pragma error_messages (off,E_END_OF_LOOP_CODE_NOT_REACHED)
+#endif
+
+/*
+ * Older Microsoft compilers don't support the C99 long long literal suffixes,
+ * so these will be defined in PC/pyconfig.h for those compilers.
+ */
+#ifndef Py_LL
+#define Py_LL(x) x##LL
+#endif
+
+#ifndef Py_ULL
+#define Py_ULL(x) Py_LL(x##U)
+#endif
+
+#endif /* Py_PYPORT_H */
diff --git a/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Lib/ntpath.py b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Lib/ntpath.py new file mode 100644 index 0000000000..ac89e2c9fe --- /dev/null +++ b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Lib/ntpath.py @@ -0,0 +1,550 @@ +# Module 'ntpath' -- common operations on WinNT/Win95 pathnames
+"""Common pathname manipulations, WindowsNT/95 version.
+
+Instead of importing this module directly, import os and refer to this
+module as os.path.
+"""
+
+import os
+import sys
+import stat
+import genericpath
+import warnings
+
+from genericpath import *
+from genericpath import _unicode
+
+__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
+ "basename","dirname","commonprefix","getsize","getmtime",
+ "getatime","getctime", "islink","exists","lexists","isdir","isfile",
+ "ismount","walk","expanduser","expandvars","normpath","abspath",
+ "splitunc","curdir","pardir","sep","pathsep","defpath","altsep",
+ "extsep","devnull","realpath","supports_unicode_filenames","relpath"]
+
+# strings representing various path-related bits and pieces
+curdir = '.'
+pardir = '..'
+extsep = '.'
+sep = '\\'
+pathsep = ';'
+altsep = '/'
+defpath = '.;C:\\bin'
+if 'ce' in sys.builtin_module_names:
+ defpath = '\\Windows'
+elif 'os2' in sys.builtin_module_names:
+ # OS/2 w/ VACPP
+ altsep = '/'
+devnull = 'nul'
+
+# Normalize the case of a pathname and map slashes to backslashes.
+# Other normalizations (such as optimizing '../' away) are not done
+# (this is done by normpath).
+
+def normcase(s):
+ """Normalize case of pathname.
+
+ Makes all characters lowercase and all slashes into backslashes."""
+ return s.replace("/", "\\").lower()
+
+
+# Return whether a path is absolute.
+# Trivial in Posix, harder on the Mac or MS-DOS.
+# For DOS it is absolute if it starts with a slash or backslash (current
+# volume), or if a pathname after the volume letter and colon / UNC resource
+# starts with a slash or backslash.
+
+def isabs(s):
+ """Test whether a path is absolute"""
+ s = splitdrive(s)[1]
+ return s != '' and s[:1] in '/\\'
+
+
+# Join two (or more) paths.
+def join(path, *paths):
+ """Join two or more pathname components, inserting "\\" as needed."""
+ result_drive, result_path = splitdrive(path)
+ for p in paths:
+ p_drive, p_path = splitdrive(p)
+ if p_path and p_path[0] in '\\/':
+ # Second path is absolute
+ if p_drive or not result_drive:
+ result_drive = p_drive
+ result_path = p_path
+ continue
+ elif p_drive and p_drive != result_drive:
+ if p_drive.lower() != result_drive.lower():
+ # Different drives => ignore the first path entirely
+ result_drive = p_drive
+ result_path = p_path
+ continue
+ # Same drive in different case
+ result_drive = p_drive
+ # Second path is relative to the first
+ if result_path and result_path[-1] not in '\\/':
+ result_path = result_path + '\\'
+ result_path = result_path + p_path
+ ## add separator between UNC and non-absolute path
+ if (result_path and result_path[0] not in '\\/' and
+ result_drive and result_drive[-1:] != ':'):
+ return result_drive + sep + result_path
+ return result_drive + result_path
+
+
+# Split a path in a drive specification (a drive letter followed by a
+# colon) and the path specification.
+# It is always true that drivespec + pathspec == p
+def splitdrive(p):
+ """Split a pathname into drive/UNC sharepoint and relative path specifiers.
+ Returns a 2-tuple (drive_or_unc, path); either part may be empty.
+
+ If you assign
+ result = splitdrive(p)
+ It is always true that:
+ result[0] + result[1] == p
+
+ If the path contained a drive letter, drive_or_unc will contain everything
+ up to and including the colon. e.g. splitdrive("c:/dir") returns ("c:", "/dir")
+
+ If the path contained a UNC path, the drive_or_unc will contain the host name
+ and share up to but not including the fourth directory separator character.
+ e.g. splitdrive("//host/computer/dir") returns ("//host/computer", "/dir")
+
+ Paths cannot contain both a drive letter and a UNC path.
+
+ """
+ if len(p) > 1:
+ normp = p.replace(altsep, sep)
+ if (normp[0:2] == sep*2) and (normp[2:3] != sep):
+ # is a UNC path:
+ # vvvvvvvvvvvvvvvvvvvv drive letter or UNC path
+ # \\machine\mountpoint\directory\etc\...
+ # directory ^^^^^^^^^^^^^^^
+ index = normp.find(sep, 2)
+ if index == -1:
+ return '', p
+ index2 = normp.find(sep, index + 1)
+ # a UNC path can't have two slashes in a row
+ # (after the initial two)
+ if index2 == index + 1:
+ return '', p
+ if index2 == -1:
+ index2 = len(p)
+ return p[:index2], p[index2:]
+ if normp[1] == ':':
+ return p[:2], p[2:]
+ return '', p
+
+# Parse UNC paths
+def splitunc(p):
+ """Split a pathname into UNC mount point and relative path specifiers.
+
+ Return a 2-tuple (unc, rest); either part may be empty.
+ If unc is not empty, it has the form '//host/mount' (or similar
+ using backslashes). unc+rest is always the input path.
+ Paths containing drive letters never have an UNC part.
+ """
+ if p[1:2] == ':':
+ return '', p # Drive letter present
+ firstTwo = p[0:2]
+ if firstTwo == '//' or firstTwo == '\\\\':
+ # is a UNC path:
+ # vvvvvvvvvvvvvvvvvvvv equivalent to drive letter
+ # \\machine\mountpoint\directories...
+ # directory ^^^^^^^^^^^^^^^
+ normp = p.replace('\\', '/')
+ index = normp.find('/', 2)
+ if index <= 2:
+ return '', p
+ index2 = normp.find('/', index + 1)
+ # a UNC path can't have two slashes in a row
+ # (after the initial two)
+ if index2 == index + 1:
+ return '', p
+ if index2 == -1:
+ index2 = len(p)
+ return p[:index2], p[index2:]
+ return '', p
+
+
+# Split a path in head (everything up to the last '/') and tail (the
+# rest). After the trailing '/' is stripped, the invariant
+# join(head, tail) == p holds.
+# The resulting head won't end in '/' unless it is the root.
+
+def split(p):
+ """Split a pathname.
+
+ Return tuple (head, tail) where tail is everything after the final slash.
+ Either part may be empty."""
+
+ d, p = splitdrive(p)
+ # set i to index beyond p's last slash
+ i = len(p)
+ while i and p[i-1] not in '/\\':
+ i = i - 1
+ head, tail = p[:i], p[i:] # now tail has no slashes
+ # remove trailing slashes from head, unless it's all slashes
+ head2 = head
+ while head2 and head2[-1] in '/\\':
+ head2 = head2[:-1]
+ head = head2 or head
+ return d + head, tail
+
+
+# Split a path in root and extension.
+# The extension is everything starting at the last dot in the last
+# pathname component; the root is everything before that.
+# It is always true that root + ext == p.
+
+def splitext(p):
+ return genericpath._splitext(p, sep, altsep, extsep)
+splitext.__doc__ = genericpath._splitext.__doc__
+
+
+# Return the tail (basename) part of a path.
+
+def basename(p):
+ """Returns the final component of a pathname"""
+ return split(p)[1]
+
+
+# Return the head (dirname) part of a path.
+
+def dirname(p):
+ """Returns the directory component of a pathname"""
+ return split(p)[0]
+
+# Is a path a symbolic link?
+# This will always return false on systems where posix.lstat doesn't exist.
+
+def islink(path):
+ """Test for symbolic link.
+ On WindowsNT/95 and OS/2 always returns false
+ """
+ return False
+
+# alias exists to lexists
+lexists = exists
+
+# Is a path a mount point? Either a root (with or without drive letter)
+# or an UNC path with at most a / or \ after the mount point.
+
+def ismount(path):
+ """Test whether a path is a mount point (defined as root of drive)"""
+ unc, rest = splitunc(path)
+ if unc:
+ return rest in ("", "/", "\\")
+ p = splitdrive(path)[1]
+ return len(p) == 1 and p[0] in '/\\'
+
+
+# Directory tree walk.
+# For each directory under top (including top itself, but excluding
+# '.' and '..'), func(arg, dirname, filenames) is called, where
+# dirname is the name of the directory and filenames is the list
+# of files (and subdirectories etc.) in the directory.
+# The func may modify the filenames list, to implement a filter,
+# or to impose a different order of visiting.
+
+def walk(top, func, arg):
+ """Directory tree walk with callback function.
+
+ For each directory in the directory tree rooted at top (including top
+ itself, but excluding '.' and '..'), call func(arg, dirname, fnames).
+ dirname is the name of the directory, and fnames a list of the names of
+ the files and subdirectories in dirname (excluding '.' and '..'). func
+ may modify the fnames list in-place (e.g. via del or slice assignment),
+ and walk will only recurse into the subdirectories whose names remain in
+ fnames; this can be used to implement a filter, or to impose a specific
+ order of visiting. No semantics are defined for, or required of, arg,
+ beyond that arg is always passed to func. It can be used, e.g., to pass
+ a filename pattern, or a mutable object designed to accumulate
+ statistics. Passing None for arg is common."""
+ warnings.warnpy3k("In 3.x, os.path.walk is removed in favor of os.walk.",
+ stacklevel=2)
+ try:
+ names = os.listdir(top)
+ except os.error:
+ return
+ func(arg, top, names)
+ for name in names:
+ name = join(top, name)
+ if isdir(name):
+ walk(name, func, arg)
+
+
+# Expand paths beginning with '~' or '~user'.
+# '~' means $HOME; '~user' means that user's home directory.
+# If the path doesn't begin with '~', or if the user or $HOME is unknown,
+# the path is returned unchanged (leaving error reporting to whatever
+# function is called with the expanded path as argument).
+# See also module 'glob' for expansion of *, ? and [...] in pathnames.
+# (A function should also be defined to do full *sh-style environment
+# variable expansion.)
+
+def expanduser(path):
+ """Expand ~ and ~user constructs.
+
+ If user or $HOME is unknown, do nothing."""
+ if path[:1] != '~':
+ return path
+ i, n = 1, len(path)
+ while i < n and path[i] not in '/\\':
+ i = i + 1
+
+ if 'HOME' in os.environ:
+ userhome = os.environ['HOME']
+ elif 'USERPROFILE' in os.environ:
+ userhome = os.environ['USERPROFILE']
+ elif not 'HOMEPATH' in os.environ:
+ return path
+ else:
+ try:
+ drive = os.environ['HOMEDRIVE']
+ except KeyError:
+ drive = ''
+ userhome = join(drive, os.environ['HOMEPATH'])
+
+ if i != 1: #~user
+ userhome = join(dirname(userhome), path[1:i])
+
+ return userhome + path[i:]
+
+
+# Expand paths containing shell variable substitutions.
+# The following rules apply:
+# - no expansion within single quotes
+# - '$$' is translated into '$'
+# - '%%' is translated into '%' if '%%' are not seen in %var1%%var2%
+# - ${varname} is accepted.
+# - $varname is accepted.
+# - %varname% is accepted.
+# - varnames can be made out of letters, digits and the characters '_-'
+# (though is not verified in the ${varname} and %varname% cases)
+# XXX With COMMAND.COM you can use any characters in a variable name,
+# XXX except '^|<>='.
+
+def expandvars(path):
+ """Expand shell variables of the forms $var, ${var} and %var%.
+
+ Unknown variables are left unchanged."""
+ if '$' not in path and '%' not in path:
+ return path
+ import string
+ varchars = string.ascii_letters + string.digits + '_-'
+ if isinstance(path, _unicode):
+ encoding = sys.getfilesystemencoding()
+ def getenv(var):
+ return os.environ[var.encode(encoding)].decode(encoding)
+ else:
+ def getenv(var):
+ return os.environ[var]
+ res = ''
+ index = 0
+ pathlen = len(path)
+ while index < pathlen:
+ c = path[index]
+ if c == '\'': # no expansion within single quotes
+ path = path[index + 1:]
+ pathlen = len(path)
+ try:
+ index = path.index('\'')
+ res = res + '\'' + path[:index + 1]
+ except ValueError:
+ res = res + c + path
+ index = pathlen - 1
+ elif c == '%': # variable or '%'
+ if path[index + 1:index + 2] == '%':
+ res = res + c
+ index = index + 1
+ else:
+ path = path[index+1:]
+ pathlen = len(path)
+ try:
+ index = path.index('%')
+ except ValueError:
+ res = res + '%' + path
+ index = pathlen - 1
+ else:
+ var = path[:index]
+ try:
+ res = res + getenv(var)
+ except KeyError:
+ res = res + '%' + var + '%'
+ elif c == '$': # variable or '$$'
+ if path[index + 1:index + 2] == '$':
+ res = res + c
+ index = index + 1
+ elif path[index + 1:index + 2] == '{':
+ path = path[index+2:]
+ pathlen = len(path)
+ try:
+ index = path.index('}')
+ var = path[:index]
+ try:
+ res = res + getenv(var)
+ except KeyError:
+ res = res + '${' + var + '}'
+ except ValueError:
+ res = res + '${' + path
+ index = pathlen - 1
+ else:
+ var = ''
+ index = index + 1
+ c = path[index:index + 1]
+ while c != '' and c in varchars:
+ var = var + c
+ index = index + 1
+ c = path[index:index + 1]
+ try:
+ res = res + getenv(var)
+ except KeyError:
+ res = res + '$' + var
+ if c != '':
+ index = index - 1
+ else:
+ res = res + c
+ index = index + 1
+ return res
+
+
+# Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A\B.
+# Previously, this function also truncated pathnames to 8+3 format,
+# but as this module is called "ntpath", that's obviously wrong!
+
+def normpath(path):
+ """Normalize path, eliminating double slashes, etc."""
+ # Preserve unicode (if path is unicode)
+ backslash, dot = (u'\\', u'.') if isinstance(path, _unicode) else ('\\', '.')
+ if path.startswith(('\\\\.\\', '\\\\?\\')):
+ # in the case of paths with these prefixes:
+ # \\.\ -> device names
+ # \\?\ -> literal paths
+ # do not do any normalization, but return the path unchanged
+ return path
+ path = path.replace("/", "\\")
+ prefix, path = splitdrive(path)
+ # We need to be careful here. If the prefix is empty, and the path starts
+ # with a backslash, it could either be an absolute path on the current
+ # drive (\dir1\dir2\file) or a UNC filename (\\server\mount\dir1\file). It
+ # is therefore imperative NOT to collapse multiple backslashes blindly in
+ # that case.
+ # The code below preserves multiple backslashes when there is no drive
+ # letter. This means that the invalid filename \\\a\b is preserved
+ # unchanged, where a\\\b is normalised to a\b. It's not clear that there
+ # is any better behaviour for such edge cases.
+ if prefix == '':
+ # No drive letter - preserve initial backslashes
+ while path[:1] == "\\":
+ prefix = prefix + backslash
+ path = path[1:]
+ else:
+ # We have a drive letter - collapse initial backslashes
+ if path.startswith("\\"):
+ prefix = prefix + backslash
+ path = path.lstrip("\\")
+ comps = path.split("\\")
+ i = 0
+ while i < len(comps):
+ if comps[i] in ('.', ''):
+ del comps[i]
+ elif comps[i] == '..':
+ if i > 0 and comps[i-1] != '..':
+ del comps[i-1:i+1]
+ i -= 1
+ elif i == 0 and prefix.endswith("\\"):
+ del comps[i]
+ else:
+ i += 1
+ else:
+ i += 1
+ # If the path is now empty, substitute '.'
+ if not prefix and not comps:
+ comps.append(dot)
+ return prefix + backslash.join(comps)
+
+
+# Return an absolute path.
+try:
+ from nt import _getfullpathname
+
+except ImportError: # not running on Windows - mock up something sensible
+ def abspath(path):
+ """Return the absolute version of a path."""
+ if not isabs(path):
+ if isinstance(path, _unicode):
+ cwd = os.getcwdu()
+ else:
+ cwd = os.getcwd()
+ path = join(cwd, path)
+ return normpath(path)
+
+else: # use native Windows method on Windows
+ def abspath(path):
+ """Return the absolute version of a path."""
+
+ if path: # Empty path must return current working directory.
+ try:
+ path = _getfullpathname(path)
+ except WindowsError:
+ pass # Bad path - return unchanged.
+ elif isinstance(path, _unicode):
+ path = os.getcwdu()
+ else:
+ path = os.getcwd()
+ return normpath(path)
+
+# realpath is a no-op on systems without islink support
+realpath = abspath
+# Win9x family and earlier have no Unicode filename support.
+supports_unicode_filenames = (hasattr(sys, "getwindowsversion") and
+ sys.getwindowsversion()[3] >= 2)
+
+def _abspath_split(path):
+ abs = abspath(normpath(path))
+ prefix, rest = splitunc(abs)
+ is_unc = bool(prefix)
+ if not is_unc:
+ prefix, rest = splitdrive(abs)
+ return is_unc, prefix, [x for x in rest.split(sep) if x]
+
+def relpath(path, start=curdir):
+ """Return a relative version of a path"""
+
+ if not path:
+ raise ValueError("no path specified")
+
+ start_is_unc, start_prefix, start_list = _abspath_split(start)
+ path_is_unc, path_prefix, path_list = _abspath_split(path)
+
+ if path_is_unc ^ start_is_unc:
+ raise ValueError("Cannot mix UNC and non-UNC paths (%s and %s)"
+ % (path, start))
+ if path_prefix.lower() != start_prefix.lower():
+ if path_is_unc:
+ raise ValueError("path is on UNC root %s, start on UNC root %s"
+ % (path_prefix, start_prefix))
+ else:
+ raise ValueError("path is on drive %s, start on drive %s"
+ % (path_prefix, start_prefix))
+ # Work out how much of the filepath is shared by start and path.
+ i = 0
+ for e1, e2 in zip(start_list, path_list):
+ if e1.lower() != e2.lower():
+ break
+ i += 1
+
+ rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
+ if not rel_list:
+ return curdir
+ return join(*rel_list)
+
+try:
+ # The genericpath.isdir implementation uses os.stat and checks the mode
+ # attribute to tell whether or not the path is a directory.
+ # This is overkill on Windows - just pass the path to GetFileAttributes
+ # and check the attribute from there.
+ from nt import _isdir as isdir
+except ImportError:
+ # Use genericpath.isdir as imported above.
+ pass
diff --git a/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Lib/os.py b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Lib/os.py new file mode 100644 index 0000000000..1a4b73c964 --- /dev/null +++ b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Lib/os.py @@ -0,0 +1,742 @@ +r"""OS routines for NT or Posix depending on what system we're on.
+
+This exports:
+ - all functions from posix, nt, os2, or ce, e.g. unlink, stat, etc.
+ - os.path is one of the modules posixpath, or ntpath
+ - os.name is 'posix', 'nt', 'os2', 'ce' or 'riscos'
+ - os.curdir is a string representing the current directory ('.' or ':')
+ - os.pardir is a string representing the parent directory ('..' or '::')
+ - os.sep is the (or a most common) pathname separator ('/' or ':' or '\\')
+ - os.extsep is the extension separator ('.' or '/')
+ - os.altsep is the alternate pathname separator (None or '/')
+ - os.pathsep is the component separator used in $PATH etc
+ - os.linesep is the line separator in text files ('\r' or '\n' or '\r\n')
+ - os.defpath is the default search path for executables
+ - os.devnull is the file path of the null device ('/dev/null', etc.)
+
+Programs that import and use 'os' stand a better chance of being
+portable between different platforms. Of course, they must then
+only use functions that are defined by all platforms (e.g., unlink
+and opendir), and leave all pathname manipulation to os.path
+(e.g., split and join).
+"""
+
+#'
+
+import sys, errno
+
+_names = sys.builtin_module_names
+
+# Note: more names are added to __all__ later.
+__all__ = ["altsep", "curdir", "pardir", "sep", "extsep", "pathsep", "linesep",
+ "defpath", "name", "path", "devnull",
+ "SEEK_SET", "SEEK_CUR", "SEEK_END"]
+
+def _get_exports_list(module):
+ try:
+ return list(module.__all__)
+ except AttributeError:
+ return [n for n in dir(module) if n[0] != '_']
+
+if 'posix' in _names:
+ name = 'posix'
+ linesep = '\n'
+ from posix import *
+ try:
+ from posix import _exit
+ except ImportError:
+ pass
+ import posixpath as path
+
+ import posix
+ __all__.extend(_get_exports_list(posix))
+ del posix
+
+elif 'nt' in _names:
+ name = 'nt'
+ linesep = '\r\n'
+ from nt import *
+ try:
+ from nt import _exit
+ except ImportError:
+ pass
+ import ntpath as path
+
+ import nt
+ __all__.extend(_get_exports_list(nt))
+ del nt
+
+elif 'os2' in _names:
+ name = 'os2'
+ linesep = '\r\n'
+ from os2 import *
+ try:
+ from os2 import _exit
+ except ImportError:
+ pass
+ if sys.version.find('EMX GCC') == -1:
+ import ntpath as path
+ else:
+ import os2emxpath as path
+ from _emx_link import link
+
+ import os2
+ __all__.extend(_get_exports_list(os2))
+ del os2
+
+elif 'ce' in _names:
+ name = 'ce'
+ linesep = '\r\n'
+ from ce import *
+ try:
+ from ce import _exit
+ except ImportError:
+ pass
+ # We can use the standard Windows path.
+ import ntpath as path
+
+ import ce
+ __all__.extend(_get_exports_list(ce))
+ del ce
+
+elif 'riscos' in _names:
+ name = 'riscos'
+ linesep = '\n'
+ from riscos import *
+ try:
+ from riscos import _exit
+ except ImportError:
+ pass
+ import riscospath as path
+
+ import riscos
+ __all__.extend(_get_exports_list(riscos))
+ del riscos
+
+else:
+ raise ImportError, 'no os specific module found'
+
+sys.modules['os.path'] = path
+from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep,
+ devnull)
+
+del _names
+
+# Python uses fixed values for the SEEK_ constants; they are mapped
+# to native constants if necessary in posixmodule.c
+SEEK_SET = 0
+SEEK_CUR = 1
+SEEK_END = 2
+
+#'
+
+# Super directory utilities.
+# (Inspired by Eric Raymond; the doc strings are mostly his)
+
+def makedirs(name, mode=0777):
+ """makedirs(path [, mode=0777])
+
+ Super-mkdir; create a leaf directory and all intermediate ones.
+ Works like mkdir, except that any intermediate path segment (not
+ just the rightmost) will be created if it does not exist. This is
+ recursive.
+
+ """
+ head, tail = path.split(name)
+ if not tail:
+ head, tail = path.split(head)
+ if head and tail and not path.exists(head):
+ try:
+ makedirs(head, mode)
+ except OSError, e:
+ # be happy if someone already created the path
+ if e.errno != errno.EEXIST:
+ raise
+ if tail == curdir: # xxx/newdir/. exists if xxx/newdir exists
+ return
+ mkdir(name, mode)
+
+def removedirs(name):
+ """removedirs(path)
+
+ Super-rmdir; remove a leaf directory and all empty intermediate
+ ones. Works like rmdir except that, if the leaf directory is
+ successfully removed, directories corresponding to rightmost path
+ segments will be pruned away until either the whole path is
+ consumed or an error occurs. Errors during this latter phase are
+ ignored -- they generally mean that a directory was not empty.
+
+ """
+ rmdir(name)
+ head, tail = path.split(name)
+ if not tail:
+ head, tail = path.split(head)
+ while head and tail:
+ try:
+ rmdir(head)
+ except error:
+ break
+ head, tail = path.split(head)
+
+def renames(old, new):
+ """renames(old, new)
+
+ Super-rename; create directories as necessary and delete any left
+ empty. Works like rename, except creation of any intermediate
+ directories needed to make the new pathname good is attempted
+ first. After the rename, directories corresponding to rightmost
+ path segments of the old name will be pruned until either the
+ whole path is consumed or a nonempty directory is found.
+
+ Note: this function can fail with the new directory structure made
+ if you lack permissions needed to unlink the leaf directory or
+ file.
+
+ """
+ head, tail = path.split(new)
+ if head and tail and not path.exists(head):
+ makedirs(head)
+ rename(old, new)
+ head, tail = path.split(old)
+ if head and tail:
+ try:
+ removedirs(head)
+ except error:
+ pass
+
+__all__.extend(["makedirs", "removedirs", "renames"])
+
+def walk(top, topdown=True, onerror=None, followlinks=False):
+ """Directory tree generator.
+
+ For each directory in the directory tree rooted at top (including top
+ itself, but excluding '.' and '..'), yields a 3-tuple
+
+ dirpath, dirnames, filenames
+
+ dirpath is a string, the path to the directory. dirnames is a list of
+ the names of the subdirectories in dirpath (excluding '.' and '..').
+ filenames is a list of the names of the non-directory files in dirpath.
+ Note that the names in the lists are just names, with no path components.
+ To get a full path (which begins with top) to a file or directory in
+ dirpath, do os.path.join(dirpath, name).
+
+ If optional arg 'topdown' is true or not specified, the triple for a
+ directory is generated before the triples for any of its subdirectories
+ (directories are generated top down). If topdown is false, the triple
+ for a directory is generated after the triples for all of its
+ subdirectories (directories are generated bottom up).
+
+ When topdown is true, the caller can modify the dirnames list in-place
+ (e.g., via del or slice assignment), and walk will only recurse into the
+ subdirectories whose names remain in dirnames; this can be used to prune the
+ search, or to impose a specific order of visiting. Modifying dirnames when
+ topdown is false is ineffective, since the directories in dirnames have
+ already been generated by the time dirnames itself is generated. No matter
+ the value of topdown, the list of subdirectories is retrieved before the
+ tuples for the directory and its subdirectories are generated.
+
+ By default errors from the os.listdir() call are ignored. If
+ optional arg 'onerror' is specified, it should be a function; it
+ will be called with one argument, an os.error instance. It can
+ report the error to continue with the walk, or raise the exception
+ to abort the walk. Note that the filename is available as the
+ filename attribute of the exception object.
+
+ By default, os.walk does not follow symbolic links to subdirectories on
+ systems that support them. In order to get this functionality, set the
+ optional argument 'followlinks' to true.
+
+ Caution: if you pass a relative pathname for top, don't change the
+ current working directory between resumptions of walk. walk never
+ changes the current directory, and assumes that the client doesn't
+ either.
+
+ Example:
+
+ import os
+ from os.path import join, getsize
+ for root, dirs, files in os.walk('python/Lib/email'):
+ print root, "consumes",
+ print sum([getsize(join(root, name)) for name in files]),
+ print "bytes in", len(files), "non-directory files"
+ if 'CVS' in dirs:
+ dirs.remove('CVS') # don't visit CVS directories
+
+ """
+
+ islink, join, isdir = path.islink, path.join, path.isdir
+
+ # We may not have read permission for top, in which case we can't
+ # get a list of the files the directory contains. os.path.walk
+ # always suppressed the exception then, rather than blow up for a
+ # minor reason when (say) a thousand readable directories are still
+ # left to visit. That logic is copied here.
+ try:
+ # Note that listdir and error are globals in this module due
+ # to earlier import-*.
+ names = listdir(top)
+ except error, err:
+ if onerror is not None:
+ onerror(err)
+ return
+
+ dirs, nondirs = [], []
+ for name in names:
+ if isdir(join(top, name)):
+ dirs.append(name)
+ else:
+ nondirs.append(name)
+
+ if topdown:
+ yield top, dirs, nondirs
+ for name in dirs:
+ new_path = join(top, name)
+ if followlinks or not islink(new_path):
+ for x in walk(new_path, topdown, onerror, followlinks):
+ yield x
+ if not topdown:
+ yield top, dirs, nondirs
+
+__all__.append("walk")
+
+# Make sure os.environ exists, at least
+try:
+ environ
+except NameError:
+ environ = {}
+
+def execl(file, *args):
+ """execl(file, *args)
+
+ Execute the executable file with argument list args, replacing the
+ current process. """
+ execv(file, args)
+
+def execle(file, *args):
+ """execle(file, *args, env)
+
+ Execute the executable file with argument list args and
+ environment env, replacing the current process. """
+ env = args[-1]
+ execve(file, args[:-1], env)
+
+def execlp(file, *args):
+ """execlp(file, *args)
+
+ Execute the executable file (which is searched for along $PATH)
+ with argument list args, replacing the current process. """
+ execvp(file, args)
+
+def execlpe(file, *args):
+ """execlpe(file, *args, env)
+
+ Execute the executable file (which is searched for along $PATH)
+ with argument list args and environment env, replacing the current
+ process. """
+ env = args[-1]
+ execvpe(file, args[:-1], env)
+
+def execvp(file, args):
+ """execvp(file, args)
+
+ Execute the executable file (which is searched for along $PATH)
+ with argument list args, replacing the current process.
+ args may be a list or tuple of strings. """
+ _execvpe(file, args)
+
+def execvpe(file, args, env):
+ """execvpe(file, args, env)
+
+ Execute the executable file (which is searched for along $PATH)
+ with argument list args and environment env , replacing the
+ current process.
+ args may be a list or tuple of strings. """
+ _execvpe(file, args, env)
+
+__all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"])
+
+def _execvpe(file, args, env=None):
+ if env is not None:
+ func = execve
+ argrest = (args, env)
+ else:
+ func = execv
+ argrest = (args,)
+ env = environ
+
+ head, tail = path.split(file)
+ if head:
+ func(file, *argrest)
+ return
+ if 'PATH' in env:
+ envpath = env['PATH']
+ else:
+ envpath = defpath
+ PATH = envpath.split(pathsep)
+ saved_exc = None
+ saved_tb = None
+ for dir in PATH:
+ fullname = path.join(dir, file)
+ try:
+ func(fullname, *argrest)
+ except error, e:
+ tb = sys.exc_info()[2]
+ if (e.errno != errno.ENOENT and e.errno != errno.ENOTDIR
+ and saved_exc is None):
+ saved_exc = e
+ saved_tb = tb
+ if saved_exc:
+ raise error, saved_exc, saved_tb
+ raise error, e, tb
+
+# Change environ to automatically call putenv() if it exists
+try:
+ # This will fail if there's no putenv
+ putenv
+except NameError:
+ pass
+else:
+ import UserDict
+
+ # Fake unsetenv() for Windows
+ # not sure about os2 here but
+ # I'm guessing they are the same.
+
+ if name in ('os2', 'nt'):
+ def unsetenv(key):
+ putenv(key, "")
+
+ if name == "riscos":
+ # On RISC OS, all env access goes through getenv and putenv
+ from riscosenviron import _Environ
+ elif name in ('os2', 'nt'): # Where Env Var Names Must Be UPPERCASE
+ # But we store them as upper case
+ class _Environ(UserDict.IterableUserDict):
+ def __init__(self, environ):
+ UserDict.UserDict.__init__(self)
+ data = self.data
+ for k, v in environ.items():
+ data[k.upper()] = v
+ def __setitem__(self, key, item):
+ putenv(key, item)
+ self.data[key.upper()] = item
+ def __getitem__(self, key):
+ return self.data[key.upper()]
+ try:
+ unsetenv
+ except NameError:
+ def __delitem__(self, key):
+ del self.data[key.upper()]
+ else:
+ def __delitem__(self, key):
+ unsetenv(key)
+ del self.data[key.upper()]
+ def clear(self):
+ for key in self.data.keys():
+ unsetenv(key)
+ del self.data[key]
+ def pop(self, key, *args):
+ unsetenv(key)
+ return self.data.pop(key.upper(), *args)
+ def has_key(self, key):
+ return key.upper() in self.data
+ def __contains__(self, key):
+ return key.upper() in self.data
+ def get(self, key, failobj=None):
+ return self.data.get(key.upper(), failobj)
+ def update(self, dict=None, **kwargs):
+ if dict:
+ try:
+ keys = dict.keys()
+ except AttributeError:
+ # List of (key, value)
+ for k, v in dict:
+ self[k] = v
+ else:
+ # got keys
+ # cannot use items(), since mappings
+ # may not have them.
+ for k in keys:
+ self[k] = dict[k]
+ if kwargs:
+ self.update(kwargs)
+ def copy(self):
+ return dict(self)
+
+ else: # Where Env Var Names Can Be Mixed Case
+ class _Environ(UserDict.IterableUserDict):
+ def __init__(self, environ):
+ UserDict.UserDict.__init__(self)
+ self.data = environ
+ def __setitem__(self, key, item):
+ putenv(key, item)
+ self.data[key] = item
+ def update(self, dict=None, **kwargs):
+ if dict:
+ try:
+ keys = dict.keys()
+ except AttributeError:
+ # List of (key, value)
+ for k, v in dict:
+ self[k] = v
+ else:
+ # got keys
+ # cannot use items(), since mappings
+ # may not have them.
+ for k in keys:
+ self[k] = dict[k]
+ if kwargs:
+ self.update(kwargs)
+ try:
+ unsetenv
+ except NameError:
+ pass
+ else:
+ def __delitem__(self, key):
+ unsetenv(key)
+ del self.data[key]
+ def clear(self):
+ for key in self.data.keys():
+ unsetenv(key)
+ del self.data[key]
+ def pop(self, key, *args):
+ unsetenv(key)
+ return self.data.pop(key, *args)
+ def copy(self):
+ return dict(self)
+
+
+ environ = _Environ(environ)
+
+def getenv(key, default=None):
+ """Get an environment variable, return None if it doesn't exist.
+ The optional second argument can specify an alternate default."""
+ return environ.get(key, default)
+__all__.append("getenv")
+
+def _exists(name):
+ return name in globals()
+
+# Supply spawn*() (probably only for Unix)
+if _exists("fork") and not _exists("spawnv") and _exists("execv"):
+
+ P_WAIT = 0
+ P_NOWAIT = P_NOWAITO = 1
+
+ # XXX Should we support P_DETACH? I suppose it could fork()**2
+ # and close the std I/O streams. Also, P_OVERLAY is the same
+ # as execv*()?
+
+ def _spawnvef(mode, file, args, env, func):
+ # Internal helper; func is the exec*() function to use
+ pid = fork()
+ if not pid:
+ # Child
+ try:
+ if env is None:
+ func(file, args)
+ else:
+ func(file, args, env)
+ except:
+ _exit(127)
+ else:
+ # Parent
+ if mode == P_NOWAIT:
+ return pid # Caller is responsible for waiting!
+ while 1:
+ wpid, sts = waitpid(pid, 0)
+ if WIFSTOPPED(sts):
+ continue
+ elif WIFSIGNALED(sts):
+ return -WTERMSIG(sts)
+ elif WIFEXITED(sts):
+ return WEXITSTATUS(sts)
+ else:
+ raise error, "Not stopped, signaled or exited???"
+
+ def spawnv(mode, file, args):
+ """spawnv(mode, file, args) -> integer
+
+Execute file with arguments from args in a subprocess.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+ return _spawnvef(mode, file, args, None, execv)
+
+ def spawnve(mode, file, args, env):
+ """spawnve(mode, file, args, env) -> integer
+
+Execute file with arguments from args in a subprocess with the
+specified environment.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+ return _spawnvef(mode, file, args, env, execve)
+
+ # Note: spawnvp[e] is't currently supported on Windows
+
+ def spawnvp(mode, file, args):
+ """spawnvp(mode, file, args) -> integer
+
+Execute file (which is looked for along $PATH) with arguments from
+args in a subprocess.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+ return _spawnvef(mode, file, args, None, execvp)
+
+ def spawnvpe(mode, file, args, env):
+ """spawnvpe(mode, file, args, env) -> integer
+
+Execute file (which is looked for along $PATH) with arguments from
+args in a subprocess with the supplied environment.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+ return _spawnvef(mode, file, args, env, execvpe)
+
+if _exists("spawnv"):
+ # These aren't supplied by the basic Windows code
+ # but can be easily implemented in Python
+
+ def spawnl(mode, file, *args):
+ """spawnl(mode, file, *args) -> integer
+
+Execute file with arguments from args in a subprocess.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+ return spawnv(mode, file, args)
+
+ def spawnle(mode, file, *args):
+ """spawnle(mode, file, *args, env) -> integer
+
+Execute file with arguments from args in a subprocess with the
+supplied environment.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+ env = args[-1]
+ return spawnve(mode, file, args[:-1], env)
+
+
+ __all__.extend(["spawnv", "spawnve", "spawnl", "spawnle",])
+
+
+if _exists("spawnvp"):
+ # At the moment, Windows doesn't implement spawnvp[e],
+ # so it won't have spawnlp[e] either.
+ def spawnlp(mode, file, *args):
+ """spawnlp(mode, file, *args) -> integer
+
+Execute file (which is looked for along $PATH) with arguments from
+args in a subprocess with the supplied environment.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+ return spawnvp(mode, file, args)
+
+ def spawnlpe(mode, file, *args):
+ """spawnlpe(mode, file, *args, env) -> integer
+
+Execute file (which is looked for along $PATH) with arguments from
+args in a subprocess with the supplied environment.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+ env = args[-1]
+ return spawnvpe(mode, file, args[:-1], env)
+
+
+ __all__.extend(["spawnvp", "spawnvpe", "spawnlp", "spawnlpe",])
+
+
+# Supply popen2 etc. (for Unix)
+if _exists("fork"):
+ if not _exists("popen2"):
+ def popen2(cmd, mode="t", bufsize=-1):
+ """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd'
+ may be a sequence, in which case arguments will be passed directly to
+ the program without shell intervention (as with os.spawnv()). If 'cmd'
+ is a string it will be passed to the shell (as with os.system()). If
+ 'bufsize' is specified, it sets the buffer size for the I/O pipes. The
+ file objects (child_stdin, child_stdout) are returned."""
+ import warnings
+ msg = "os.popen2 is deprecated. Use the subprocess module."
+ warnings.warn(msg, DeprecationWarning, stacklevel=2)
+
+ import subprocess
+ PIPE = subprocess.PIPE
+ p = subprocess.Popen(cmd, shell=isinstance(cmd, basestring),
+ bufsize=bufsize, stdin=PIPE, stdout=PIPE,
+ close_fds=True)
+ return p.stdin, p.stdout
+ __all__.append("popen2")
+
+ if not _exists("popen3"):
+ def popen3(cmd, mode="t", bufsize=-1):
+ """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd'
+ may be a sequence, in which case arguments will be passed directly to
+ the program without shell intervention (as with os.spawnv()). If 'cmd'
+ is a string it will be passed to the shell (as with os.system()). If
+ 'bufsize' is specified, it sets the buffer size for the I/O pipes. The
+ file objects (child_stdin, child_stdout, child_stderr) are returned."""
+ import warnings
+ msg = "os.popen3 is deprecated. Use the subprocess module."
+ warnings.warn(msg, DeprecationWarning, stacklevel=2)
+
+ import subprocess
+ PIPE = subprocess.PIPE
+ p = subprocess.Popen(cmd, shell=isinstance(cmd, basestring),
+ bufsize=bufsize, stdin=PIPE, stdout=PIPE,
+ stderr=PIPE, close_fds=True)
+ return p.stdin, p.stdout, p.stderr
+ __all__.append("popen3")
+
+ if not _exists("popen4"):
+ def popen4(cmd, mode="t", bufsize=-1):
+ """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd'
+ may be a sequence, in which case arguments will be passed directly to
+ the program without shell intervention (as with os.spawnv()). If 'cmd'
+ is a string it will be passed to the shell (as with os.system()). If
+ 'bufsize' is specified, it sets the buffer size for the I/O pipes. The
+ file objects (child_stdin, child_stdout_stderr) are returned."""
+ import warnings
+ msg = "os.popen4 is deprecated. Use the subprocess module."
+ warnings.warn(msg, DeprecationWarning, stacklevel=2)
+
+ import subprocess
+ PIPE = subprocess.PIPE
+ p = subprocess.Popen(cmd, shell=isinstance(cmd, basestring),
+ bufsize=bufsize, stdin=PIPE, stdout=PIPE,
+ stderr=subprocess.STDOUT, close_fds=True)
+ return p.stdin, p.stdout
+ __all__.append("popen4")
+
+import copy_reg as _copy_reg
+
+def _make_stat_result(tup, dict):
+ return stat_result(tup, dict)
+
+def _pickle_stat_result(sr):
+ (type, args) = sr.__reduce__()
+ return (_make_stat_result, args)
+
+try:
+ _copy_reg.pickle(stat_result, _pickle_stat_result, _make_stat_result)
+except NameError: # stat_result may not exist
+ pass
+
+def _make_statvfs_result(tup, dict):
+ return statvfs_result(tup, dict)
+
+def _pickle_statvfs_result(sr):
+ (type, args) = sr.__reduce__()
+ return (_make_statvfs_result, args)
+
+try:
+ _copy_reg.pickle(statvfs_result, _pickle_statvfs_result,
+ _make_statvfs_result)
+except NameError: # statvfs_result may not exist
+ pass
diff --git a/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Lib/pydoc.py b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Lib/pydoc.py new file mode 100644 index 0000000000..06fa7dd893 --- /dev/null +++ b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Lib/pydoc.py @@ -0,0 +1,2406 @@ +#!/usr/bin/env python
+# -*- coding: latin-1 -*-
+"""Generate Python documentation in HTML or text for interactive use.
+
+In the Python interpreter, do "from pydoc import help" to provide online
+help. Calling help(thing) on a Python object documents the object.
+
+Or, at the shell command line outside of Python:
+
+Run "pydoc <name>" to show documentation on something. <name> may be
+the name of a function, module, package, or a dotted reference to a
+class or function within a module or module in a package. If the
+argument contains a path segment delimiter (e.g. slash on Unix,
+backslash on Windows) it is treated as the path to a Python source file.
+
+Run "pydoc -k <keyword>" to search for a keyword in the synopsis lines
+of all available modules.
+
+Run "pydoc -p <port>" to start an HTTP server on a given port on the
+local machine to generate documentation web pages. Port number 0 can be
+used to get an arbitrary unused port.
+
+For platforms without a command line, "pydoc -g" starts the HTTP server
+and also pops up a little window for controlling it.
+
+Run "pydoc -w <name>" to write out the HTML documentation for a module
+to a file named "<name>.html".
+
+Module docs for core modules are assumed to be in
+
+ http://docs.python.org/library/
+
+This can be overridden by setting the PYTHONDOCS environment variable
+to a different URL or to a local directory containing the Library
+Reference Manual pages.
+"""
+
+__author__ = "Ka-Ping Yee <ping@lfw.org>"
+__date__ = "26 February 2001"
+
+__version__ = "$Revision: 88564 $"
+__credits__ = """Guido van Rossum, for an excellent programming language.
+Tommy Burnette, the original creator of manpy.
+Paul Prescod, for all his work on onlinehelp.
+Richard Chamberlain, for the first implementation of textdoc.
+"""
+
+# Known bugs that can't be fixed here:
+# - imp.load_module() cannot be prevented from clobbering existing
+# loaded modules, so calling synopsis() on a binary module file
+# changes the contents of any existing module with the same name.
+# - If the __file__ attribute on a module is a relative path and
+# the current directory is changed with os.chdir(), an incorrect
+# path will be displayed.
+
+import sys, imp, os, re, types, inspect, __builtin__, pkgutil, warnings
+from repr import Repr
+from string import expandtabs, find, join, lower, split, strip, rfind, rstrip
+from traceback import extract_tb
+try:
+ from collections import deque
+except ImportError:
+ # Python 2.3 compatibility
+ class deque(list):
+ def popleft(self):
+ return self.pop(0)
+
+# --------------------------------------------------------- common routines
+
+def pathdirs():
+ """Convert sys.path into a list of absolute, existing, unique paths."""
+ dirs = []
+ normdirs = []
+ for dir in sys.path:
+ dir = os.path.abspath(dir or '.')
+ normdir = os.path.normcase(dir)
+ if normdir not in normdirs and os.path.isdir(dir):
+ dirs.append(dir)
+ normdirs.append(normdir)
+ return dirs
+
+def getdoc(object):
+ """Get the doc string or comments for an object."""
+ result = inspect.getdoc(object) or inspect.getcomments(object)
+ result = _encode(result)
+ return result and re.sub('^ *\n', '', rstrip(result)) or ''
+
+def splitdoc(doc):
+ """Split a doc string into a synopsis line (if any) and the rest."""
+ lines = split(strip(doc), '\n')
+ if len(lines) == 1:
+ return lines[0], ''
+ elif len(lines) >= 2 and not rstrip(lines[1]):
+ return lines[0], join(lines[2:], '\n')
+ return '', join(lines, '\n')
+
+def classname(object, modname):
+ """Get a class name and qualify it with a module name if necessary."""
+ name = object.__name__
+ if object.__module__ != modname:
+ name = object.__module__ + '.' + name
+ return name
+
+def isdata(object):
+ """Check if an object is of a type that probably means it's data."""
+ return not (inspect.ismodule(object) or inspect.isclass(object) or
+ inspect.isroutine(object) or inspect.isframe(object) or
+ inspect.istraceback(object) or inspect.iscode(object))
+
+def replace(text, *pairs):
+ """Do a series of global replacements on a string."""
+ while pairs:
+ text = join(split(text, pairs[0]), pairs[1])
+ pairs = pairs[2:]
+ return text
+
+def cram(text, maxlen):
+ """Omit part of a string if needed to make it fit in a maximum length."""
+ if len(text) > maxlen:
+ pre = max(0, (maxlen-3)//2)
+ post = max(0, maxlen-3-pre)
+ return text[:pre] + '...' + text[len(text)-post:]
+ return text
+
+_re_stripid = re.compile(r' at 0x[0-9a-f]{6,16}(>+)$', re.IGNORECASE)
+def stripid(text):
+ """Remove the hexadecimal id from a Python object representation."""
+ # The behaviour of %p is implementation-dependent in terms of case.
+ return _re_stripid.sub(r'\1', text)
+
+def _is_some_method(obj):
+ return inspect.ismethod(obj) or inspect.ismethoddescriptor(obj)
+
+def allmethods(cl):
+ methods = {}
+ for key, value in inspect.getmembers(cl, _is_some_method):
+ methods[key] = 1
+ for base in cl.__bases__:
+ methods.update(allmethods(base)) # all your base are belong to us
+ for key in methods.keys():
+ methods[key] = getattr(cl, key)
+ return methods
+
+def _split_list(s, predicate):
+ """Split sequence s via predicate, and return pair ([true], [false]).
+
+ The return value is a 2-tuple of lists,
+ ([x for x in s if predicate(x)],
+ [x for x in s if not predicate(x)])
+ """
+
+ yes = []
+ no = []
+ for x in s:
+ if predicate(x):
+ yes.append(x)
+ else:
+ no.append(x)
+ return yes, no
+
+def visiblename(name, all=None, obj=None):
+ """Decide whether to show documentation on a variable."""
+ # Certain special names are redundant.
+ _hidden_names = ('__builtins__', '__doc__', '__file__', '__path__',
+ '__module__', '__name__', '__slots__', '__package__')
+ if name in _hidden_names: return 0
+ # Private names are hidden, but special names are displayed.
+ if name.startswith('__') and name.endswith('__'): return 1
+ # Namedtuples have public fields and methods with a single leading underscore
+ if name.startswith('_') and hasattr(obj, '_fields'):
+ return 1
+ if all is not None:
+ # only document that which the programmer exported in __all__
+ return name in all
+ else:
+ return not name.startswith('_')
+
+def classify_class_attrs(object):
+ """Wrap inspect.classify_class_attrs, with fixup for data descriptors."""
+ def fixup(data):
+ name, kind, cls, value = data
+ if inspect.isdatadescriptor(value):
+ kind = 'data descriptor'
+ return name, kind, cls, value
+ return map(fixup, inspect.classify_class_attrs(object))
+
+# ----------------------------------------------------- Unicode support helpers
+
+try:
+ _unicode = unicode
+except NameError:
+ # If Python is built without Unicode support, the unicode type
+ # will not exist. Fake one that nothing will match, and make
+ # the _encode function that do nothing.
+ class _unicode(object):
+ pass
+ _encoding = 'ascii'
+ def _encode(text, encoding='ascii'):
+ return text
+else:
+ import locale
+ _encoding = locale.getpreferredencoding()
+
+ def _encode(text, encoding=None):
+ if isinstance(text, unicode):
+ return text.encode(encoding or _encoding, 'xmlcharrefreplace')
+ else:
+ return text
+
+def _binstr(obj):
+ # Ensure that we have an encoded (binary) string representation of obj,
+ # even if it is a unicode string.
+ if isinstance(obj, _unicode):
+ return obj.encode(_encoding, 'xmlcharrefreplace')
+ return str(obj)
+
+# ----------------------------------------------------- module manipulation
+
+def ispackage(path):
+ """Guess whether a path refers to a package directory."""
+ if os.path.isdir(path):
+ for ext in ('.py', '.pyc', '.pyo'):
+ if os.path.isfile(os.path.join(path, '__init__' + ext)):
+ return True
+ return False
+
+def source_synopsis(file):
+ line = file.readline()
+ while line[:1] == '#' or not strip(line):
+ line = file.readline()
+ if not line: break
+ line = strip(line)
+ if line[:4] == 'r"""': line = line[1:]
+ if line[:3] == '"""':
+ line = line[3:]
+ if line[-1:] == '\\': line = line[:-1]
+ while not strip(line):
+ line = file.readline()
+ if not line: break
+ result = strip(split(line, '"""')[0])
+ else: result = None
+ return result
+
+def synopsis(filename, cache={}):
+ """Get the one-line summary out of a module file."""
+ mtime = os.stat(filename).st_mtime
+ lastupdate, result = cache.get(filename, (None, None))
+ if lastupdate is None or lastupdate < mtime:
+ info = inspect.getmoduleinfo(filename)
+ try:
+ file = open(filename)
+ except IOError:
+ # module can't be opened, so skip it
+ return None
+ if info and 'b' in info[2]: # binary modules have to be imported
+ try: module = imp.load_module('__temp__', file, filename, info[1:])
+ except: return None
+ result = module.__doc__.splitlines()[0] if module.__doc__ else None
+ del sys.modules['__temp__']
+ else: # text modules can be directly examined
+ result = source_synopsis(file)
+ file.close()
+ cache[filename] = (mtime, result)
+ return result
+
+class ErrorDuringImport(Exception):
+ """Errors that occurred while trying to import something to document it."""
+ def __init__(self, filename, exc_info):
+ exc, value, tb = exc_info
+ self.filename = filename
+ self.exc = exc
+ self.value = value
+ self.tb = tb
+
+ def __str__(self):
+ exc = self.exc
+ if type(exc) is types.ClassType:
+ exc = exc.__name__
+ return 'problem in %s - %s: %s' % (self.filename, exc, self.value)
+
+def importfile(path):
+ """Import a Python source file or compiled file given its path."""
+ magic = imp.get_magic()
+ file = open(path, 'r')
+ if file.read(len(magic)) == magic:
+ kind = imp.PY_COMPILED
+ else:
+ kind = imp.PY_SOURCE
+ file.close()
+ filename = os.path.basename(path)
+ name, ext = os.path.splitext(filename)
+ file = open(path, 'r')
+ try:
+ module = imp.load_module(name, file, path, (ext, 'r', kind))
+ except:
+ raise ErrorDuringImport(path, sys.exc_info())
+ file.close()
+ return module
+
+def safeimport(path, forceload=0, cache={}):
+ """Import a module; handle errors; return None if the module isn't found.
+
+ If the module *is* found but an exception occurs, it's wrapped in an
+ ErrorDuringImport exception and reraised. Unlike __import__, if a
+ package path is specified, the module at the end of the path is returned,
+ not the package at the beginning. If the optional 'forceload' argument
+ is 1, we reload the module from disk (unless it's a dynamic extension)."""
+ try:
+ # If forceload is 1 and the module has been previously loaded from
+ # disk, we always have to reload the module. Checking the file's
+ # mtime isn't good enough (e.g. the module could contain a class
+ # that inherits from another module that has changed).
+ if forceload and path in sys.modules:
+ if path not in sys.builtin_module_names:
+ # Avoid simply calling reload() because it leaves names in
+ # the currently loaded module lying around if they're not
+ # defined in the new source file. Instead, remove the
+ # module from sys.modules and re-import. Also remove any
+ # submodules because they won't appear in the newly loaded
+ # module's namespace if they're already in sys.modules.
+ subs = [m for m in sys.modules if m.startswith(path + '.')]
+ for key in [path] + subs:
+ # Prevent garbage collection.
+ cache[key] = sys.modules[key]
+ del sys.modules[key]
+ module = __import__(path)
+ except:
+ # Did the error occur before or after the module was found?
+ (exc, value, tb) = info = sys.exc_info()
+ if path in sys.modules:
+ # An error occurred while executing the imported module.
+ raise ErrorDuringImport(sys.modules[path].__file__, info)
+ elif exc is SyntaxError:
+ # A SyntaxError occurred before we could execute the module.
+ raise ErrorDuringImport(value.filename, info)
+ elif exc is ImportError and extract_tb(tb)[-1][2]=='safeimport':
+ # The import error occurred directly in this function,
+ # which means there is no such module in the path.
+ return None
+ else:
+ # Some other error occurred during the importing process.
+ raise ErrorDuringImport(path, sys.exc_info())
+ for part in split(path, '.')[1:]:
+ try: module = getattr(module, part)
+ except AttributeError: return None
+ return module
+
+# ---------------------------------------------------- formatter base class
+
+class Doc:
+ def document(self, object, name=None, *args):
+ """Generate documentation for an object."""
+ args = (object, name) + args
+ # 'try' clause is to attempt to handle the possibility that inspect
+ # identifies something in a way that pydoc itself has issues handling;
+ # think 'super' and how it is a descriptor (which raises the exception
+ # by lacking a __name__ attribute) and an instance.
+ if inspect.isgetsetdescriptor(object): return self.docdata(*args)
+ if inspect.ismemberdescriptor(object): return self.docdata(*args)
+ try:
+ if inspect.ismodule(object): return self.docmodule(*args)
+ if inspect.isclass(object): return self.docclass(*args)
+ if inspect.isroutine(object): return self.docroutine(*args)
+ except AttributeError:
+ pass
+ if isinstance(object, property): return self.docproperty(*args)
+ return self.docother(*args)
+
+ def fail(self, object, name=None, *args):
+ """Raise an exception for unimplemented types."""
+ message = "don't know how to document object%s of type %s" % (
+ name and ' ' + repr(name), type(object).__name__)
+ raise TypeError, message
+
+ docmodule = docclass = docroutine = docother = docproperty = docdata = fail
+
+ def getdocloc(self, object):
+ """Return the location of module docs or None"""
+
+ try:
+ file = inspect.getabsfile(object)
+ except TypeError:
+ file = '(built-in)'
+
+ docloc = os.environ.get("PYTHONDOCS",
+ "http://docs.python.org/library")
+ basedir = os.path.join(sys.exec_prefix, "lib",
+ "python"+sys.version[0:3])
+ if (isinstance(object, type(os)) and
+ (object.__name__ in ('errno', 'exceptions', 'gc', 'imp',
+ 'marshal', 'posix', 'signal', 'sys',
+ 'thread', 'zipimport') or
+ (file.startswith(basedir) and
+ not file.startswith(os.path.join(basedir, 'site-packages')))) and
+ object.__name__ not in ('xml.etree', 'test.pydoc_mod')):
+ if docloc.startswith("http://"):
+ docloc = "%s/%s" % (docloc.rstrip("/"), object.__name__)
+ else:
+ docloc = os.path.join(docloc, object.__name__ + ".html")
+ else:
+ docloc = None
+ return docloc
+
+# -------------------------------------------- HTML documentation generator
+
+class HTMLRepr(Repr):
+ """Class for safely making an HTML representation of a Python object."""
+ def __init__(self):
+ Repr.__init__(self)
+ self.maxlist = self.maxtuple = 20
+ self.maxdict = 10
+ self.maxstring = self.maxother = 100
+
+ def escape(self, text):
+ return replace(text, '&', '&', '<', '<', '>', '>')
+
+ def repr(self, object):
+ return Repr.repr(self, object)
+
+ def repr1(self, x, level):
+ if hasattr(type(x), '__name__'):
+ methodname = 'repr_' + join(split(type(x).__name__), '_')
+ if hasattr(self, methodname):
+ return getattr(self, methodname)(x, level)
+ return self.escape(cram(stripid(repr(x)), self.maxother))
+
+ def repr_string(self, x, level):
+ test = cram(x, self.maxstring)
+ testrepr = repr(test)
+ if '\\' in test and '\\' not in replace(testrepr, r'\\', ''):
+ # Backslashes are only literal in the string and are never
+ # needed to make any special characters, so show a raw string.
+ return 'r' + testrepr[0] + self.escape(test) + testrepr[0]
+ return re.sub(r'((\\[\\abfnrtv\'"]|\\[0-9]..|\\x..|\\u....)+)',
+ r'<font color="#c040c0">\1</font>',
+ self.escape(testrepr))
+
+ repr_str = repr_string
+
+ def repr_instance(self, x, level):
+ try:
+ return self.escape(cram(stripid(repr(x)), self.maxstring))
+ except:
+ return self.escape('<%s instance>' % x.__class__.__name__)
+
+ repr_unicode = repr_string
+
+class HTMLDoc(Doc):
+ """Formatter class for HTML documentation."""
+
+ # ------------------------------------------- HTML formatting utilities
+
+ _repr_instance = HTMLRepr()
+ repr = _repr_instance.repr
+ escape = _repr_instance.escape
+
+ def page(self, title, contents):
+ """Format an HTML page."""
+ return _encode('''
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html><head><title>Python: %s</title>
+<meta charset="utf-8">
+</head><body bgcolor="#f0f0f8">
+%s
+</body></html>''' % (title, contents), 'ascii')
+
+ def heading(self, title, fgcol, bgcol, extras=''):
+ """Format a page heading."""
+ return '''
+<table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="heading">
+<tr bgcolor="%s">
+<td valign=bottom> <br>
+<font color="%s" face="helvetica, arial"> <br>%s</font></td
+><td align=right valign=bottom
+><font color="%s" face="helvetica, arial">%s</font></td></tr></table>
+ ''' % (bgcol, fgcol, title, fgcol, extras or ' ')
+
+ def section(self, title, fgcol, bgcol, contents, width=6,
+ prelude='', marginalia=None, gap=' '):
+ """Format a section with a heading."""
+ if marginalia is None:
+ marginalia = '<tt>' + ' ' * width + '</tt>'
+ result = '''<p>
+<table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="%s">
+<td colspan=3 valign=bottom> <br>
+<font color="%s" face="helvetica, arial">%s</font></td></tr>
+ ''' % (bgcol, fgcol, title)
+ if prelude:
+ result = result + '''
+<tr bgcolor="%s"><td rowspan=2>%s</td>
+<td colspan=2>%s</td></tr>
+<tr><td>%s</td>''' % (bgcol, marginalia, prelude, gap)
+ else:
+ result = result + '''
+<tr><td bgcolor="%s">%s</td><td>%s</td>''' % (bgcol, marginalia, gap)
+
+ return result + '\n<td width="100%%">%s</td></tr></table>' % contents
+
+ def bigsection(self, title, *args):
+ """Format a section with a big heading."""
+ title = '<big><strong>%s</strong></big>' % title
+ return self.section(title, *args)
+
+ def preformat(self, text):
+ """Format literal preformatted text."""
+ text = self.escape(expandtabs(text))
+ return replace(text, '\n\n', '\n \n', '\n\n', '\n \n',
+ ' ', ' ', '\n', '<br>\n')
+
+ def multicolumn(self, list, format, cols=4):
+ """Format a list of items into a multi-column list."""
+ result = ''
+ rows = (len(list)+cols-1)//cols
+ for col in range(cols):
+ result = result + '<td width="%d%%" valign=top>' % (100//cols)
+ for i in range(rows*col, rows*col+rows):
+ if i < len(list):
+ result = result + format(list[i]) + '<br>\n'
+ result = result + '</td>'
+ return '<table width="100%%" summary="list"><tr>%s</tr></table>' % result
+
+ def grey(self, text): return '<font color="#909090">%s</font>' % text
+
+ def namelink(self, name, *dicts):
+ """Make a link for an identifier, given name-to-URL mappings."""
+ for dict in dicts:
+ if name in dict:
+ return '<a href="%s">%s</a>' % (dict[name], name)
+ return name
+
+ def classlink(self, object, modname):
+ """Make a link for a class."""
+ name, module = object.__name__, sys.modules.get(object.__module__)
+ if hasattr(module, name) and getattr(module, name) is object:
+ return '<a href="%s.html#%s">%s</a>' % (
+ module.__name__, name, classname(object, modname))
+ return classname(object, modname)
+
+ def modulelink(self, object):
+ """Make a link for a module."""
+ return '<a href="%s.html">%s</a>' % (object.__name__, object.__name__)
+
+ def modpkglink(self, data):
+ """Make a link for a module or package to display in an index."""
+ name, path, ispackage, shadowed = data
+ if shadowed:
+ return self.grey(name)
+ if path:
+ url = '%s.%s.html' % (path, name)
+ else:
+ url = '%s.html' % name
+ if ispackage:
+ text = '<strong>%s</strong> (package)' % name
+ else:
+ text = name
+ return '<a href="%s">%s</a>' % (url, text)
+
+ def markup(self, text, escape=None, funcs={}, classes={}, methods={}):
+ """Mark up some plain text, given a context of symbols to look for.
+ Each context dictionary maps object names to anchor names."""
+ escape = escape or self.escape
+ results = []
+ here = 0
+ pattern = re.compile(r'\b((http|ftp)://\S+[\w/]|'
+ r'RFC[- ]?(\d+)|'
+ r'PEP[- ]?(\d+)|'
+ r'(self\.)?(\w+))')
+ while True:
+ match = pattern.search(text, here)
+ if not match: break
+ start, end = match.span()
+ results.append(escape(text[here:start]))
+
+ all, scheme, rfc, pep, selfdot, name = match.groups()
+ if scheme:
+ url = escape(all).replace('"', '"')
+ results.append('<a href="%s">%s</a>' % (url, url))
+ elif rfc:
+ url = 'http://www.rfc-editor.org/rfc/rfc%d.txt' % int(rfc)
+ results.append('<a href="%s">%s</a>' % (url, escape(all)))
+ elif pep:
+ url = 'http://www.python.org/dev/peps/pep-%04d/' % int(pep)
+ results.append('<a href="%s">%s</a>' % (url, escape(all)))
+ elif selfdot:
+ # Create a link for methods like 'self.method(...)'
+ # and use <strong> for attributes like 'self.attr'
+ if text[end:end+1] == '(':
+ results.append('self.' + self.namelink(name, methods))
+ else:
+ results.append('self.<strong>%s</strong>' % name)
+ elif text[end:end+1] == '(':
+ results.append(self.namelink(name, methods, funcs, classes))
+ else:
+ results.append(self.namelink(name, classes))
+ here = end
+ results.append(escape(text[here:]))
+ return join(results, '')
+
+ # ---------------------------------------------- type-specific routines
+
+ def formattree(self, tree, modname, parent=None):
+ """Produce HTML for a class tree as given by inspect.getclasstree()."""
+ result = ''
+ for entry in tree:
+ if type(entry) is type(()):
+ c, bases = entry
+ result = result + '<dt><font face="helvetica, arial">'
+ result = result + self.classlink(c, modname)
+ if bases and bases != (parent,):
+ parents = []
+ for base in bases:
+ parents.append(self.classlink(base, modname))
+ result = result + '(' + join(parents, ', ') + ')'
+ result = result + '\n</font></dt>'
+ elif type(entry) is type([]):
+ result = result + '<dd>\n%s</dd>\n' % self.formattree(
+ entry, modname, c)
+ return '<dl>\n%s</dl>\n' % result
+
+ def docmodule(self, object, name=None, mod=None, *ignored):
+ """Produce HTML documentation for a module object."""
+ name = object.__name__ # ignore the passed-in name
+ try:
+ all = object.__all__
+ except AttributeError:
+ all = None
+ parts = split(name, '.')
+ links = []
+ for i in range(len(parts)-1):
+ links.append(
+ '<a href="%s.html"><font color="#ffffff">%s</font></a>' %
+ (join(parts[:i+1], '.'), parts[i]))
+ linkedname = join(links + parts[-1:], '.')
+ head = '<big><big><strong>%s</strong></big></big>' % linkedname
+ try:
+ path = inspect.getabsfile(object)
+ url = path
+ if sys.platform == 'win32':
+ import nturl2path
+ url = nturl2path.pathname2url(path)
+ filelink = '<a href="file:%s">%s</a>' % (url, path)
+ except TypeError:
+ filelink = '(built-in)'
+ info = []
+ if hasattr(object, '__version__'):
+ version = _binstr(object.__version__)
+ if version[:11] == '$' + 'Revision: ' and version[-1:] == '$':
+ version = strip(version[11:-1])
+ info.append('version %s' % self.escape(version))
+ if hasattr(object, '__date__'):
+ info.append(self.escape(_binstr(object.__date__)))
+ if info:
+ head = head + ' (%s)' % join(info, ', ')
+ docloc = self.getdocloc(object)
+ if docloc is not None:
+ docloc = '<br><a href="%(docloc)s">Module Docs</a>' % locals()
+ else:
+ docloc = ''
+ result = self.heading(
+ head, '#ffffff', '#7799ee',
+ '<a href=".">index</a><br>' + filelink + docloc)
+
+ modules = inspect.getmembers(object, inspect.ismodule)
+
+ classes, cdict = [], {}
+ for key, value in inspect.getmembers(object, inspect.isclass):
+ # if __all__ exists, believe it. Otherwise use old heuristic.
+ if (all is not None or
+ (inspect.getmodule(value) or object) is object):
+ if visiblename(key, all, object):
+ classes.append((key, value))
+ cdict[key] = cdict[value] = '#' + key
+ for key, value in classes:
+ for base in value.__bases__:
+ key, modname = base.__name__, base.__module__
+ module = sys.modules.get(modname)
+ if modname != name and module and hasattr(module, key):
+ if getattr(module, key) is base:
+ if not key in cdict:
+ cdict[key] = cdict[base] = modname + '.html#' + key
+ funcs, fdict = [], {}
+ for key, value in inspect.getmembers(object, inspect.isroutine):
+ # if __all__ exists, believe it. Otherwise use old heuristic.
+ if (all is not None or
+ inspect.isbuiltin(value) or inspect.getmodule(value) is object):
+ if visiblename(key, all, object):
+ funcs.append((key, value))
+ fdict[key] = '#-' + key
+ if inspect.isfunction(value): fdict[value] = fdict[key]
+ data = []
+ for key, value in inspect.getmembers(object, isdata):
+ if visiblename(key, all, object):
+ data.append((key, value))
+
+ doc = self.markup(getdoc(object), self.preformat, fdict, cdict)
+ doc = doc and '<tt>%s</tt>' % doc
+ result = result + '<p>%s</p>\n' % doc
+
+ if hasattr(object, '__path__'):
+ modpkgs = []
+ for importer, modname, ispkg in pkgutil.iter_modules(object.__path__):
+ modpkgs.append((modname, name, ispkg, 0))
+ modpkgs.sort()
+ contents = self.multicolumn(modpkgs, self.modpkglink)
+ result = result + self.bigsection(
+ 'Package Contents', '#ffffff', '#aa55cc', contents)
+ elif modules:
+ contents = self.multicolumn(
+ modules, lambda key_value, s=self: s.modulelink(key_value[1]))
+ result = result + self.bigsection(
+ 'Modules', '#ffffff', '#aa55cc', contents)
+
+ if classes:
+ classlist = map(lambda key_value: key_value[1], classes)
+ contents = [
+ self.formattree(inspect.getclasstree(classlist, 1), name)]
+ for key, value in classes:
+ contents.append(self.document(value, key, name, fdict, cdict))
+ result = result + self.bigsection(
+ 'Classes', '#ffffff', '#ee77aa', join(contents))
+ if funcs:
+ contents = []
+ for key, value in funcs:
+ contents.append(self.document(value, key, name, fdict, cdict))
+ result = result + self.bigsection(
+ 'Functions', '#ffffff', '#eeaa77', join(contents))
+ if data:
+ contents = []
+ for key, value in data:
+ contents.append(self.document(value, key))
+ result = result + self.bigsection(
+ 'Data', '#ffffff', '#55aa55', join(contents, '<br>\n'))
+ if hasattr(object, '__author__'):
+ contents = self.markup(_binstr(object.__author__), self.preformat)
+ result = result + self.bigsection(
+ 'Author', '#ffffff', '#7799ee', contents)
+ if hasattr(object, '__credits__'):
+ contents = self.markup(_binstr(object.__credits__), self.preformat)
+ result = result + self.bigsection(
+ 'Credits', '#ffffff', '#7799ee', contents)
+
+ return result
+
+ def docclass(self, object, name=None, mod=None, funcs={}, classes={},
+ *ignored):
+ """Produce HTML documentation for a class object."""
+ realname = object.__name__
+ name = name or realname
+ bases = object.__bases__
+
+ contents = []
+ push = contents.append
+
+ # Cute little class to pump out a horizontal rule between sections.
+ class HorizontalRule:
+ def __init__(self):
+ self.needone = 0
+ def maybe(self):
+ if self.needone:
+ push('<hr>\n')
+ self.needone = 1
+ hr = HorizontalRule()
+
+ # List the mro, if non-trivial.
+ mro = deque(inspect.getmro(object))
+ if len(mro) > 2:
+ hr.maybe()
+ push('<dl><dt>Method resolution order:</dt>\n')
+ for base in mro:
+ push('<dd>%s</dd>\n' % self.classlink(base,
+ object.__module__))
+ push('</dl>\n')
+
+ def spill(msg, attrs, predicate):
+ ok, attrs = _split_list(attrs, predicate)
+ if ok:
+ hr.maybe()
+ push(msg)
+ for name, kind, homecls, value in ok:
+ try:
+ value = getattr(object, name)
+ except Exception:
+ # Some descriptors may meet a failure in their __get__.
+ # (bug #1785)
+ push(self._docdescriptor(name, value, mod))
+ else:
+ push(self.document(value, name, mod,
+ funcs, classes, mdict, object))
+ push('\n')
+ return attrs
+
+ def spilldescriptors(msg, attrs, predicate):
+ ok, attrs = _split_list(attrs, predicate)
+ if ok:
+ hr.maybe()
+ push(msg)
+ for name, kind, homecls, value in ok:
+ push(self._docdescriptor(name, value, mod))
+ return attrs
+
+ def spilldata(msg, attrs, predicate):
+ ok, attrs = _split_list(attrs, predicate)
+ if ok:
+ hr.maybe()
+ push(msg)
+ for name, kind, homecls, value in ok:
+ base = self.docother(getattr(object, name), name, mod)
+ if (hasattr(value, '__call__') or
+ inspect.isdatadescriptor(value)):
+ doc = getattr(value, "__doc__", None)
+ else:
+ doc = None
+ if doc is None:
+ push('<dl><dt>%s</dl>\n' % base)
+ else:
+ doc = self.markup(getdoc(value), self.preformat,
+ funcs, classes, mdict)
+ doc = '<dd><tt>%s</tt>' % doc
+ push('<dl><dt>%s%s</dl>\n' % (base, doc))
+ push('\n')
+ return attrs
+
+ attrs = filter(lambda data: visiblename(data[0], obj=object),
+ classify_class_attrs(object))
+ mdict = {}
+ for key, kind, homecls, value in attrs:
+ mdict[key] = anchor = '#' + name + '-' + key
+ try:
+ value = getattr(object, name)
+ except Exception:
+ # Some descriptors may meet a failure in their __get__.
+ # (bug #1785)
+ pass
+ try:
+ # The value may not be hashable (e.g., a data attr with
+ # a dict or list value).
+ mdict[value] = anchor
+ except TypeError:
+ pass
+
+ while attrs:
+ if mro:
+ thisclass = mro.popleft()
+ else:
+ thisclass = attrs[0][2]
+ attrs, inherited = _split_list(attrs, lambda t: t[2] is thisclass)
+
+ if thisclass is __builtin__.object:
+ attrs = inherited
+ continue
+ elif thisclass is object:
+ tag = 'defined here'
+ else:
+ tag = 'inherited from %s' % self.classlink(thisclass,
+ object.__module__)
+ tag += ':<br>\n'
+
+ # Sort attrs by name.
+ try:
+ attrs.sort(key=lambda t: t[0])
+ except TypeError:
+ attrs.sort(lambda t1, t2: cmp(t1[0], t2[0])) # 2.3 compat
+
+ # Pump out the attrs, segregated by kind.
+ attrs = spill('Methods %s' % tag, attrs,
+ lambda t: t[1] == 'method')
+ attrs = spill('Class methods %s' % tag, attrs,
+ lambda t: t[1] == 'class method')
+ attrs = spill('Static methods %s' % tag, attrs,
+ lambda t: t[1] == 'static method')
+ attrs = spilldescriptors('Data descriptors %s' % tag, attrs,
+ lambda t: t[1] == 'data descriptor')
+ attrs = spilldata('Data and other attributes %s' % tag, attrs,
+ lambda t: t[1] == 'data')
+ assert attrs == []
+ attrs = inherited
+
+ contents = ''.join(contents)
+
+ if name == realname:
+ title = '<a name="%s">class <strong>%s</strong></a>' % (
+ name, realname)
+ else:
+ title = '<strong>%s</strong> = <a name="%s">class %s</a>' % (
+ name, name, realname)
+ if bases:
+ parents = []
+ for base in bases:
+ parents.append(self.classlink(base, object.__module__))
+ title = title + '(%s)' % join(parents, ', ')
+ doc = self.markup(getdoc(object), self.preformat, funcs, classes, mdict)
+ doc = doc and '<tt>%s<br> </tt>' % doc
+
+ return self.section(title, '#000000', '#ffc8d8', contents, 3, doc)
+
+ def formatvalue(self, object):
+ """Format an argument default value as text."""
+ return self.grey('=' + self.repr(object))
+
+ def docroutine(self, object, name=None, mod=None,
+ funcs={}, classes={}, methods={}, cl=None):
+ """Produce HTML documentation for a function or method object."""
+ realname = object.__name__
+ name = name or realname
+ anchor = (cl and cl.__name__ or '') + '-' + name
+ note = ''
+ skipdocs = 0
+ if inspect.ismethod(object):
+ imclass = object.im_class
+ if cl:
+ if imclass is not cl:
+ note = ' from ' + self.classlink(imclass, mod)
+ else:
+ if object.im_self is not None:
+ note = ' method of %s instance' % self.classlink(
+ object.im_self.__class__, mod)
+ else:
+ note = ' unbound %s method' % self.classlink(imclass,mod)
+ object = object.im_func
+
+ if name == realname:
+ title = '<a name="%s"><strong>%s</strong></a>' % (anchor, realname)
+ else:
+ if (cl and realname in cl.__dict__ and
+ cl.__dict__[realname] is object):
+ reallink = '<a href="#%s">%s</a>' % (
+ cl.__name__ + '-' + realname, realname)
+ skipdocs = 1
+ else:
+ reallink = realname
+ title = '<a name="%s"><strong>%s</strong></a> = %s' % (
+ anchor, name, reallink)
+ if inspect.isfunction(object):
+ args, varargs, varkw, defaults = inspect.getargspec(object)
+ argspec = inspect.formatargspec(
+ args, varargs, varkw, defaults, formatvalue=self.formatvalue)
+ if realname == '<lambda>':
+ title = '<strong>%s</strong> <em>lambda</em> ' % name
+ argspec = argspec[1:-1] # remove parentheses
+ else:
+ argspec = '(...)'
+
+ decl = title + argspec + (note and self.grey(
+ '<font face="helvetica, arial">%s</font>' % note))
+
+ if skipdocs:
+ return '<dl><dt>%s</dt></dl>\n' % decl
+ else:
+ doc = self.markup(
+ getdoc(object), self.preformat, funcs, classes, methods)
+ doc = doc and '<dd><tt>%s</tt></dd>' % doc
+ return '<dl><dt>%s</dt>%s</dl>\n' % (decl, doc)
+
+ def _docdescriptor(self, name, value, mod):
+ results = []
+ push = results.append
+
+ if name:
+ push('<dl><dt><strong>%s</strong></dt>\n' % name)
+ if value.__doc__ is not None:
+ doc = self.markup(getdoc(value), self.preformat)
+ push('<dd><tt>%s</tt></dd>\n' % doc)
+ push('</dl>\n')
+
+ return ''.join(results)
+
+ def docproperty(self, object, name=None, mod=None, cl=None):
+ """Produce html documentation for a property."""
+ return self._docdescriptor(name, object, mod)
+
+ def docother(self, object, name=None, mod=None, *ignored):
+ """Produce HTML documentation for a data object."""
+ lhs = name and '<strong>%s</strong> = ' % name or ''
+ return lhs + self.repr(object)
+
+ def docdata(self, object, name=None, mod=None, cl=None):
+ """Produce html documentation for a data descriptor."""
+ return self._docdescriptor(name, object, mod)
+
+ def index(self, dir, shadowed=None):
+ """Generate an HTML index for a directory of modules."""
+ modpkgs = []
+ if shadowed is None: shadowed = {}
+ for importer, name, ispkg in pkgutil.iter_modules([dir]):
+ modpkgs.append((name, '', ispkg, name in shadowed))
+ shadowed[name] = 1
+
+ modpkgs.sort()
+ contents = self.multicolumn(modpkgs, self.modpkglink)
+ return self.bigsection(dir, '#ffffff', '#ee77aa', contents)
+
+# -------------------------------------------- text documentation generator
+
+class TextRepr(Repr):
+ """Class for safely making a text representation of a Python object."""
+ def __init__(self):
+ Repr.__init__(self)
+ self.maxlist = self.maxtuple = 20
+ self.maxdict = 10
+ self.maxstring = self.maxother = 100
+
+ def repr1(self, x, level):
+ if hasattr(type(x), '__name__'):
+ methodname = 'repr_' + join(split(type(x).__name__), '_')
+ if hasattr(self, methodname):
+ return getattr(self, methodname)(x, level)
+ return cram(stripid(repr(x)), self.maxother)
+
+ def repr_string(self, x, level):
+ test = cram(x, self.maxstring)
+ testrepr = repr(test)
+ if '\\' in test and '\\' not in replace(testrepr, r'\\', ''):
+ # Backslashes are only literal in the string and are never
+ # needed to make any special characters, so show a raw string.
+ return 'r' + testrepr[0] + test + testrepr[0]
+ return testrepr
+
+ repr_str = repr_string
+
+ def repr_instance(self, x, level):
+ try:
+ return cram(stripid(repr(x)), self.maxstring)
+ except:
+ return '<%s instance>' % x.__class__.__name__
+
+class TextDoc(Doc):
+ """Formatter class for text documentation."""
+
+ # ------------------------------------------- text formatting utilities
+
+ _repr_instance = TextRepr()
+ repr = _repr_instance.repr
+
+ def bold(self, text):
+ """Format a string in bold by overstriking."""
+ return join(map(lambda ch: ch + '\b' + ch, text), '')
+
+ def indent(self, text, prefix=' '):
+ """Indent text by prepending a given prefix to each line."""
+ if not text: return ''
+ lines = split(text, '\n')
+ lines = map(lambda line, prefix=prefix: prefix + line, lines)
+ if lines: lines[-1] = rstrip(lines[-1])
+ return join(lines, '\n')
+
+ def section(self, title, contents):
+ """Format a section with a given heading."""
+ return self.bold(title) + '\n' + rstrip(self.indent(contents)) + '\n\n'
+
+ # ---------------------------------------------- type-specific routines
+
+ def formattree(self, tree, modname, parent=None, prefix=''):
+ """Render in text a class tree as returned by inspect.getclasstree()."""
+ result = ''
+ for entry in tree:
+ if type(entry) is type(()):
+ c, bases = entry
+ result = result + prefix + classname(c, modname)
+ if bases and bases != (parent,):
+ parents = map(lambda c, m=modname: classname(c, m), bases)
+ result = result + '(%s)' % join(parents, ', ')
+ result = result + '\n'
+ elif type(entry) is type([]):
+ result = result + self.formattree(
+ entry, modname, c, prefix + ' ')
+ return result
+
+ def docmodule(self, object, name=None, mod=None):
+ """Produce text documentation for a given module object."""
+ name = object.__name__ # ignore the passed-in name
+ synop, desc = splitdoc(getdoc(object))
+ result = self.section('NAME', name + (synop and ' - ' + synop))
+
+ try:
+ all = object.__all__
+ except AttributeError:
+ all = None
+
+ try:
+ file = inspect.getabsfile(object)
+ except TypeError:
+ file = '(built-in)'
+ result = result + self.section('FILE', file)
+
+ docloc = self.getdocloc(object)
+ if docloc is not None:
+ result = result + self.section('MODULE DOCS', docloc)
+
+ if desc:
+ result = result + self.section('DESCRIPTION', desc)
+
+ classes = []
+ for key, value in inspect.getmembers(object, inspect.isclass):
+ # if __all__ exists, believe it. Otherwise use old heuristic.
+ if (all is not None
+ or (inspect.getmodule(value) or object) is object):
+ if visiblename(key, all, object):
+ classes.append((key, value))
+ funcs = []
+ for key, value in inspect.getmembers(object, inspect.isroutine):
+ # if __all__ exists, believe it. Otherwise use old heuristic.
+ if (all is not None or
+ inspect.isbuiltin(value) or inspect.getmodule(value) is object):
+ if visiblename(key, all, object):
+ funcs.append((key, value))
+ data = []
+ for key, value in inspect.getmembers(object, isdata):
+ if visiblename(key, all, object):
+ data.append((key, value))
+
+ modpkgs = []
+ modpkgs_names = set()
+ if hasattr(object, '__path__'):
+ for importer, modname, ispkg in pkgutil.iter_modules(object.__path__):
+ modpkgs_names.add(modname)
+ if ispkg:
+ modpkgs.append(modname + ' (package)')
+ else:
+ modpkgs.append(modname)
+
+ modpkgs.sort()
+ result = result + self.section(
+ 'PACKAGE CONTENTS', join(modpkgs, '\n'))
+
+ # Detect submodules as sometimes created by C extensions
+ submodules = []
+ for key, value in inspect.getmembers(object, inspect.ismodule):
+ if value.__name__.startswith(name + '.') and key not in modpkgs_names:
+ submodules.append(key)
+ if submodules:
+ submodules.sort()
+ result = result + self.section(
+ 'SUBMODULES', join(submodules, '\n'))
+
+ if classes:
+ classlist = map(lambda key_value: key_value[1], classes)
+ contents = [self.formattree(
+ inspect.getclasstree(classlist, 1), name)]
+ for key, value in classes:
+ contents.append(self.document(value, key, name))
+ result = result + self.section('CLASSES', join(contents, '\n'))
+
+ if funcs:
+ contents = []
+ for key, value in funcs:
+ contents.append(self.document(value, key, name))
+ result = result + self.section('FUNCTIONS', join(contents, '\n'))
+
+ if data:
+ contents = []
+ for key, value in data:
+ contents.append(self.docother(value, key, name, maxlen=70))
+ result = result + self.section('DATA', join(contents, '\n'))
+
+ if hasattr(object, '__version__'):
+ version = _binstr(object.__version__)
+ if version[:11] == '$' + 'Revision: ' and version[-1:] == '$':
+ version = strip(version[11:-1])
+ result = result + self.section('VERSION', version)
+ if hasattr(object, '__date__'):
+ result = result + self.section('DATE', _binstr(object.__date__))
+ if hasattr(object, '__author__'):
+ result = result + self.section('AUTHOR', _binstr(object.__author__))
+ if hasattr(object, '__credits__'):
+ result = result + self.section('CREDITS', _binstr(object.__credits__))
+ return result
+
+ def docclass(self, object, name=None, mod=None, *ignored):
+ """Produce text documentation for a given class object."""
+ realname = object.__name__
+ name = name or realname
+ bases = object.__bases__
+
+ def makename(c, m=object.__module__):
+ return classname(c, m)
+
+ if name == realname:
+ title = 'class ' + self.bold(realname)
+ else:
+ title = self.bold(name) + ' = class ' + realname
+ if bases:
+ parents = map(makename, bases)
+ title = title + '(%s)' % join(parents, ', ')
+
+ doc = getdoc(object)
+ contents = doc and [doc + '\n'] or []
+ push = contents.append
+
+ # List the mro, if non-trivial.
+ mro = deque(inspect.getmro(object))
+ if len(mro) > 2:
+ push("Method resolution order:")
+ for base in mro:
+ push(' ' + makename(base))
+ push('')
+
+ # Cute little class to pump out a horizontal rule between sections.
+ class HorizontalRule:
+ def __init__(self):
+ self.needone = 0
+ def maybe(self):
+ if self.needone:
+ push('-' * 70)
+ self.needone = 1
+ hr = HorizontalRule()
+
+ def spill(msg, attrs, predicate):
+ ok, attrs = _split_list(attrs, predicate)
+ if ok:
+ hr.maybe()
+ push(msg)
+ for name, kind, homecls, value in ok:
+ try:
+ value = getattr(object, name)
+ except Exception:
+ # Some descriptors may meet a failure in their __get__.
+ # (bug #1785)
+ push(self._docdescriptor(name, value, mod))
+ else:
+ push(self.document(value,
+ name, mod, object))
+ return attrs
+
+ def spilldescriptors(msg, attrs, predicate):
+ ok, attrs = _split_list(attrs, predicate)
+ if ok:
+ hr.maybe()
+ push(msg)
+ for name, kind, homecls, value in ok:
+ push(self._docdescriptor(name, value, mod))
+ return attrs
+
+ def spilldata(msg, attrs, predicate):
+ ok, attrs = _split_list(attrs, predicate)
+ if ok:
+ hr.maybe()
+ push(msg)
+ for name, kind, homecls, value in ok:
+ if (hasattr(value, '__call__') or
+ inspect.isdatadescriptor(value)):
+ doc = getdoc(value)
+ else:
+ doc = None
+ push(self.docother(getattr(object, name),
+ name, mod, maxlen=70, doc=doc) + '\n')
+ return attrs
+
+ attrs = filter(lambda data: visiblename(data[0], obj=object),
+ classify_class_attrs(object))
+ while attrs:
+ if mro:
+ thisclass = mro.popleft()
+ else:
+ thisclass = attrs[0][2]
+ attrs, inherited = _split_list(attrs, lambda t: t[2] is thisclass)
+
+ if thisclass is __builtin__.object:
+ attrs = inherited
+ continue
+ elif thisclass is object:
+ tag = "defined here"
+ else:
+ tag = "inherited from %s" % classname(thisclass,
+ object.__module__)
+
+ # Sort attrs by name.
+ attrs.sort()
+
+ # Pump out the attrs, segregated by kind.
+ attrs = spill("Methods %s:\n" % tag, attrs,
+ lambda t: t[1] == 'method')
+ attrs = spill("Class methods %s:\n" % tag, attrs,
+ lambda t: t[1] == 'class method')
+ attrs = spill("Static methods %s:\n" % tag, attrs,
+ lambda t: t[1] == 'static method')
+ attrs = spilldescriptors("Data descriptors %s:\n" % tag, attrs,
+ lambda t: t[1] == 'data descriptor')
+ attrs = spilldata("Data and other attributes %s:\n" % tag, attrs,
+ lambda t: t[1] == 'data')
+ assert attrs == []
+ attrs = inherited
+
+ contents = '\n'.join(contents)
+ if not contents:
+ return title + '\n'
+ return title + '\n' + self.indent(rstrip(contents), ' | ') + '\n'
+
+ def formatvalue(self, object):
+ """Format an argument default value as text."""
+ return '=' + self.repr(object)
+
+ def docroutine(self, object, name=None, mod=None, cl=None):
+ """Produce text documentation for a function or method object."""
+ realname = object.__name__
+ name = name or realname
+ note = ''
+ skipdocs = 0
+ if inspect.ismethod(object):
+ imclass = object.im_class
+ if cl:
+ if imclass is not cl:
+ note = ' from ' + classname(imclass, mod)
+ else:
+ if object.im_self is not None:
+ note = ' method of %s instance' % classname(
+ object.im_self.__class__, mod)
+ else:
+ note = ' unbound %s method' % classname(imclass,mod)
+ object = object.im_func
+
+ if name == realname:
+ title = self.bold(realname)
+ else:
+ if (cl and realname in cl.__dict__ and
+ cl.__dict__[realname] is object):
+ skipdocs = 1
+ title = self.bold(name) + ' = ' + realname
+ if inspect.isfunction(object):
+ args, varargs, varkw, defaults = inspect.getargspec(object)
+ argspec = inspect.formatargspec(
+ args, varargs, varkw, defaults, formatvalue=self.formatvalue)
+ if realname == '<lambda>':
+ title = self.bold(name) + ' lambda '
+ argspec = argspec[1:-1] # remove parentheses
+ else:
+ argspec = '(...)'
+ decl = title + argspec + note
+
+ if skipdocs:
+ return decl + '\n'
+ else:
+ doc = getdoc(object) or ''
+ return decl + '\n' + (doc and rstrip(self.indent(doc)) + '\n')
+
+ def _docdescriptor(self, name, value, mod):
+ results = []
+ push = results.append
+
+ if name:
+ push(self.bold(name))
+ push('\n')
+ doc = getdoc(value) or ''
+ if doc:
+ push(self.indent(doc))
+ push('\n')
+ return ''.join(results)
+
+ def docproperty(self, object, name=None, mod=None, cl=None):
+ """Produce text documentation for a property."""
+ return self._docdescriptor(name, object, mod)
+
+ def docdata(self, object, name=None, mod=None, cl=None):
+ """Produce text documentation for a data descriptor."""
+ return self._docdescriptor(name, object, mod)
+
+ def docother(self, object, name=None, mod=None, parent=None, maxlen=None, doc=None):
+ """Produce text documentation for a data object."""
+ repr = self.repr(object)
+ if maxlen:
+ line = (name and name + ' = ' or '') + repr
+ chop = maxlen - len(line)
+ if chop < 0: repr = repr[:chop] + '...'
+ line = (name and self.bold(name) + ' = ' or '') + repr
+ if doc is not None:
+ line += '\n' + self.indent(str(doc))
+ return line
+
+# --------------------------------------------------------- user interfaces
+
+def pager(text):
+ """The first time this is called, determine what kind of pager to use."""
+ global pager
+ pager = getpager()
+ pager(text)
+
+def getpager():
+ """Decide what method to use for paging through text."""
+ if type(sys.stdout) is not types.FileType:
+ return plainpager
+ if not hasattr(sys.stdin, "isatty"):
+ return plainpager
+ if not sys.stdin.isatty() or not sys.stdout.isatty():
+ return plainpager
+ if 'PAGER' in os.environ:
+ if sys.platform == 'win32': # pipes completely broken in Windows
+ return lambda text: tempfilepager(plain(text), os.environ['PAGER'])
+ elif os.environ.get('TERM') in ('dumb', 'emacs'):
+ return lambda text: pipepager(plain(text), os.environ['PAGER'])
+ else:
+ return lambda text: pipepager(text, os.environ['PAGER'])
+ if os.environ.get('TERM') in ('dumb', 'emacs'):
+ return plainpager
+ if sys.platform == 'win32' or sys.platform.startswith('os2'):
+ return lambda text: tempfilepager(plain(text), 'more <')
+ if hasattr(os, 'system') and os.system('(less) 2>/dev/null') == 0:
+ return lambda text: pipepager(text, 'less')
+
+ import tempfile
+ (fd, filename) = tempfile.mkstemp()
+ os.close(fd)
+ try:
+ if hasattr(os, 'system') and os.system('more "%s"' % filename) == 0:
+ return lambda text: pipepager(text, 'more')
+ else:
+ return ttypager
+ finally:
+ os.unlink(filename)
+
+def plain(text):
+ """Remove boldface formatting from text."""
+ return re.sub('.\b', '', text)
+
+def pipepager(text, cmd):
+ """Page through text by feeding it to another program."""
+ pipe = os.popen(cmd, 'w')
+ try:
+ pipe.write(_encode(text))
+ pipe.close()
+ except IOError:
+ pass # Ignore broken pipes caused by quitting the pager program.
+
+def tempfilepager(text, cmd):
+ """Page through text by invoking a program on a temporary file."""
+ import tempfile
+ filename = tempfile.mktemp()
+ file = open(filename, 'w')
+ file.write(_encode(text))
+ file.close()
+ try:
+ os.system(cmd + ' "' + filename + '"')
+ finally:
+ os.unlink(filename)
+
+def ttypager(text):
+ """Page through text on a text terminal."""
+ lines = plain(_encode(plain(text), getattr(sys.stdout, 'encoding', _encoding))).split('\n')
+ try:
+ import tty
+ fd = sys.stdin.fileno()
+ old = tty.tcgetattr(fd)
+ tty.setcbreak(fd)
+ getchar = lambda: sys.stdin.read(1)
+ except (ImportError, AttributeError):
+ tty = None
+ getchar = lambda: sys.stdin.readline()[:-1][:1]
+
+ try:
+ try:
+ h = int(os.environ.get('LINES', 0))
+ except ValueError:
+ h = 0
+ if h <= 1:
+ h = 25
+ r = inc = h - 1
+ sys.stdout.write(join(lines[:inc], '\n') + '\n')
+ while lines[r:]:
+ sys.stdout.write('-- more --')
+ sys.stdout.flush()
+ c = getchar()
+
+ if c in ('q', 'Q'):
+ sys.stdout.write('\r \r')
+ break
+ elif c in ('\r', '\n'):
+ sys.stdout.write('\r \r' + lines[r] + '\n')
+ r = r + 1
+ continue
+ if c in ('b', 'B', '\x1b'):
+ r = r - inc - inc
+ if r < 0: r = 0
+ sys.stdout.write('\n' + join(lines[r:r+inc], '\n') + '\n')
+ r = r + inc
+
+ finally:
+ if tty:
+ tty.tcsetattr(fd, tty.TCSAFLUSH, old)
+
+def plainpager(text):
+ """Simply print unformatted text. This is the ultimate fallback."""
+ sys.stdout.write(_encode(plain(text), getattr(sys.stdout, 'encoding', _encoding)))
+
+def describe(thing):
+ """Produce a short description of the given thing."""
+ if inspect.ismodule(thing):
+ if thing.__name__ in sys.builtin_module_names:
+ return 'built-in module ' + thing.__name__
+ if hasattr(thing, '__path__'):
+ return 'package ' + thing.__name__
+ else:
+ return 'module ' + thing.__name__
+ if inspect.isbuiltin(thing):
+ return 'built-in function ' + thing.__name__
+ if inspect.isgetsetdescriptor(thing):
+ return 'getset descriptor %s.%s.%s' % (
+ thing.__objclass__.__module__, thing.__objclass__.__name__,
+ thing.__name__)
+ if inspect.ismemberdescriptor(thing):
+ return 'member descriptor %s.%s.%s' % (
+ thing.__objclass__.__module__, thing.__objclass__.__name__,
+ thing.__name__)
+ if inspect.isclass(thing):
+ return 'class ' + thing.__name__
+ if inspect.isfunction(thing):
+ return 'function ' + thing.__name__
+ if inspect.ismethod(thing):
+ return 'method ' + thing.__name__
+ if type(thing) is types.InstanceType:
+ return 'instance of ' + thing.__class__.__name__
+ return type(thing).__name__
+
+def locate(path, forceload=0):
+ """Locate an object by name or dotted path, importing as necessary."""
+ parts = [part for part in split(path, '.') if part]
+ module, n = None, 0
+ while n < len(parts):
+ nextmodule = safeimport(join(parts[:n+1], '.'), forceload)
+ if nextmodule: module, n = nextmodule, n + 1
+ else: break
+ if module:
+ object = module
+ else:
+ object = __builtin__
+ for part in parts[n:]:
+ try:
+ object = getattr(object, part)
+ except AttributeError:
+ return None
+ return object
+
+# --------------------------------------- interactive interpreter interface
+
+text = TextDoc()
+html = HTMLDoc()
+
+class _OldStyleClass: pass
+_OLD_INSTANCE_TYPE = type(_OldStyleClass())
+
+def resolve(thing, forceload=0):
+ """Given an object or a path to an object, get the object and its name."""
+ if isinstance(thing, str):
+ object = locate(thing, forceload)
+ if object is None:
+ raise ImportError, 'no Python documentation found for %r' % thing
+ return object, thing
+ else:
+ name = getattr(thing, '__name__', None)
+ return thing, name if isinstance(name, str) else None
+
+def render_doc(thing, title='Python Library Documentation: %s', forceload=0):
+ """Render text documentation, given an object or a path to an object."""
+ object, name = resolve(thing, forceload)
+ desc = describe(object)
+ module = inspect.getmodule(object)
+ if name and '.' in name:
+ desc += ' in ' + name[:name.rfind('.')]
+ elif module and module is not object:
+ desc += ' in module ' + module.__name__
+ if type(object) is _OLD_INSTANCE_TYPE:
+ # If the passed object is an instance of an old-style class,
+ # document its available methods instead of its value.
+ object = object.__class__
+ elif not (inspect.ismodule(object) or
+ inspect.isclass(object) or
+ inspect.isroutine(object) or
+ inspect.isgetsetdescriptor(object) or
+ inspect.ismemberdescriptor(object) or
+ isinstance(object, property)):
+ # If the passed object is a piece of data or an instance,
+ # document its available methods instead of its value.
+ object = type(object)
+ desc += ' object'
+ return title % desc + '\n\n' + text.document(object, name)
+
+def doc(thing, title='Python Library Documentation: %s', forceload=0):
+ """Display text documentation, given an object or a path to an object."""
+ try:
+ pager(render_doc(thing, title, forceload))
+ except (ImportError, ErrorDuringImport), value:
+ print value
+
+def writedoc(thing, forceload=0):
+ """Write HTML documentation to a file in the current directory."""
+ try:
+ object, name = resolve(thing, forceload)
+ page = html.page(describe(object), html.document(object, name))
+ file = open(name + '.html', 'w')
+ file.write(page)
+ file.close()
+ print 'wrote', name + '.html'
+ except (ImportError, ErrorDuringImport), value:
+ print value
+
+def writedocs(dir, pkgpath='', done=None):
+ """Write out HTML documentation for all modules in a directory tree."""
+ if done is None: done = {}
+ for importer, modname, ispkg in pkgutil.walk_packages([dir], pkgpath):
+ writedoc(modname)
+ return
+
+class Helper:
+
+ # These dictionaries map a topic name to either an alias, or a tuple
+ # (label, seealso-items). The "label" is the label of the corresponding
+ # section in the .rst file under Doc/ and an index into the dictionary
+ # in pydoc_data/topics.py.
+ #
+ # CAUTION: if you change one of these dictionaries, be sure to adapt the
+ # list of needed labels in Doc/tools/pyspecific.py and
+ # regenerate the pydoc_data/topics.py file by running
+ # make pydoc-topics
+ # in Doc/ and copying the output file into the Lib/ directory.
+
+ keywords = {
+ 'and': 'BOOLEAN',
+ 'as': 'with',
+ 'assert': ('assert', ''),
+ 'break': ('break', 'while for'),
+ 'class': ('class', 'CLASSES SPECIALMETHODS'),
+ 'continue': ('continue', 'while for'),
+ 'def': ('function', ''),
+ 'del': ('del', 'BASICMETHODS'),
+ 'elif': 'if',
+ 'else': ('else', 'while for'),
+ 'except': 'try',
+ 'exec': ('exec', ''),
+ 'finally': 'try',
+ 'for': ('for', 'break continue while'),
+ 'from': 'import',
+ 'global': ('global', 'NAMESPACES'),
+ 'if': ('if', 'TRUTHVALUE'),
+ 'import': ('import', 'MODULES'),
+ 'in': ('in', 'SEQUENCEMETHODS2'),
+ 'is': 'COMPARISON',
+ 'lambda': ('lambda', 'FUNCTIONS'),
+ 'not': 'BOOLEAN',
+ 'or': 'BOOLEAN',
+ 'pass': ('pass', ''),
+ 'print': ('print', ''),
+ 'raise': ('raise', 'EXCEPTIONS'),
+ 'return': ('return', 'FUNCTIONS'),
+ 'try': ('try', 'EXCEPTIONS'),
+ 'while': ('while', 'break continue if TRUTHVALUE'),
+ 'with': ('with', 'CONTEXTMANAGERS EXCEPTIONS yield'),
+ 'yield': ('yield', ''),
+ }
+ # Either add symbols to this dictionary or to the symbols dictionary
+ # directly: Whichever is easier. They are merged later.
+ _symbols_inverse = {
+ 'STRINGS' : ("'", "'''", "r'", "u'", '"""', '"', 'r"', 'u"'),
+ 'OPERATORS' : ('+', '-', '*', '**', '/', '//', '%', '<<', '>>', '&',
+ '|', '^', '~', '<', '>', '<=', '>=', '==', '!=', '<>'),
+ 'COMPARISON' : ('<', '>', '<=', '>=', '==', '!=', '<>'),
+ 'UNARY' : ('-', '~'),
+ 'AUGMENTEDASSIGNMENT' : ('+=', '-=', '*=', '/=', '%=', '&=', '|=',
+ '^=', '<<=', '>>=', '**=', '//='),
+ 'BITWISE' : ('<<', '>>', '&', '|', '^', '~'),
+ 'COMPLEX' : ('j', 'J')
+ }
+ symbols = {
+ '%': 'OPERATORS FORMATTING',
+ '**': 'POWER',
+ ',': 'TUPLES LISTS FUNCTIONS',
+ '.': 'ATTRIBUTES FLOAT MODULES OBJECTS',
+ '...': 'ELLIPSIS',
+ ':': 'SLICINGS DICTIONARYLITERALS',
+ '@': 'def class',
+ '\\': 'STRINGS',
+ '_': 'PRIVATENAMES',
+ '__': 'PRIVATENAMES SPECIALMETHODS',
+ '`': 'BACKQUOTES',
+ '(': 'TUPLES FUNCTIONS CALLS',
+ ')': 'TUPLES FUNCTIONS CALLS',
+ '[': 'LISTS SUBSCRIPTS SLICINGS',
+ ']': 'LISTS SUBSCRIPTS SLICINGS'
+ }
+ for topic, symbols_ in _symbols_inverse.iteritems():
+ for symbol in symbols_:
+ topics = symbols.get(symbol, topic)
+ if topic not in topics:
+ topics = topics + ' ' + topic
+ symbols[symbol] = topics
+
+ topics = {
+ 'TYPES': ('types', 'STRINGS UNICODE NUMBERS SEQUENCES MAPPINGS '
+ 'FUNCTIONS CLASSES MODULES FILES inspect'),
+ 'STRINGS': ('strings', 'str UNICODE SEQUENCES STRINGMETHODS FORMATTING '
+ 'TYPES'),
+ 'STRINGMETHODS': ('string-methods', 'STRINGS FORMATTING'),
+ 'FORMATTING': ('formatstrings', 'OPERATORS'),
+ 'UNICODE': ('strings', 'encodings unicode SEQUENCES STRINGMETHODS '
+ 'FORMATTING TYPES'),
+ 'NUMBERS': ('numbers', 'INTEGER FLOAT COMPLEX TYPES'),
+ 'INTEGER': ('integers', 'int range'),
+ 'FLOAT': ('floating', 'float math'),
+ 'COMPLEX': ('imaginary', 'complex cmath'),
+ 'SEQUENCES': ('typesseq', 'STRINGMETHODS FORMATTING xrange LISTS'),
+ 'MAPPINGS': 'DICTIONARIES',
+ 'FUNCTIONS': ('typesfunctions', 'def TYPES'),
+ 'METHODS': ('typesmethods', 'class def CLASSES TYPES'),
+ 'CODEOBJECTS': ('bltin-code-objects', 'compile FUNCTIONS TYPES'),
+ 'TYPEOBJECTS': ('bltin-type-objects', 'types TYPES'),
+ 'FRAMEOBJECTS': 'TYPES',
+ 'TRACEBACKS': 'TYPES',
+ 'NONE': ('bltin-null-object', ''),
+ 'ELLIPSIS': ('bltin-ellipsis-object', 'SLICINGS'),
+ 'FILES': ('bltin-file-objects', ''),
+ 'SPECIALATTRIBUTES': ('specialattrs', ''),
+ 'CLASSES': ('types', 'class SPECIALMETHODS PRIVATENAMES'),
+ 'MODULES': ('typesmodules', 'import'),
+ 'PACKAGES': 'import',
+ 'EXPRESSIONS': ('operator-summary', 'lambda or and not in is BOOLEAN '
+ 'COMPARISON BITWISE SHIFTING BINARY FORMATTING POWER '
+ 'UNARY ATTRIBUTES SUBSCRIPTS SLICINGS CALLS TUPLES '
+ 'LISTS DICTIONARIES BACKQUOTES'),
+ 'OPERATORS': 'EXPRESSIONS',
+ 'PRECEDENCE': 'EXPRESSIONS',
+ 'OBJECTS': ('objects', 'TYPES'),
+ 'SPECIALMETHODS': ('specialnames', 'BASICMETHODS ATTRIBUTEMETHODS '
+ 'CALLABLEMETHODS SEQUENCEMETHODS1 MAPPINGMETHODS '
+ 'SEQUENCEMETHODS2 NUMBERMETHODS CLASSES'),
+ 'BASICMETHODS': ('customization', 'cmp hash repr str SPECIALMETHODS'),
+ 'ATTRIBUTEMETHODS': ('attribute-access', 'ATTRIBUTES SPECIALMETHODS'),
+ 'CALLABLEMETHODS': ('callable-types', 'CALLS SPECIALMETHODS'),
+ 'SEQUENCEMETHODS1': ('sequence-types', 'SEQUENCES SEQUENCEMETHODS2 '
+ 'SPECIALMETHODS'),
+ 'SEQUENCEMETHODS2': ('sequence-methods', 'SEQUENCES SEQUENCEMETHODS1 '
+ 'SPECIALMETHODS'),
+ 'MAPPINGMETHODS': ('sequence-types', 'MAPPINGS SPECIALMETHODS'),
+ 'NUMBERMETHODS': ('numeric-types', 'NUMBERS AUGMENTEDASSIGNMENT '
+ 'SPECIALMETHODS'),
+ 'EXECUTION': ('execmodel', 'NAMESPACES DYNAMICFEATURES EXCEPTIONS'),
+ 'NAMESPACES': ('naming', 'global ASSIGNMENT DELETION DYNAMICFEATURES'),
+ 'DYNAMICFEATURES': ('dynamic-features', ''),
+ 'SCOPING': 'NAMESPACES',
+ 'FRAMES': 'NAMESPACES',
+ 'EXCEPTIONS': ('exceptions', 'try except finally raise'),
+ 'COERCIONS': ('coercion-rules','CONVERSIONS'),
+ 'CONVERSIONS': ('conversions', 'COERCIONS'),
+ 'IDENTIFIERS': ('identifiers', 'keywords SPECIALIDENTIFIERS'),
+ 'SPECIALIDENTIFIERS': ('id-classes', ''),
+ 'PRIVATENAMES': ('atom-identifiers', ''),
+ 'LITERALS': ('atom-literals', 'STRINGS BACKQUOTES NUMBERS '
+ 'TUPLELITERALS LISTLITERALS DICTIONARYLITERALS'),
+ 'TUPLES': 'SEQUENCES',
+ 'TUPLELITERALS': ('exprlists', 'TUPLES LITERALS'),
+ 'LISTS': ('typesseq-mutable', 'LISTLITERALS'),
+ 'LISTLITERALS': ('lists', 'LISTS LITERALS'),
+ 'DICTIONARIES': ('typesmapping', 'DICTIONARYLITERALS'),
+ 'DICTIONARYLITERALS': ('dict', 'DICTIONARIES LITERALS'),
+ 'BACKQUOTES': ('string-conversions', 'repr str STRINGS LITERALS'),
+ 'ATTRIBUTES': ('attribute-references', 'getattr hasattr setattr '
+ 'ATTRIBUTEMETHODS'),
+ 'SUBSCRIPTS': ('subscriptions', 'SEQUENCEMETHODS1'),
+ 'SLICINGS': ('slicings', 'SEQUENCEMETHODS2'),
+ 'CALLS': ('calls', 'EXPRESSIONS'),
+ 'POWER': ('power', 'EXPRESSIONS'),
+ 'UNARY': ('unary', 'EXPRESSIONS'),
+ 'BINARY': ('binary', 'EXPRESSIONS'),
+ 'SHIFTING': ('shifting', 'EXPRESSIONS'),
+ 'BITWISE': ('bitwise', 'EXPRESSIONS'),
+ 'COMPARISON': ('comparisons', 'EXPRESSIONS BASICMETHODS'),
+ 'BOOLEAN': ('booleans', 'EXPRESSIONS TRUTHVALUE'),
+ 'ASSERTION': 'assert',
+ 'ASSIGNMENT': ('assignment', 'AUGMENTEDASSIGNMENT'),
+ 'AUGMENTEDASSIGNMENT': ('augassign', 'NUMBERMETHODS'),
+ 'DELETION': 'del',
+ 'PRINTING': 'print',
+ 'RETURNING': 'return',
+ 'IMPORTING': 'import',
+ 'CONDITIONAL': 'if',
+ 'LOOPING': ('compound', 'for while break continue'),
+ 'TRUTHVALUE': ('truth', 'if while and or not BASICMETHODS'),
+ 'DEBUGGING': ('debugger', 'pdb'),
+ 'CONTEXTMANAGERS': ('context-managers', 'with'),
+ }
+
+ def __init__(self, input=None, output=None):
+ self._input = input
+ self._output = output
+
+ input = property(lambda self: self._input or sys.stdin)
+ output = property(lambda self: self._output or sys.stdout)
+
+ def __repr__(self):
+ if inspect.stack()[1][3] == '?':
+ self()
+ return ''
+ return '<pydoc.Helper instance>'
+
+ _GoInteractive = object()
+ def __call__(self, request=_GoInteractive):
+ if request is not self._GoInteractive:
+ self.help(request)
+ else:
+ self.intro()
+ self.interact()
+ self.output.write('''
+You are now leaving help and returning to the Python interpreter.
+If you want to ask for help on a particular object directly from the
+interpreter, you can type "help(object)". Executing "help('string')"
+has the same effect as typing a particular string at the help> prompt.
+''')
+
+ def interact(self):
+ self.output.write('\n')
+ while True:
+ try:
+ request = self.getline('help> ')
+ if not request: break
+ except (KeyboardInterrupt, EOFError):
+ break
+ request = strip(replace(request, '"', '', "'", ''))
+ if lower(request) in ('q', 'quit'): break
+ self.help(request)
+
+ def getline(self, prompt):
+ """Read one line, using raw_input when available."""
+ if self.input is sys.stdin:
+ return raw_input(prompt)
+ else:
+ self.output.write(prompt)
+ self.output.flush()
+ return self.input.readline()
+
+ def help(self, request):
+ if type(request) is type(''):
+ request = request.strip()
+ if request == 'help': self.intro()
+ elif request == 'keywords': self.listkeywords()
+ elif request == 'symbols': self.listsymbols()
+ elif request == 'topics': self.listtopics()
+ elif request == 'modules': self.listmodules()
+ elif request[:8] == 'modules ':
+ self.listmodules(split(request)[1])
+ elif request in self.symbols: self.showsymbol(request)
+ elif request in self.keywords: self.showtopic(request)
+ elif request in self.topics: self.showtopic(request)
+ elif request: doc(request, 'Help on %s:')
+ elif isinstance(request, Helper): self()
+ else: doc(request, 'Help on %s:')
+ self.output.write('\n')
+
+ def intro(self):
+ self.output.write('''
+Welcome to Python %s! This is the online help utility.
+
+If this is your first time using Python, you should definitely check out
+the tutorial on the Internet at http://docs.python.org/%s/tutorial/.
+
+Enter the name of any module, keyword, or topic to get help on writing
+Python programs and using Python modules. To quit this help utility and
+return to the interpreter, just type "quit".
+
+To get a list of available modules, keywords, or topics, type "modules",
+"keywords", or "topics". Each module also comes with a one-line summary
+of what it does; to list the modules whose summaries contain a given word
+such as "spam", type "modules spam".
+''' % tuple([sys.version[:3]]*2))
+
+ def list(self, items, columns=4, width=80):
+ items = items[:]
+ items.sort()
+ colw = width / columns
+ rows = (len(items) + columns - 1) / columns
+ for row in range(rows):
+ for col in range(columns):
+ i = col * rows + row
+ if i < len(items):
+ self.output.write(items[i])
+ if col < columns - 1:
+ self.output.write(' ' + ' ' * (colw-1 - len(items[i])))
+ self.output.write('\n')
+
+ def listkeywords(self):
+ self.output.write('''
+Here is a list of the Python keywords. Enter any keyword to get more help.
+
+''')
+ self.list(self.keywords.keys())
+
+ def listsymbols(self):
+ self.output.write('''
+Here is a list of the punctuation symbols which Python assigns special meaning
+to. Enter any symbol to get more help.
+
+''')
+ self.list(self.symbols.keys())
+
+ def listtopics(self):
+ self.output.write('''
+Here is a list of available topics. Enter any topic name to get more help.
+
+''')
+ self.list(self.topics.keys())
+
+ def showtopic(self, topic, more_xrefs=''):
+ try:
+ import pydoc_data.topics
+ except ImportError:
+ self.output.write('''
+Sorry, topic and keyword documentation is not available because the
+module "pydoc_data.topics" could not be found.
+''')
+ return
+ target = self.topics.get(topic, self.keywords.get(topic))
+ if not target:
+ self.output.write('no documentation found for %s\n' % repr(topic))
+ return
+ if type(target) is type(''):
+ return self.showtopic(target, more_xrefs)
+
+ label, xrefs = target
+ try:
+ doc = pydoc_data.topics.topics[label]
+ except KeyError:
+ self.output.write('no documentation found for %s\n' % repr(topic))
+ return
+ pager(strip(doc) + '\n')
+ if more_xrefs:
+ xrefs = (xrefs or '') + ' ' + more_xrefs
+ if xrefs:
+ import StringIO, formatter
+ buffer = StringIO.StringIO()
+ formatter.DumbWriter(buffer).send_flowing_data(
+ 'Related help topics: ' + join(split(xrefs), ', ') + '\n')
+ self.output.write('\n%s\n' % buffer.getvalue())
+
+ def showsymbol(self, symbol):
+ target = self.symbols[symbol]
+ topic, _, xrefs = target.partition(' ')
+ self.showtopic(topic, xrefs)
+
+ def listmodules(self, key=''):
+ if key:
+ self.output.write('''
+Here is a list of matching modules. Enter any module name to get more help.
+
+''')
+ apropos(key)
+ else:
+ self.output.write('''
+Please wait a moment while I gather a list of all available modules...
+
+''')
+ modules = {}
+ def callback(path, modname, desc, modules=modules):
+ if modname and modname[-9:] == '.__init__':
+ modname = modname[:-9] + ' (package)'
+ if find(modname, '.') < 0:
+ modules[modname] = 1
+ def onerror(modname):
+ callback(None, modname, None)
+ ModuleScanner().run(callback, onerror=onerror)
+ self.list(modules.keys())
+ self.output.write('''
+Enter any module name to get more help. Or, type "modules spam" to search
+for modules whose descriptions contain the word "spam".
+''')
+
+help = Helper()
+
+class Scanner:
+ """A generic tree iterator."""
+ def __init__(self, roots, children, descendp):
+ self.roots = roots[:]
+ self.state = []
+ self.children = children
+ self.descendp = descendp
+
+ def next(self):
+ if not self.state:
+ if not self.roots:
+ return None
+ root = self.roots.pop(0)
+ self.state = [(root, self.children(root))]
+ node, children = self.state[-1]
+ if not children:
+ self.state.pop()
+ return self.next()
+ child = children.pop(0)
+ if self.descendp(child):
+ self.state.append((child, self.children(child)))
+ return child
+
+
+class ModuleScanner:
+ """An interruptible scanner that searches module synopses."""
+
+ def run(self, callback, key=None, completer=None, onerror=None):
+ if key: key = lower(key)
+ self.quit = False
+ seen = {}
+
+ for modname in sys.builtin_module_names:
+ if modname != '__main__':
+ seen[modname] = 1
+ if key is None:
+ callback(None, modname, '')
+ else:
+ desc = split(__import__(modname).__doc__ or '', '\n')[0]
+ if find(lower(modname + ' - ' + desc), key) >= 0:
+ callback(None, modname, desc)
+
+ for importer, modname, ispkg in pkgutil.walk_packages(onerror=onerror):
+ if self.quit:
+ break
+ if key is None:
+ callback(None, modname, '')
+ else:
+ loader = importer.find_module(modname)
+ if hasattr(loader,'get_source'):
+ import StringIO
+ desc = source_synopsis(
+ StringIO.StringIO(loader.get_source(modname))
+ ) or ''
+ if hasattr(loader,'get_filename'):
+ path = loader.get_filename(modname)
+ else:
+ path = None
+ else:
+ module = loader.load_module(modname)
+ desc = module.__doc__.splitlines()[0] if module.__doc__ else ''
+ path = getattr(module,'__file__',None)
+ if find(lower(modname + ' - ' + desc), key) >= 0:
+ callback(path, modname, desc)
+
+ if completer:
+ completer()
+
+def apropos(key):
+ """Print all the one-line module summaries that contain a substring."""
+ def callback(path, modname, desc):
+ if modname[-9:] == '.__init__':
+ modname = modname[:-9] + ' (package)'
+ print modname, desc and '- ' + desc
+ def onerror(modname):
+ pass
+ with warnings.catch_warnings():
+ warnings.filterwarnings('ignore') # ignore problems during import
+ ModuleScanner().run(callback, key, onerror=onerror)
+
+# --------------------------------------------------- web browser interface
+
+def serve(port, callback=None, completer=None):
+ import BaseHTTPServer, mimetools, select
+
+ # Patch up mimetools.Message so it doesn't break if rfc822 is reloaded.
+ class Message(mimetools.Message):
+ def __init__(self, fp, seekable=1):
+ Message = self.__class__
+ Message.__bases__[0].__bases__[0].__init__(self, fp, seekable)
+ self.encodingheader = self.getheader('content-transfer-encoding')
+ self.typeheader = self.getheader('content-type')
+ self.parsetype()
+ self.parseplist()
+
+ class DocHandler(BaseHTTPServer.BaseHTTPRequestHandler):
+ def send_document(self, title, contents):
+ try:
+ self.send_response(200)
+ self.send_header('Content-Type', 'text/html')
+ self.end_headers()
+ self.wfile.write(html.page(title, contents))
+ except IOError: pass
+
+ def do_GET(self):
+ path = self.path
+ if path[-5:] == '.html': path = path[:-5]
+ if path[:1] == '/': path = path[1:]
+ if path and path != '.':
+ try:
+ obj = locate(path, forceload=1)
+ except ErrorDuringImport, value:
+ self.send_document(path, html.escape(str(value)))
+ return
+ if obj:
+ self.send_document(describe(obj), html.document(obj, path))
+ else:
+ self.send_document(path,
+'no Python documentation found for %s' % repr(path))
+ else:
+ heading = html.heading(
+'<big><big><strong>Python: Index of Modules</strong></big></big>',
+'#ffffff', '#7799ee')
+ def bltinlink(name):
+ return '<a href="%s.html">%s</a>' % (name, name)
+ names = filter(lambda x: x != '__main__',
+ sys.builtin_module_names)
+ contents = html.multicolumn(names, bltinlink)
+ indices = ['<p>' + html.bigsection(
+ 'Built-in Modules', '#ffffff', '#ee77aa', contents)]
+
+ seen = {}
+ for dir in sys.path:
+ indices.append(html.index(dir, seen))
+ contents = heading + join(indices) + '''<p align=right>
+<font color="#909090" face="helvetica, arial"><strong>
+pydoc</strong> by Ka-Ping Yee <ping@lfw.org></font>'''
+ self.send_document('Index of Modules', contents)
+
+ def log_message(self, *args): pass
+
+ class DocServer(BaseHTTPServer.HTTPServer):
+ def __init__(self, port, callback):
+ host = 'localhost'
+ self.address = (host, port)
+ self.callback = callback
+ self.base.__init__(self, self.address, self.handler)
+
+ def serve_until_quit(self):
+ import select
+ self.quit = False
+ while not self.quit:
+ rd, wr, ex = select.select([self.socket.fileno()], [], [], 1)
+ if rd: self.handle_request()
+
+ def server_activate(self):
+ self.base.server_activate(self)
+ self.url = 'http://%s:%d/' % (self.address[0], self.server_port)
+ if self.callback: self.callback(self)
+
+ DocServer.base = BaseHTTPServer.HTTPServer
+ DocServer.handler = DocHandler
+ DocHandler.MessageClass = Message
+ try:
+ try:
+ DocServer(port, callback).serve_until_quit()
+ except (KeyboardInterrupt, select.error):
+ pass
+ finally:
+ if completer: completer()
+
+# ----------------------------------------------------- graphical interface
+
+def gui():
+ """Graphical interface (starts web server and pops up a control window)."""
+ class GUI:
+ def __init__(self, window, port=7464):
+ self.window = window
+ self.server = None
+ self.scanner = None
+
+ import Tkinter
+ self.server_frm = Tkinter.Frame(window)
+ self.title_lbl = Tkinter.Label(self.server_frm,
+ text='Starting server...\n ')
+ self.open_btn = Tkinter.Button(self.server_frm,
+ text='open browser', command=self.open, state='disabled')
+ self.quit_btn = Tkinter.Button(self.server_frm,
+ text='quit serving', command=self.quit, state='disabled')
+
+ self.search_frm = Tkinter.Frame(window)
+ self.search_lbl = Tkinter.Label(self.search_frm, text='Search for')
+ self.search_ent = Tkinter.Entry(self.search_frm)
+ self.search_ent.bind('<Return>', self.search)
+ self.stop_btn = Tkinter.Button(self.search_frm,
+ text='stop', pady=0, command=self.stop, state='disabled')
+ if sys.platform == 'win32':
+ # Trying to hide and show this button crashes under Windows.
+ self.stop_btn.pack(side='right')
+
+ self.window.title('pydoc')
+ self.window.protocol('WM_DELETE_WINDOW', self.quit)
+ self.title_lbl.pack(side='top', fill='x')
+ self.open_btn.pack(side='left', fill='x', expand=1)
+ self.quit_btn.pack(side='right', fill='x', expand=1)
+ self.server_frm.pack(side='top', fill='x')
+
+ self.search_lbl.pack(side='left')
+ self.search_ent.pack(side='right', fill='x', expand=1)
+ self.search_frm.pack(side='top', fill='x')
+ self.search_ent.focus_set()
+
+ font = ('helvetica', sys.platform == 'win32' and 8 or 10)
+ self.result_lst = Tkinter.Listbox(window, font=font, height=6)
+ self.result_lst.bind('<Button-1>', self.select)
+ self.result_lst.bind('<Double-Button-1>', self.goto)
+ self.result_scr = Tkinter.Scrollbar(window,
+ orient='vertical', command=self.result_lst.yview)
+ self.result_lst.config(yscrollcommand=self.result_scr.set)
+
+ self.result_frm = Tkinter.Frame(window)
+ self.goto_btn = Tkinter.Button(self.result_frm,
+ text='go to selected', command=self.goto)
+ self.hide_btn = Tkinter.Button(self.result_frm,
+ text='hide results', command=self.hide)
+ self.goto_btn.pack(side='left', fill='x', expand=1)
+ self.hide_btn.pack(side='right', fill='x', expand=1)
+
+ self.window.update()
+ self.minwidth = self.window.winfo_width()
+ self.minheight = self.window.winfo_height()
+ self.bigminheight = (self.server_frm.winfo_reqheight() +
+ self.search_frm.winfo_reqheight() +
+ self.result_lst.winfo_reqheight() +
+ self.result_frm.winfo_reqheight())
+ self.bigwidth, self.bigheight = self.minwidth, self.bigminheight
+ self.expanded = 0
+ self.window.wm_geometry('%dx%d' % (self.minwidth, self.minheight))
+ self.window.wm_minsize(self.minwidth, self.minheight)
+ self.window.tk.willdispatch()
+
+ import threading
+ threading.Thread(
+ target=serve, args=(port, self.ready, self.quit)).start()
+
+ def ready(self, server):
+ self.server = server
+ self.title_lbl.config(
+ text='Python documentation server at\n' + server.url)
+ self.open_btn.config(state='normal')
+ self.quit_btn.config(state='normal')
+
+ def open(self, event=None, url=None):
+ url = url or self.server.url
+ try:
+ import webbrowser
+ webbrowser.open(url)
+ except ImportError: # pre-webbrowser.py compatibility
+ if sys.platform == 'win32':
+ os.system('start "%s"' % url)
+ else:
+ rc = os.system('netscape -remote "openURL(%s)" &' % url)
+ if rc: os.system('netscape "%s" &' % url)
+
+ def quit(self, event=None):
+ if self.server:
+ self.server.quit = 1
+ self.window.quit()
+
+ def search(self, event=None):
+ key = self.search_ent.get()
+ self.stop_btn.pack(side='right')
+ self.stop_btn.config(state='normal')
+ self.search_lbl.config(text='Searching for "%s"...' % key)
+ self.search_ent.forget()
+ self.search_lbl.pack(side='left')
+ self.result_lst.delete(0, 'end')
+ self.goto_btn.config(state='disabled')
+ self.expand()
+
+ import threading
+ if self.scanner:
+ self.scanner.quit = 1
+ self.scanner = ModuleScanner()
+ threading.Thread(target=self.scanner.run,
+ args=(self.update, key, self.done)).start()
+
+ def update(self, path, modname, desc):
+ if modname[-9:] == '.__init__':
+ modname = modname[:-9] + ' (package)'
+ self.result_lst.insert('end',
+ modname + ' - ' + (desc or '(no description)'))
+
+ def stop(self, event=None):
+ if self.scanner:
+ self.scanner.quit = 1
+ self.scanner = None
+
+ def done(self):
+ self.scanner = None
+ self.search_lbl.config(text='Search for')
+ self.search_lbl.pack(side='left')
+ self.search_ent.pack(side='right', fill='x', expand=1)
+ if sys.platform != 'win32': self.stop_btn.forget()
+ self.stop_btn.config(state='disabled')
+
+ def select(self, event=None):
+ self.goto_btn.config(state='normal')
+
+ def goto(self, event=None):
+ selection = self.result_lst.curselection()
+ if selection:
+ modname = split(self.result_lst.get(selection[0]))[0]
+ self.open(url=self.server.url + modname + '.html')
+
+ def collapse(self):
+ if not self.expanded: return
+ self.result_frm.forget()
+ self.result_scr.forget()
+ self.result_lst.forget()
+ self.bigwidth = self.window.winfo_width()
+ self.bigheight = self.window.winfo_height()
+ self.window.wm_geometry('%dx%d' % (self.minwidth, self.minheight))
+ self.window.wm_minsize(self.minwidth, self.minheight)
+ self.expanded = 0
+
+ def expand(self):
+ if self.expanded: return
+ self.result_frm.pack(side='bottom', fill='x')
+ self.result_scr.pack(side='right', fill='y')
+ self.result_lst.pack(side='top', fill='both', expand=1)
+ self.window.wm_geometry('%dx%d' % (self.bigwidth, self.bigheight))
+ self.window.wm_minsize(self.minwidth, self.bigminheight)
+ self.expanded = 1
+
+ def hide(self, event=None):
+ self.stop()
+ self.collapse()
+
+ import Tkinter
+ try:
+ root = Tkinter.Tk()
+ # Tk will crash if pythonw.exe has an XP .manifest
+ # file and the root has is not destroyed explicitly.
+ # If the problem is ever fixed in Tk, the explicit
+ # destroy can go.
+ try:
+ gui = GUI(root)
+ root.mainloop()
+ finally:
+ root.destroy()
+ except KeyboardInterrupt:
+ pass
+
+# -------------------------------------------------- command-line interface
+
+def ispath(x):
+ return isinstance(x, str) and find(x, os.sep) >= 0
+
+def cli():
+ """Command-line interface (looks at sys.argv to decide what to do)."""
+ import getopt
+ class BadUsage: pass
+
+ # Scripts don't get the current directory in their path by default
+ # unless they are run with the '-m' switch
+ if '' not in sys.path:
+ scriptdir = os.path.dirname(sys.argv[0])
+ if scriptdir in sys.path:
+ sys.path.remove(scriptdir)
+ sys.path.insert(0, '.')
+
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], 'gk:p:w')
+ writing = 0
+
+ for opt, val in opts:
+ if opt == '-g':
+ gui()
+ return
+ if opt == '-k':
+ apropos(val)
+ return
+ if opt == '-p':
+ try:
+ port = int(val)
+ except ValueError:
+ raise BadUsage
+ def ready(server):
+ print 'pydoc server ready at %s' % server.url
+ def stopped():
+ print 'pydoc server stopped'
+ serve(port, ready, stopped)
+ return
+ if opt == '-w':
+ writing = 1
+
+ if not args: raise BadUsage
+ for arg in args:
+ if ispath(arg) and not os.path.exists(arg):
+ print 'file %r does not exist' % arg
+ break
+ try:
+ if ispath(arg) and os.path.isfile(arg):
+ arg = importfile(arg)
+ if writing:
+ if ispath(arg) and os.path.isdir(arg):
+ writedocs(arg)
+ else:
+ writedoc(arg)
+ else:
+ help.help(arg)
+ except ErrorDuringImport, value:
+ print value
+
+ except (getopt.error, BadUsage):
+ cmd = os.path.basename(sys.argv[0])
+ print """pydoc - the Python documentation tool
+
+%s <name> ...
+ Show text documentation on something. <name> may be the name of a
+ Python keyword, topic, function, module, or package, or a dotted
+ reference to a class or function within a module or module in a
+ package. If <name> contains a '%s', it is used as the path to a
+ Python source file to document. If name is 'keywords', 'topics',
+ or 'modules', a listing of these things is displayed.
+
+%s -k <keyword>
+ Search for a keyword in the synopsis lines of all available modules.
+
+%s -p <port>
+ Start an HTTP server on the given port on the local machine. Port
+ number 0 can be used to get an arbitrary unused port.
+
+%s -g
+ Pop up a graphical interface for finding and serving documentation.
+
+%s -w <name> ...
+ Write out the HTML documentation for a module to a file in the current
+ directory. If <name> contains a '%s', it is treated as a filename; if
+ it names a directory, documentation is written for all the contents.
+""" % (cmd, os.sep, cmd, cmd, cmd, cmd, os.sep)
+
+if __name__ == '__main__': cli()
diff --git a/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Lib/site.py b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Lib/site.py new file mode 100644 index 0000000000..ce60d4944a --- /dev/null +++ b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Lib/site.py @@ -0,0 +1,600 @@ +"""Append module search paths for third-party packages to sys.path.
+
+****************************************************************
+* This module is automatically imported during initialization. *
+****************************************************************
+
+In earlier versions of Python (up to 1.5a3), scripts or modules that
+needed to use site-specific modules would place ``import site''
+somewhere near the top of their code. Because of the automatic
+import, this is no longer necessary (but code that does it still
+works).
+
+This will append site-specific paths to the module search path. On
+Unix (including Mac OSX), it starts with sys.prefix and
+sys.exec_prefix (if different) and appends
+lib/python<version>/site-packages as well as lib/site-python.
+On other platforms (such as Windows), it tries each of the
+prefixes directly, as well as with lib/site-packages appended. The
+resulting directories, if they exist, are appended to sys.path, and
+also inspected for path configuration files.
+
+A path configuration file is a file whose name has the form
+<package>.pth; its contents are additional directories (one per line)
+to be added to sys.path. Non-existing directories (or
+non-directories) are never added to sys.path; no directory is added to
+sys.path more than once. Blank lines and lines beginning with
+'#' are skipped. Lines starting with 'import' are executed.
+
+For example, suppose sys.prefix and sys.exec_prefix are set to
+/usr/local and there is a directory /usr/local/lib/python2.5/site-packages
+with three subdirectories, foo, bar and spam, and two path
+configuration files, foo.pth and bar.pth. Assume foo.pth contains the
+following:
+
+ # foo package configuration
+ foo
+ bar
+ bletch
+
+and bar.pth contains:
+
+ # bar package configuration
+ bar
+
+Then the following directories are added to sys.path, in this order:
+
+ /usr/local/lib/python2.5/site-packages/bar
+ /usr/local/lib/python2.5/site-packages/foo
+
+Note that bletch is omitted because it doesn't exist; bar precedes foo
+because bar.pth comes alphabetically before foo.pth; and spam is
+omitted because it is not mentioned in either path configuration file.
+
+After these path manipulations, an attempt is made to import a module
+named sitecustomize, which can perform arbitrary additional
+site-specific customizations. If this import fails with an
+ImportError exception, it is silently ignored.
+
+"""
+
+import sys
+import os
+import __builtin__
+import traceback
+
+# Prefixes for site-packages; add additional prefixes like /usr/local here
+PREFIXES = [sys.prefix, sys.exec_prefix]
+# Enable per user site-packages directory
+# set it to False to disable the feature or True to force the feature
+ENABLE_USER_SITE = None
+
+# for distutils.commands.install
+# These values are initialized by the getuserbase() and getusersitepackages()
+# functions, through the main() function when Python starts.
+USER_SITE = None
+USER_BASE = None
+
+
+def makepath(*paths):
+ dir = os.path.join(*paths)
+ try:
+ dir = os.path.abspath(dir)
+ except OSError:
+ pass
+ return dir, os.path.normcase(dir)
+
+
+def abs__file__():
+ """Set all module' __file__ attribute to an absolute path"""
+ for m in sys.modules.values():
+ if hasattr(m, '__loader__'):
+ continue # don't mess with a PEP 302-supplied __file__
+ try:
+ m.__file__ = os.path.abspath(m.__file__)
+ except (AttributeError, OSError):
+ pass
+
+
+def removeduppaths():
+ """ Remove duplicate entries from sys.path along with making them
+ absolute"""
+ # This ensures that the initial path provided by the interpreter contains
+ # only absolute pathnames, even if we're running from the build directory.
+ L = []
+ known_paths = set()
+ for dir in sys.path:
+ # Filter out duplicate paths (on case-insensitive file systems also
+ # if they only differ in case); turn relative paths into absolute
+ # paths.
+ dir, dircase = makepath(dir)
+ if not dircase in known_paths:
+ L.append(dir)
+ known_paths.add(dircase)
+ sys.path[:] = L
+ return known_paths
+
+
+def _init_pathinfo():
+ """Return a set containing all existing directory entries from sys.path"""
+ d = set()
+ for dir in sys.path:
+ try:
+ if os.path.isdir(dir):
+ dir, dircase = makepath(dir)
+ d.add(dircase)
+ except TypeError:
+ continue
+ return d
+
+
+def addpackage(sitedir, name, known_paths):
+ """Process a .pth file within the site-packages directory:
+ For each line in the file, either combine it with sitedir to a path
+ and add that to known_paths, or execute it if it starts with 'import '.
+ """
+ if known_paths is None:
+ _init_pathinfo()
+ reset = 1
+ else:
+ reset = 0
+ fullname = os.path.join(sitedir, name)
+ try:
+ f = open(fullname, "rU")
+ except IOError:
+ return
+ with f:
+ for n, line in enumerate(f):
+ if line.startswith("#"):
+ continue
+ try:
+ if line.startswith(("import ", "import\t")):
+ exec line
+ continue
+ line = line.rstrip()
+ dir, dircase = makepath(sitedir, line)
+ if not dircase in known_paths and os.path.exists(dir):
+ sys.path.append(dir)
+ known_paths.add(dircase)
+ except Exception as err:
+ print >>sys.stderr, "Error processing line {:d} of {}:\n".format(
+ n+1, fullname)
+ for record in traceback.format_exception(*sys.exc_info()):
+ for line in record.splitlines():
+ print >>sys.stderr, ' '+line
+ print >>sys.stderr, "\nRemainder of file ignored"
+ break
+ if reset:
+ known_paths = None
+ return known_paths
+
+
+def addsitedir(sitedir, known_paths=None):
+ """Add 'sitedir' argument to sys.path if missing and handle .pth files in
+ 'sitedir'"""
+ if known_paths is None:
+ known_paths = _init_pathinfo()
+ reset = 1
+ else:
+ reset = 0
+ sitedir, sitedircase = makepath(sitedir)
+ if not sitedircase in known_paths:
+ sys.path.append(sitedir) # Add path component
+ try:
+ names = os.listdir(sitedir)
+ except os.error:
+ return
+ dotpth = os.extsep + "pth"
+ names = [name for name in names if name.endswith(dotpth)]
+ for name in sorted(names):
+ addpackage(sitedir, name, known_paths)
+ if reset:
+ known_paths = None
+ return known_paths
+
+
+def check_enableusersite():
+ """Check if user site directory is safe for inclusion
+
+ The function tests for the command line flag (including environment var),
+ process uid/gid equal to effective uid/gid.
+
+ None: Disabled for security reasons
+ False: Disabled by user (command line option)
+ True: Safe and enabled
+ """
+ if sys.flags.no_user_site:
+ return False
+
+ if hasattr(os, "getuid") and hasattr(os, "geteuid"):
+ # check process uid == effective uid
+ if os.geteuid() != os.getuid():
+ return None
+ if hasattr(os, "getgid") and hasattr(os, "getegid"):
+ # check process gid == effective gid
+ if os.getegid() != os.getgid():
+ return None
+
+ return True
+
+def getuserbase():
+ """Returns the `user base` directory path.
+
+ The `user base` directory can be used to store data. If the global
+ variable ``USER_BASE`` is not initialized yet, this function will also set
+ it.
+ """
+ global USER_BASE
+ if USER_BASE is not None:
+ return USER_BASE
+ from sysconfig import get_config_var
+ USER_BASE = get_config_var('userbase')
+ return USER_BASE
+
+def getusersitepackages():
+ """Returns the user-specific site-packages directory path.
+
+ If the global variable ``USER_SITE`` is not initialized yet, this
+ function will also set it.
+ """
+ global USER_SITE
+ user_base = getuserbase() # this will also set USER_BASE
+
+ if USER_SITE is not None:
+ return USER_SITE
+
+ from sysconfig import get_path
+ import os
+
+ if sys.platform == 'darwin':
+ from sysconfig import get_config_var
+ if get_config_var('PYTHONFRAMEWORK'):
+ USER_SITE = get_path('purelib', 'osx_framework_user')
+ return USER_SITE
+
+ USER_SITE = get_path('purelib', '%s_user' % os.name)
+ return USER_SITE
+
+def addusersitepackages(known_paths):
+ """Add a per user site-package to sys.path
+
+ Each user has its own python directory with site-packages in the
+ home directory.
+ """
+ # get the per user site-package path
+ # this call will also make sure USER_BASE and USER_SITE are set
+ user_site = getusersitepackages()
+
+ if ENABLE_USER_SITE and os.path.isdir(user_site):
+ addsitedir(user_site, known_paths)
+ return known_paths
+
+def getsitepackages():
+ """Returns a list containing all global site-packages directories
+ (and possibly site-python).
+
+ For each directory present in the global ``PREFIXES``, this function
+ will find its `site-packages` subdirectory depending on the system
+ environment, and will return a list of full paths.
+ """
+ sitepackages = []
+ seen = set()
+
+ for prefix in PREFIXES:
+ if not prefix or prefix in seen:
+ continue
+ seen.add(prefix)
+
+ if sys.platform in ('os2emx', 'riscos'):
+ sitepackages.append(os.path.join(prefix, "Lib", "site-packages"))
+ elif os.sep == '/':
+ sitepackages.append(os.path.join(prefix, "lib",
+ "python" + sys.version[:3],
+ "site-packages"))
+ sitepackages.append(os.path.join(prefix, "lib", "site-python"))
+ else:
+ sitepackages.append(prefix)
+ sitepackages.append(os.path.join(prefix, "lib", "site-packages"))
+ if sys.platform == "darwin":
+ # for framework builds *only* we add the standard Apple
+ # locations.
+ from sysconfig import get_config_var
+ framework = get_config_var("PYTHONFRAMEWORK")
+ if framework:
+ sitepackages.append(
+ os.path.join("/Library", framework,
+ sys.version[:3], "site-packages"))
+ return sitepackages
+
+def addsitepackages(known_paths):
+ """Add site-packages (and possibly site-python) to sys.path"""
+ for sitedir in getsitepackages():
+ if os.path.isdir(sitedir):
+ addsitedir(sitedir, known_paths)
+
+ return known_paths
+
+def setBEGINLIBPATH():
+ """The OS/2 EMX port has optional extension modules that do double duty
+ as DLLs (and must use the .DLL file extension) for other extensions.
+ The library search path needs to be amended so these will be found
+ during module import. Use BEGINLIBPATH so that these are at the start
+ of the library search path.
+
+ """
+ dllpath = os.path.join(sys.prefix, "Lib", "lib-dynload")
+ libpath = os.environ['BEGINLIBPATH'].split(';')
+ if libpath[-1]:
+ libpath.append(dllpath)
+ else:
+ libpath[-1] = dllpath
+ os.environ['BEGINLIBPATH'] = ';'.join(libpath)
+
+
+def setquit():
+ """Define new builtins 'quit' and 'exit'.
+
+ These are objects which make the interpreter exit when called.
+ The repr of each object contains a hint at how it works.
+
+ """
+ if os.sep == ':':
+ eof = 'Cmd-Q'
+ elif os.sep == '\\':
+ eof = 'Ctrl-Z plus Return'
+ else:
+ eof = 'Ctrl-D (i.e. EOF)'
+
+ class Quitter(object):
+ def __init__(self, name):
+ self.name = name
+ def __repr__(self):
+ return 'Use %s() or %s to exit' % (self.name, eof)
+ def __call__(self, code=None):
+ # Shells like IDLE catch the SystemExit, but listen when their
+ # stdin wrapper is closed.
+ try:
+ sys.stdin.close()
+ except:
+ pass
+ raise SystemExit(code)
+ __builtin__.quit = Quitter('quit')
+ __builtin__.exit = Quitter('exit')
+
+
+class _Printer(object):
+ """interactive prompt objects for printing the license text, a list of
+ contributors and the copyright notice."""
+
+ MAXLINES = 23
+
+ def __init__(self, name, data, files=(), dirs=()):
+ self.__name = name
+ self.__data = data
+ self.__files = files
+ self.__dirs = dirs
+ self.__lines = None
+
+ def __setup(self):
+ if self.__lines:
+ return
+ data = None
+ for dir in self.__dirs:
+ for filename in self.__files:
+ filename = os.path.join(dir, filename)
+ try:
+ fp = file(filename, "rU")
+ data = fp.read()
+ fp.close()
+ break
+ except IOError:
+ pass
+ if data:
+ break
+ if not data:
+ data = self.__data
+ self.__lines = data.split('\n')
+ self.__linecnt = len(self.__lines)
+
+ def __repr__(self):
+ self.__setup()
+ if len(self.__lines) <= self.MAXLINES:
+ return "\n".join(self.__lines)
+ else:
+ return "Type %s() to see the full %s text" % ((self.__name,)*2)
+
+ def __call__(self):
+ self.__setup()
+ prompt = 'Hit Return for more, or q (and Return) to quit: '
+ lineno = 0
+ while 1:
+ try:
+ for i in range(lineno, lineno + self.MAXLINES):
+ print self.__lines[i]
+ except IndexError:
+ break
+ else:
+ lineno += self.MAXLINES
+ key = None
+ while key is None:
+ key = raw_input(prompt)
+ if key not in ('', 'q'):
+ key = None
+ if key == 'q':
+ break
+
+def setcopyright():
+ """Set 'copyright' and 'credits' in __builtin__"""
+ __builtin__.copyright = _Printer("copyright", sys.copyright)
+ if sys.platform[:4] == 'java':
+ __builtin__.credits = _Printer(
+ "credits",
+ "Jython is maintained by the Jython developers (www.jython.org).")
+ else:
+ __builtin__.credits = _Printer("credits", """\
+ Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
+ for supporting Python development. See www.python.org for more information.""")
+ here = os.path.dirname(os.__file__)
+ __builtin__.license = _Printer(
+ "license", "See https://www.python.org/psf/license/",
+ ["LICENSE.txt", "LICENSE"],
+ [os.path.join(here, os.pardir), here, os.curdir])
+
+
+class _Helper(object):
+ """Define the builtin 'help'.
+ This is a wrapper around pydoc.help (with a twist).
+
+ """
+
+ def __repr__(self):
+ return "Type help() for interactive help, " \
+ "or help(object) for help about object."
+ def __call__(self, *args, **kwds):
+ import pydoc
+ return pydoc.help(*args, **kwds)
+
+def sethelper():
+ __builtin__.help = _Helper()
+
+def aliasmbcs():
+ """On Windows, some default encodings are not provided by Python,
+ while they are always available as "mbcs" in each locale. Make
+ them usable by aliasing to "mbcs" in such a case."""
+ if sys.platform == 'win32':
+ import locale, codecs
+ enc = locale.getdefaultlocale()[1]
+ if enc.startswith('cp'): # "cp***" ?
+ try:
+ codecs.lookup(enc)
+ except LookupError:
+ import encodings
+ encodings._cache[enc] = encodings._unknown
+ encodings.aliases.aliases[enc] = 'mbcs'
+
+def setencoding():
+ """Set the string encoding used by the Unicode implementation. The
+ default is 'ascii', but if you're willing to experiment, you can
+ change this."""
+ encoding = "ascii" # Default value set by _PyUnicode_Init()
+ if 0:
+ # Enable to support locale aware default string encodings.
+ import locale
+ loc = locale.getdefaultlocale()
+ if loc[1]:
+ encoding = loc[1]
+ if 0:
+ # Enable to switch off string to Unicode coercion and implicit
+ # Unicode to string conversion.
+ encoding = "undefined"
+ if encoding != "ascii":
+ # On Non-Unicode builds this will raise an AttributeError...
+ sys.setdefaultencoding(encoding) # Needs Python Unicode build !
+
+
+def execsitecustomize():
+ """Run custom site specific code, if available."""
+ try:
+ import sitecustomize
+ except ImportError:
+ pass
+ except Exception:
+ if sys.flags.verbose:
+ sys.excepthook(*sys.exc_info())
+ else:
+ print >>sys.stderr, \
+ "'import sitecustomize' failed; use -v for traceback"
+
+
+def execusercustomize():
+ """Run custom user specific code, if available."""
+ try:
+ import usercustomize
+ except ImportError:
+ pass
+ except Exception:
+ if sys.flags.verbose:
+ sys.excepthook(*sys.exc_info())
+ else:
+ print>>sys.stderr, \
+ "'import usercustomize' failed; use -v for traceback"
+
+
+def main():
+ global ENABLE_USER_SITE
+
+ abs__file__()
+ known_paths = removeduppaths()
+ if ENABLE_USER_SITE is None:
+ ENABLE_USER_SITE = check_enableusersite()
+ known_paths = addusersitepackages(known_paths)
+ known_paths = addsitepackages(known_paths)
+ if sys.platform == 'os2emx':
+ setBEGINLIBPATH()
+ setquit()
+ setcopyright()
+ sethelper()
+ aliasmbcs()
+ setencoding()
+ execsitecustomize()
+ if ENABLE_USER_SITE:
+ execusercustomize()
+ # Remove sys.setdefaultencoding() so that users cannot change the
+ # encoding after initialization. The test for presence is needed when
+ # this module is run as a script, because this code is executed twice.
+ if hasattr(sys, "setdefaultencoding"):
+ del sys.setdefaultencoding
+
+main()
+
+def _script():
+ help = """\
+ %s [--user-base] [--user-site]
+
+ Without arguments print some useful information
+ With arguments print the value of USER_BASE and/or USER_SITE separated
+ by '%s'.
+
+ Exit codes with --user-base or --user-site:
+ 0 - user site directory is enabled
+ 1 - user site directory is disabled by user
+ 2 - uses site directory is disabled by super user
+ or for security reasons
+ >2 - unknown error
+ """
+ args = sys.argv[1:]
+ if not args:
+ print "sys.path = ["
+ for dir in sys.path:
+ print " %r," % (dir,)
+ print "]"
+ print "USER_BASE: %r (%s)" % (USER_BASE,
+ "exists" if os.path.isdir(USER_BASE) else "doesn't exist")
+ print "USER_SITE: %r (%s)" % (USER_SITE,
+ "exists" if os.path.isdir(USER_SITE) else "doesn't exist")
+ print "ENABLE_USER_SITE: %r" % ENABLE_USER_SITE
+ sys.exit(0)
+
+ buffer = []
+ if '--user-base' in args:
+ buffer.append(USER_BASE)
+ if '--user-site' in args:
+ buffer.append(USER_SITE)
+
+ if buffer:
+ print os.pathsep.join(buffer)
+ if ENABLE_USER_SITE:
+ sys.exit(0)
+ elif ENABLE_USER_SITE is False:
+ sys.exit(1)
+ elif ENABLE_USER_SITE is None:
+ sys.exit(2)
+ else:
+ sys.exit(3)
+ else:
+ import textwrap
+ print textwrap.dedent(help % (sys.argv[0], os.pathsep))
+ sys.exit(10)
+
+if __name__ == '__main__':
+ _script()
diff --git a/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/_sre.c b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/_sre.c new file mode 100644 index 0000000000..399ea742cf --- /dev/null +++ b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/_sre.c @@ -0,0 +1,4034 @@ +/*
+ * Secret Labs' Regular Expression Engine
+ *
+ * regular expression matching engine
+ *
+ * partial history:
+ * 1999-10-24 fl created (based on existing template matcher code)
+ * 2000-03-06 fl first alpha, sort of
+ * 2000-08-01 fl fixes for 1.6b1
+ * 2000-08-07 fl use PyOS_CheckStack() if available
+ * 2000-09-20 fl added expand method
+ * 2001-03-20 fl lots of fixes for 2.1b2
+ * 2001-04-15 fl export copyright as Python attribute, not global
+ * 2001-04-28 fl added __copy__ methods (work in progress)
+ * 2001-05-14 fl fixes for 1.5.2 compatibility
+ * 2001-07-01 fl added BIGCHARSET support (from Martin von Loewis)
+ * 2001-10-18 fl fixed group reset issue (from Matthew Mueller)
+ * 2001-10-20 fl added split primitive; reenable unicode for 1.6/2.0/2.1
+ * 2001-10-21 fl added sub/subn primitive
+ * 2001-10-24 fl added finditer primitive (for 2.2 only)
+ * 2001-12-07 fl fixed memory leak in sub/subn (Guido van Rossum)
+ * 2002-11-09 fl fixed empty sub/subn return type
+ * 2003-04-18 mvl fully support 4-byte codes
+ * 2003-10-17 gn implemented non recursive scheme
+ *
+ * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved.
+ *
+ * This version of the SRE library can be redistributed under CNRI's
+ * Python 1.6 license. For any other use, please contact Secret Labs
+ * AB (info@pythonware.com).
+ *
+ * Portions of this engine have been developed in cooperation with
+ * CNRI. Hewlett-Packard provided funding for 1.6 integration and
+ * other compatibility work.
+ */
+
+#ifndef SRE_RECURSIVE
+
+static char copyright[] =
+ " SRE 2.2.2 Copyright (c) 1997-2002 by Secret Labs AB ";
+
+#define PY_SSIZE_T_CLEAN
+
+#include "Python.h"
+#include "structmember.h" /* offsetof */
+
+#include "sre.h"
+
+#include <ctype.h>
+
+/* name of this module, minus the leading underscore */
+#if !defined(SRE_MODULE)
+#define SRE_MODULE "sre"
+#endif
+
+#define SRE_PY_MODULE "re"
+
+/* defining this one enables tracing */
+#undef VERBOSE
+
+#if PY_VERSION_HEX >= 0x01060000
+#if PY_VERSION_HEX < 0x02020000 || defined(Py_USING_UNICODE)
+/* defining this enables unicode support (default under 1.6a1 and later) */
+#define HAVE_UNICODE
+#endif
+#endif
+
+/* -------------------------------------------------------------------- */
+/* optional features */
+
+/* enables fast searching */
+#define USE_FAST_SEARCH
+
+/* enables aggressive inlining (always on for Visual C) */
+#undef USE_INLINE
+
+/* enables copy/deepcopy handling (work in progress) */
+#undef USE_BUILTIN_COPY
+
+#if PY_VERSION_HEX < 0x01060000
+#define PyObject_DEL(op) PyMem_DEL((op))
+#endif
+
+/* -------------------------------------------------------------------- */
+
+#if defined(_MSC_VER)
+#pragma optimize("agtw", on) /* doesn't seem to make much difference... */
+#pragma warning(disable: 4710) /* who cares if functions are not inlined ;-) */
+/* fastest possible local call under MSVC */
+#define LOCAL(type) static __inline type __fastcall
+#elif defined(USE_INLINE)
+#define LOCAL(type) static inline type
+#else
+#define LOCAL(type) static type
+#endif
+
+/* error codes */
+#define SRE_ERROR_ILLEGAL -1 /* illegal opcode */
+#define SRE_ERROR_STATE -2 /* illegal state */
+#define SRE_ERROR_RECURSION_LIMIT -3 /* runaway recursion */
+#define SRE_ERROR_MEMORY -9 /* out of memory */
+#define SRE_ERROR_INTERRUPTED -10 /* signal handler raised exception */
+
+#if defined(VERBOSE)
+#define TRACE(v) printf v
+#else
+#define TRACE(v)
+#endif
+
+/* -------------------------------------------------------------------- */
+/* search engine state */
+
+/* default character predicates (run sre_chars.py to regenerate tables) */
+
+#define SRE_DIGIT_MASK 1
+#define SRE_SPACE_MASK 2
+#define SRE_LINEBREAK_MASK 4
+#define SRE_ALNUM_MASK 8
+#define SRE_WORD_MASK 16
+
+/* FIXME: this assumes ASCII. create tables in init_sre() instead */
+
+static char sre_char_info[128] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 2,
+2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25,
+25, 25, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0,
+0, 0, 16, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0 };
+
+static char sre_char_lower[128] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
+44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,
+108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
+122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
+106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
+120, 121, 122, 123, 124, 125, 126, 127 };
+
+#define SRE_IS_DIGIT(ch)\
+ ((ch) < 128 ? (sre_char_info[(ch)] & SRE_DIGIT_MASK) : 0)
+#define SRE_IS_SPACE(ch)\
+ ((ch) < 128 ? (sre_char_info[(ch)] & SRE_SPACE_MASK) : 0)
+#define SRE_IS_LINEBREAK(ch)\
+ ((ch) < 128 ? (sre_char_info[(ch)] & SRE_LINEBREAK_MASK) : 0)
+#define SRE_IS_ALNUM(ch)\
+ ((ch) < 128 ? (sre_char_info[(ch)] & SRE_ALNUM_MASK) : 0)
+#define SRE_IS_WORD(ch)\
+ ((ch) < 128 ? (sre_char_info[(ch)] & SRE_WORD_MASK) : 0)
+
+static unsigned int sre_lower(unsigned int ch)
+{
+ return ((ch) < 128 ? (unsigned int)sre_char_lower[ch] : ch);
+}
+
+/* locale-specific character predicates */
+/* !(c & ~N) == (c < N+1) for any unsigned c, this avoids
+ * warnings when c's type supports only numbers < N+1 */
+#define SRE_LOC_IS_DIGIT(ch) (!((ch) & ~255) ? isdigit((ch)) : 0)
+#define SRE_LOC_IS_SPACE(ch) (!((ch) & ~255) ? isspace((ch)) : 0)
+#define SRE_LOC_IS_LINEBREAK(ch) ((ch) == '\n')
+#define SRE_LOC_IS_ALNUM(ch) (!((ch) & ~255) ? isalnum((ch)) : 0)
+#define SRE_LOC_IS_WORD(ch) (SRE_LOC_IS_ALNUM((ch)) || (ch) == '_')
+
+static unsigned int sre_lower_locale(unsigned int ch)
+{
+ return ((ch) < 256 ? (unsigned int)tolower((ch)) : ch);
+}
+
+/* unicode-specific character predicates */
+
+#if defined(HAVE_UNICODE)
+
+#define SRE_UNI_IS_DIGIT(ch) Py_UNICODE_ISDECIMAL((Py_UNICODE)(ch))
+#define SRE_UNI_IS_SPACE(ch) Py_UNICODE_ISSPACE((Py_UNICODE)(ch))
+#define SRE_UNI_IS_LINEBREAK(ch) Py_UNICODE_ISLINEBREAK((Py_UNICODE)(ch))
+#define SRE_UNI_IS_ALNUM(ch) Py_UNICODE_ISALNUM((Py_UNICODE)(ch))
+#define SRE_UNI_IS_WORD(ch) (SRE_UNI_IS_ALNUM((ch)) || (ch) == '_')
+
+static unsigned int sre_lower_unicode(unsigned int ch)
+{
+ return (unsigned int) Py_UNICODE_TOLOWER((Py_UNICODE)(ch));
+}
+
+#endif
+
+LOCAL(int)
+sre_category(SRE_CODE category, unsigned int ch)
+{
+ switch (category) {
+
+ case SRE_CATEGORY_DIGIT:
+ return SRE_IS_DIGIT(ch);
+ case SRE_CATEGORY_NOT_DIGIT:
+ return !SRE_IS_DIGIT(ch);
+ case SRE_CATEGORY_SPACE:
+ return SRE_IS_SPACE(ch);
+ case SRE_CATEGORY_NOT_SPACE:
+ return !SRE_IS_SPACE(ch);
+ case SRE_CATEGORY_WORD:
+ return SRE_IS_WORD(ch);
+ case SRE_CATEGORY_NOT_WORD:
+ return !SRE_IS_WORD(ch);
+ case SRE_CATEGORY_LINEBREAK:
+ return SRE_IS_LINEBREAK(ch);
+ case SRE_CATEGORY_NOT_LINEBREAK:
+ return !SRE_IS_LINEBREAK(ch);
+
+ case SRE_CATEGORY_LOC_WORD:
+ return SRE_LOC_IS_WORD(ch);
+ case SRE_CATEGORY_LOC_NOT_WORD:
+ return !SRE_LOC_IS_WORD(ch);
+
+#if defined(HAVE_UNICODE)
+ case SRE_CATEGORY_UNI_DIGIT:
+ return SRE_UNI_IS_DIGIT(ch);
+ case SRE_CATEGORY_UNI_NOT_DIGIT:
+ return !SRE_UNI_IS_DIGIT(ch);
+ case SRE_CATEGORY_UNI_SPACE:
+ return SRE_UNI_IS_SPACE(ch);
+ case SRE_CATEGORY_UNI_NOT_SPACE:
+ return !SRE_UNI_IS_SPACE(ch);
+ case SRE_CATEGORY_UNI_WORD:
+ return SRE_UNI_IS_WORD(ch);
+ case SRE_CATEGORY_UNI_NOT_WORD:
+ return !SRE_UNI_IS_WORD(ch);
+ case SRE_CATEGORY_UNI_LINEBREAK:
+ return SRE_UNI_IS_LINEBREAK(ch);
+ case SRE_CATEGORY_UNI_NOT_LINEBREAK:
+ return !SRE_UNI_IS_LINEBREAK(ch);
+#else
+ case SRE_CATEGORY_UNI_DIGIT:
+ return SRE_IS_DIGIT(ch);
+ case SRE_CATEGORY_UNI_NOT_DIGIT:
+ return !SRE_IS_DIGIT(ch);
+ case SRE_CATEGORY_UNI_SPACE:
+ return SRE_IS_SPACE(ch);
+ case SRE_CATEGORY_UNI_NOT_SPACE:
+ return !SRE_IS_SPACE(ch);
+ case SRE_CATEGORY_UNI_WORD:
+ return SRE_LOC_IS_WORD(ch);
+ case SRE_CATEGORY_UNI_NOT_WORD:
+ return !SRE_LOC_IS_WORD(ch);
+ case SRE_CATEGORY_UNI_LINEBREAK:
+ return SRE_IS_LINEBREAK(ch);
+ case SRE_CATEGORY_UNI_NOT_LINEBREAK:
+ return !SRE_IS_LINEBREAK(ch);
+#endif
+ }
+ return 0;
+}
+
+/* helpers */
+
+static void
+data_stack_dealloc(SRE_STATE* state)
+{
+ if (state->data_stack) {
+ PyMem_FREE(state->data_stack);
+ state->data_stack = NULL;
+ }
+ state->data_stack_size = state->data_stack_base = 0;
+}
+
+static int
+data_stack_grow(SRE_STATE* state, Py_ssize_t size)
+{
+ Py_ssize_t minsize, cursize;
+ minsize = state->data_stack_base+size;
+ cursize = state->data_stack_size;
+ if (cursize < minsize) {
+ void* stack;
+ cursize = minsize+minsize/4+1024;
+ TRACE(("allocate/grow stack %" PY_FORMAT_SIZE_T "d\n", cursize));
+ stack = PyMem_REALLOC(state->data_stack, cursize);
+ if (!stack) {
+ data_stack_dealloc(state);
+ return SRE_ERROR_MEMORY;
+ }
+ state->data_stack = (char *)stack;
+ state->data_stack_size = cursize;
+ }
+ return 0;
+}
+
+/* generate 8-bit version */
+
+#define SRE_CHAR unsigned char
+#define SRE_AT sre_at
+#define SRE_COUNT sre_count
+#define SRE_CHARSET sre_charset
+#define SRE_INFO sre_info
+#define SRE_MATCH sre_match
+#define SRE_MATCH_CONTEXT sre_match_context
+#define SRE_SEARCH sre_search
+#define SRE_LITERAL_TEMPLATE sre_literal_template
+
+#if defined(HAVE_UNICODE)
+
+#define SRE_RECURSIVE
+#include "_sre.c"
+#undef SRE_RECURSIVE
+
+#undef SRE_LITERAL_TEMPLATE
+#undef SRE_SEARCH
+#undef SRE_MATCH
+#undef SRE_MATCH_CONTEXT
+#undef SRE_INFO
+#undef SRE_CHARSET
+#undef SRE_COUNT
+#undef SRE_AT
+#undef SRE_CHAR
+
+/* generate 16-bit unicode version */
+
+#define SRE_CHAR Py_UNICODE
+#define SRE_AT sre_uat
+#define SRE_COUNT sre_ucount
+#define SRE_CHARSET sre_ucharset
+#define SRE_INFO sre_uinfo
+#define SRE_MATCH sre_umatch
+#define SRE_MATCH_CONTEXT sre_umatch_context
+#define SRE_SEARCH sre_usearch
+#define SRE_LITERAL_TEMPLATE sre_uliteral_template
+#endif
+
+#endif /* SRE_RECURSIVE */
+
+/* -------------------------------------------------------------------- */
+/* String matching engine */
+
+/* the following section is compiled twice, with different character
+ settings */
+
+LOCAL(int)
+SRE_AT(SRE_STATE* state, SRE_CHAR* ptr, SRE_CODE at)
+{
+ /* check if pointer is at given position */
+
+ Py_ssize_t thisp, thatp;
+
+ switch (at) {
+
+ case SRE_AT_BEGINNING:
+ case SRE_AT_BEGINNING_STRING:
+ return ((void*) ptr == state->beginning);
+
+ case SRE_AT_BEGINNING_LINE:
+ return ((void*) ptr == state->beginning ||
+ SRE_IS_LINEBREAK((int) ptr[-1]));
+
+ case SRE_AT_END:
+ return (((void*) (ptr+1) == state->end &&
+ SRE_IS_LINEBREAK((int) ptr[0])) ||
+ ((void*) ptr == state->end));
+
+ case SRE_AT_END_LINE:
+ return ((void*) ptr == state->end ||
+ SRE_IS_LINEBREAK((int) ptr[0]));
+
+ case SRE_AT_END_STRING:
+ return ((void*) ptr == state->end);
+
+ case SRE_AT_BOUNDARY:
+ if (state->beginning == state->end)
+ return 0;
+ thatp = ((void*) ptr > state->beginning) ?
+ SRE_IS_WORD((int) ptr[-1]) : 0;
+ thisp = ((void*) ptr < state->end) ?
+ SRE_IS_WORD((int) ptr[0]) : 0;
+ return thisp != thatp;
+
+ case SRE_AT_NON_BOUNDARY:
+ if (state->beginning == state->end)
+ return 0;
+ thatp = ((void*) ptr > state->beginning) ?
+ SRE_IS_WORD((int) ptr[-1]) : 0;
+ thisp = ((void*) ptr < state->end) ?
+ SRE_IS_WORD((int) ptr[0]) : 0;
+ return thisp == thatp;
+
+ case SRE_AT_LOC_BOUNDARY:
+ if (state->beginning == state->end)
+ return 0;
+ thatp = ((void*) ptr > state->beginning) ?
+ SRE_LOC_IS_WORD((int) ptr[-1]) : 0;
+ thisp = ((void*) ptr < state->end) ?
+ SRE_LOC_IS_WORD((int) ptr[0]) : 0;
+ return thisp != thatp;
+
+ case SRE_AT_LOC_NON_BOUNDARY:
+ if (state->beginning == state->end)
+ return 0;
+ thatp = ((void*) ptr > state->beginning) ?
+ SRE_LOC_IS_WORD((int) ptr[-1]) : 0;
+ thisp = ((void*) ptr < state->end) ?
+ SRE_LOC_IS_WORD((int) ptr[0]) : 0;
+ return thisp == thatp;
+
+#if defined(HAVE_UNICODE)
+ case SRE_AT_UNI_BOUNDARY:
+ if (state->beginning == state->end)
+ return 0;
+ thatp = ((void*) ptr > state->beginning) ?
+ SRE_UNI_IS_WORD((int) ptr[-1]) : 0;
+ thisp = ((void*) ptr < state->end) ?
+ SRE_UNI_IS_WORD((int) ptr[0]) : 0;
+ return thisp != thatp;
+
+ case SRE_AT_UNI_NON_BOUNDARY:
+ if (state->beginning == state->end)
+ return 0;
+ thatp = ((void*) ptr > state->beginning) ?
+ SRE_UNI_IS_WORD((int) ptr[-1]) : 0;
+ thisp = ((void*) ptr < state->end) ?
+ SRE_UNI_IS_WORD((int) ptr[0]) : 0;
+ return thisp == thatp;
+#endif
+
+ }
+
+ return 0;
+}
+
+LOCAL(int)
+SRE_CHARSET(SRE_CODE* set, SRE_CODE ch)
+{
+ /* check if character is a member of the given set */
+
+ int ok = 1;
+
+ for (;;) {
+ switch (*set++) {
+
+ case SRE_OP_FAILURE:
+ return !ok;
+
+ case SRE_OP_LITERAL:
+ /* <LITERAL> <code> */
+ if (ch == set[0])
+ return ok;
+ set++;
+ break;
+
+ case SRE_OP_CATEGORY:
+ /* <CATEGORY> <code> */
+ if (sre_category(set[0], (int) ch))
+ return ok;
+ set += 1;
+ break;
+
+ case SRE_OP_CHARSET:
+ if (sizeof(SRE_CODE) == 2) {
+ /* <CHARSET> <bitmap> (16 bits per code word) */
+ if (ch < 256 && (set[ch >> 4] & (1 << (ch & 15))))
+ return ok;
+ set += 16;
+ }
+ else {
+ /* <CHARSET> <bitmap> (32 bits per code word) */
+ if (ch < 256 && (set[ch >> 5] & (1u << (ch & 31))))
+ return ok;
+ set += 8;
+ }
+ break;
+
+ case SRE_OP_RANGE:
+ /* <RANGE> <lower> <upper> */
+ if (set[0] <= ch && ch <= set[1])
+ return ok;
+ set += 2;
+ break;
+
+ case SRE_OP_NEGATE:
+ ok = !ok;
+ break;
+
+ case SRE_OP_BIGCHARSET:
+ /* <BIGCHARSET> <blockcount> <256 blockindices> <blocks> */
+ {
+ Py_ssize_t count, block;
+ count = *(set++);
+
+ if (sizeof(SRE_CODE) == 2) {
+ block = ((unsigned char*)set)[ch >> 8];
+ set += 128;
+ if (set[block*16 + ((ch & 255)>>4)] & (1 << (ch & 15)))
+ return ok;
+ set += count*16;
+ }
+ else {
+ /* !(c & ~N) == (c < N+1) for any unsigned c, this avoids
+ * warnings when c's type supports only numbers < N+1 */
+ if (!(ch & ~65535))
+ block = ((unsigned char*)set)[ch >> 8];
+ else
+ block = -1;
+ set += 64;
+ if (block >=0 &&
+ (set[block*8 + ((ch & 255)>>5)] & (1u << (ch & 31))))
+ return ok;
+ set += count*8;
+ }
+ break;
+ }
+
+ default:
+ /* internal error -- there's not much we can do about it
+ here, so let's just pretend it didn't match... */
+ return 0;
+ }
+ }
+}
+
+LOCAL(Py_ssize_t) SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern);
+
+LOCAL(Py_ssize_t)
+SRE_COUNT(SRE_STATE* state, SRE_CODE* pattern, Py_ssize_t maxcount)
+{
+ SRE_CODE chr;
+ SRE_CHAR* ptr = (SRE_CHAR *)state->ptr;
+ SRE_CHAR* end = (SRE_CHAR *)state->end;
+ Py_ssize_t i;
+
+ /* adjust end */
+ if (maxcount < end - ptr && maxcount != SRE_MAXREPEAT)
+ end = ptr + maxcount;
+
+ switch (pattern[0]) {
+
+ case SRE_OP_IN:
+ /* repeated set */
+ TRACE(("|%p|%p|COUNT IN\n", pattern, ptr));
+ while (ptr < end && SRE_CHARSET(pattern + 2, *ptr))
+ ptr++;
+ break;
+
+ case SRE_OP_ANY:
+ /* repeated dot wildcard. */
+ TRACE(("|%p|%p|COUNT ANY\n", pattern, ptr));
+ while (ptr < end && !SRE_IS_LINEBREAK(*ptr))
+ ptr++;
+ break;
+
+ case SRE_OP_ANY_ALL:
+ /* repeated dot wildcard. skip to the end of the target
+ string, and backtrack from there */
+ TRACE(("|%p|%p|COUNT ANY_ALL\n", pattern, ptr));
+ ptr = end;
+ break;
+
+ case SRE_OP_LITERAL:
+ /* repeated literal */
+ chr = pattern[1];
+ TRACE(("|%p|%p|COUNT LITERAL %d\n", pattern, ptr, chr));
+ while (ptr < end && (SRE_CODE) *ptr == chr)
+ ptr++;
+ break;
+
+ case SRE_OP_LITERAL_IGNORE:
+ /* repeated literal */
+ chr = pattern[1];
+ TRACE(("|%p|%p|COUNT LITERAL_IGNORE %d\n", pattern, ptr, chr));
+ while (ptr < end && (SRE_CODE) state->lower(*ptr) == chr)
+ ptr++;
+ break;
+
+ case SRE_OP_NOT_LITERAL:
+ /* repeated non-literal */
+ chr = pattern[1];
+ TRACE(("|%p|%p|COUNT NOT_LITERAL %d\n", pattern, ptr, chr));
+ while (ptr < end && (SRE_CODE) *ptr != chr)
+ ptr++;
+ break;
+
+ case SRE_OP_NOT_LITERAL_IGNORE:
+ /* repeated non-literal */
+ chr = pattern[1];
+ TRACE(("|%p|%p|COUNT NOT_LITERAL_IGNORE %d\n", pattern, ptr, chr));
+ while (ptr < end && (SRE_CODE) state->lower(*ptr) != chr)
+ ptr++;
+ break;
+
+ default:
+ /* repeated single character pattern */
+ TRACE(("|%p|%p|COUNT SUBPATTERN\n", pattern, ptr));
+ while ((SRE_CHAR*) state->ptr < end) {
+ i = SRE_MATCH(state, pattern);
+ if (i < 0)
+ return i;
+ if (!i)
+ break;
+ }
+ TRACE(("|%p|%p|COUNT %" PY_FORMAT_SIZE_T "d\n", pattern, ptr,
+ (SRE_CHAR*) state->ptr - ptr));
+ return (SRE_CHAR*) state->ptr - ptr;
+ }
+
+ TRACE(("|%p|%p|COUNT %" PY_FORMAT_SIZE_T "d\n", pattern, ptr,
+ ptr - (SRE_CHAR*) state->ptr));
+ return ptr - (SRE_CHAR*) state->ptr;
+}
+
+#if 0 /* not used in this release */
+LOCAL(int)
+SRE_INFO(SRE_STATE* state, SRE_CODE* pattern)
+{
+ /* check if an SRE_OP_INFO block matches at the current position.
+ returns the number of SRE_CODE objects to skip if successful, 0
+ if no match */
+
+ SRE_CHAR* end = state->end;
+ SRE_CHAR* ptr = state->ptr;
+ Py_ssize_t i;
+
+ /* check minimal length */
+ if (pattern[3] && (end - ptr) < pattern[3])
+ return 0;
+
+ /* check known prefix */
+ if (pattern[2] & SRE_INFO_PREFIX && pattern[5] > 1) {
+ /* <length> <skip> <prefix data> <overlap data> */
+ for (i = 0; i < pattern[5]; i++)
+ if ((SRE_CODE) ptr[i] != pattern[7 + i])
+ return 0;
+ return pattern[0] + 2 * pattern[6];
+ }
+ return pattern[0];
+}
+#endif
+
+/* The macros below should be used to protect recursive SRE_MATCH()
+ * calls that *failed* and do *not* return immediately (IOW, those
+ * that will backtrack). Explaining:
+ *
+ * - Recursive SRE_MATCH() returned true: that's usually a success
+ * (besides atypical cases like ASSERT_NOT), therefore there's no
+ * reason to restore lastmark;
+ *
+ * - Recursive SRE_MATCH() returned false but the current SRE_MATCH()
+ * is returning to the caller: If the current SRE_MATCH() is the
+ * top function of the recursion, returning false will be a matching
+ * failure, and it doesn't matter where lastmark is pointing to.
+ * If it's *not* the top function, it will be a recursive SRE_MATCH()
+ * failure by itself, and the calling SRE_MATCH() will have to deal
+ * with the failure by the same rules explained here (it will restore
+ * lastmark by itself if necessary);
+ *
+ * - Recursive SRE_MATCH() returned false, and will continue the
+ * outside 'for' loop: must be protected when breaking, since the next
+ * OP could potentially depend on lastmark;
+ *
+ * - Recursive SRE_MATCH() returned false, and will be called again
+ * inside a local for/while loop: must be protected between each
+ * loop iteration, since the recursive SRE_MATCH() could do anything,
+ * and could potentially depend on lastmark.
+ *
+ * For more information, check the discussion at SF patch #712900.
+ */
+#define LASTMARK_SAVE() \
+ do { \
+ ctx->lastmark = state->lastmark; \
+ ctx->lastindex = state->lastindex; \
+ } while (0)
+#define LASTMARK_RESTORE() \
+ do { \
+ state->lastmark = ctx->lastmark; \
+ state->lastindex = ctx->lastindex; \
+ } while (0)
+
+#define RETURN_ERROR(i) do { return i; } while(0)
+#define RETURN_FAILURE do { ret = 0; goto exit; } while(0)
+#define RETURN_SUCCESS do { ret = 1; goto exit; } while(0)
+
+#define RETURN_ON_ERROR(i) \
+ do { if (i < 0) RETURN_ERROR(i); } while (0)
+#define RETURN_ON_SUCCESS(i) \
+ do { RETURN_ON_ERROR(i); if (i > 0) RETURN_SUCCESS; } while (0)
+#define RETURN_ON_FAILURE(i) \
+ do { RETURN_ON_ERROR(i); if (i == 0) RETURN_FAILURE; } while (0)
+
+#define SFY(x) #x
+
+#define DATA_STACK_ALLOC(state, type, ptr) \
+do { \
+ alloc_pos = state->data_stack_base; \
+ TRACE(("allocating %s in %" PY_FORMAT_SIZE_T "d " \
+ "(%" PY_FORMAT_SIZE_T "d)\n", \
+ SFY(type), alloc_pos, sizeof(type))); \
+ if (sizeof(type) > state->data_stack_size - alloc_pos) { \
+ int j = data_stack_grow(state, sizeof(type)); \
+ if (j < 0) return j; \
+ if (ctx_pos != -1) \
+ DATA_STACK_LOOKUP_AT(state, SRE_MATCH_CONTEXT, ctx, ctx_pos); \
+ } \
+ ptr = (type*)(state->data_stack+alloc_pos); \
+ state->data_stack_base += sizeof(type); \
+} while (0)
+
+#define DATA_STACK_LOOKUP_AT(state, type, ptr, pos) \
+do { \
+ TRACE(("looking up %s at %" PY_FORMAT_SIZE_T "d\n", SFY(type), pos)); \
+ ptr = (type*)(state->data_stack+pos); \
+} while (0)
+
+#define DATA_STACK_PUSH(state, data, size) \
+do { \
+ TRACE(("copy data in %p to %" PY_FORMAT_SIZE_T "d " \
+ "(%" PY_FORMAT_SIZE_T "d)\n", \
+ data, state->data_stack_base, size)); \
+ if (size > state->data_stack_size - state->data_stack_base) { \
+ int j = data_stack_grow(state, size); \
+ if (j < 0) return j; \
+ if (ctx_pos != -1) \
+ DATA_STACK_LOOKUP_AT(state, SRE_MATCH_CONTEXT, ctx, ctx_pos); \
+ } \
+ memcpy(state->data_stack+state->data_stack_base, data, size); \
+ state->data_stack_base += size; \
+} while (0)
+
+#define DATA_STACK_POP(state, data, size, discard) \
+do { \
+ TRACE(("copy data to %p from %" PY_FORMAT_SIZE_T "d " \
+ "(%" PY_FORMAT_SIZE_T "d)\n", \
+ data, state->data_stack_base-size, size)); \
+ memcpy(data, state->data_stack+state->data_stack_base-size, size); \
+ if (discard) \
+ state->data_stack_base -= size; \
+} while (0)
+
+#define DATA_STACK_POP_DISCARD(state, size) \
+do { \
+ TRACE(("discard data from %" PY_FORMAT_SIZE_T "d " \
+ "(%" PY_FORMAT_SIZE_T "d)\n", \
+ state->data_stack_base-size, size)); \
+ state->data_stack_base -= size; \
+} while(0)
+
+#define DATA_PUSH(x) \
+ DATA_STACK_PUSH(state, (x), sizeof(*(x)))
+#define DATA_POP(x) \
+ DATA_STACK_POP(state, (x), sizeof(*(x)), 1)
+#define DATA_POP_DISCARD(x) \
+ DATA_STACK_POP_DISCARD(state, sizeof(*(x)))
+#define DATA_ALLOC(t,p) \
+ DATA_STACK_ALLOC(state, t, p)
+#define DATA_LOOKUP_AT(t,p,pos) \
+ DATA_STACK_LOOKUP_AT(state,t,p,pos)
+
+#define MARK_PUSH(lastmark) \
+ do if (lastmark > 0) { \
+ i = lastmark; /* ctx->lastmark may change if reallocated */ \
+ DATA_STACK_PUSH(state, state->mark, (i+1)*sizeof(void*)); \
+ } while (0)
+#define MARK_POP(lastmark) \
+ do if (lastmark > 0) { \
+ DATA_STACK_POP(state, state->mark, (lastmark+1)*sizeof(void*), 1); \
+ } while (0)
+#define MARK_POP_KEEP(lastmark) \
+ do if (lastmark > 0) { \
+ DATA_STACK_POP(state, state->mark, (lastmark+1)*sizeof(void*), 0); \
+ } while (0)
+#define MARK_POP_DISCARD(lastmark) \
+ do if (lastmark > 0) { \
+ DATA_STACK_POP_DISCARD(state, (lastmark+1)*sizeof(void*)); \
+ } while (0)
+
+#define JUMP_NONE 0
+#define JUMP_MAX_UNTIL_1 1
+#define JUMP_MAX_UNTIL_2 2
+#define JUMP_MAX_UNTIL_3 3
+#define JUMP_MIN_UNTIL_1 4
+#define JUMP_MIN_UNTIL_2 5
+#define JUMP_MIN_UNTIL_3 6
+#define JUMP_REPEAT 7
+#define JUMP_REPEAT_ONE_1 8
+#define JUMP_REPEAT_ONE_2 9
+#define JUMP_MIN_REPEAT_ONE 10
+#define JUMP_BRANCH 11
+#define JUMP_ASSERT 12
+#define JUMP_ASSERT_NOT 13
+
+#define DO_JUMP(jumpvalue, jumplabel, nextpattern) \
+ DATA_ALLOC(SRE_MATCH_CONTEXT, nextctx); \
+ nextctx->last_ctx_pos = ctx_pos; \
+ nextctx->jump = jumpvalue; \
+ nextctx->pattern = nextpattern; \
+ ctx_pos = alloc_pos; \
+ ctx = nextctx; \
+ goto entrance; \
+ jumplabel: \
+ while (0) /* gcc doesn't like labels at end of scopes */ \
+
+typedef struct {
+ Py_ssize_t last_ctx_pos;
+ Py_ssize_t jump;
+ SRE_CHAR* ptr;
+ SRE_CODE* pattern;
+ Py_ssize_t count;
+ Py_ssize_t lastmark;
+ Py_ssize_t lastindex;
+ union {
+ SRE_CODE chr;
+ SRE_REPEAT* rep;
+ } u;
+} SRE_MATCH_CONTEXT;
+
+/* check if string matches the given pattern. returns <0 for
+ error, 0 for failure, and 1 for success */
+LOCAL(Py_ssize_t)
+SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern)
+{
+ SRE_CHAR* end = (SRE_CHAR *)state->end;
+ Py_ssize_t alloc_pos, ctx_pos = -1;
+ Py_ssize_t i, ret = 0;
+ Py_ssize_t jump;
+ unsigned int sigcount=0;
+
+ SRE_MATCH_CONTEXT* ctx;
+ SRE_MATCH_CONTEXT* nextctx;
+
+ TRACE(("|%p|%p|ENTER\n", pattern, state->ptr));
+
+ DATA_ALLOC(SRE_MATCH_CONTEXT, ctx);
+ ctx->last_ctx_pos = -1;
+ ctx->jump = JUMP_NONE;
+ ctx->pattern = pattern;
+ ctx_pos = alloc_pos;
+
+entrance:
+
+ ctx->ptr = (SRE_CHAR *)state->ptr;
+
+ if (ctx->pattern[0] == SRE_OP_INFO) {
+ /* optimization info block */
+ /* <INFO> <1=skip> <2=flags> <3=min> ... */
+ if (ctx->pattern[3] && (end - ctx->ptr) < ctx->pattern[3]) {
+ TRACE(("reject (got %" PY_FORMAT_SIZE_T "d chars, "
+ "need %" PY_FORMAT_SIZE_T "d)\n",
+ (end - ctx->ptr), (Py_ssize_t) ctx->pattern[3]));
+ RETURN_FAILURE;
+ }
+ ctx->pattern += ctx->pattern[1] + 1;
+ }
+
+ for (;;) {
+ ++sigcount;
+ if ((0 == (sigcount & 0xfff)) && PyErr_CheckSignals())
+ RETURN_ERROR(SRE_ERROR_INTERRUPTED);
+
+ switch (*ctx->pattern++) {
+
+ case SRE_OP_MARK:
+ /* set mark */
+ /* <MARK> <gid> */
+ TRACE(("|%p|%p|MARK %d\n", ctx->pattern,
+ ctx->ptr, ctx->pattern[0]));
+ i = ctx->pattern[0];
+ if (i & 1)
+ state->lastindex = i/2 + 1;
+ if (i > state->lastmark) {
+ /* state->lastmark is the highest valid index in the
+ state->mark array. If it is increased by more than 1,
+ the intervening marks must be set to NULL to signal
+ that these marks have not been encountered. */
+ Py_ssize_t j = state->lastmark + 1;
+ while (j < i)
+ state->mark[j++] = NULL;
+ state->lastmark = i;
+ }
+ state->mark[i] = ctx->ptr;
+ ctx->pattern++;
+ break;
+
+ case SRE_OP_LITERAL:
+ /* match literal string */
+ /* <LITERAL> <code> */
+ TRACE(("|%p|%p|LITERAL %d\n", ctx->pattern,
+ ctx->ptr, *ctx->pattern));
+ if (ctx->ptr >= end || (SRE_CODE) ctx->ptr[0] != ctx->pattern[0])
+ RETURN_FAILURE;
+ ctx->pattern++;
+ ctx->ptr++;
+ break;
+
+ case SRE_OP_NOT_LITERAL:
+ /* match anything that is not literal character */
+ /* <NOT_LITERAL> <code> */
+ TRACE(("|%p|%p|NOT_LITERAL %d\n", ctx->pattern,
+ ctx->ptr, *ctx->pattern));
+ if (ctx->ptr >= end || (SRE_CODE) ctx->ptr[0] == ctx->pattern[0])
+ RETURN_FAILURE;
+ ctx->pattern++;
+ ctx->ptr++;
+ break;
+
+ case SRE_OP_SUCCESS:
+ /* end of pattern */
+ TRACE(("|%p|%p|SUCCESS\n", ctx->pattern, ctx->ptr));
+ state->ptr = ctx->ptr;
+ RETURN_SUCCESS;
+
+ case SRE_OP_AT:
+ /* match at given position */
+ /* <AT> <code> */
+ TRACE(("|%p|%p|AT %d\n", ctx->pattern, ctx->ptr, *ctx->pattern));
+ if (!SRE_AT(state, ctx->ptr, *ctx->pattern))
+ RETURN_FAILURE;
+ ctx->pattern++;
+ break;
+
+ case SRE_OP_CATEGORY:
+ /* match at given category */
+ /* <CATEGORY> <code> */
+ TRACE(("|%p|%p|CATEGORY %d\n", ctx->pattern,
+ ctx->ptr, *ctx->pattern));
+ if (ctx->ptr >= end || !sre_category(ctx->pattern[0], ctx->ptr[0]))
+ RETURN_FAILURE;
+ ctx->pattern++;
+ ctx->ptr++;
+ break;
+
+ case SRE_OP_ANY:
+ /* match anything (except a newline) */
+ /* <ANY> */
+ TRACE(("|%p|%p|ANY\n", ctx->pattern, ctx->ptr));
+ if (ctx->ptr >= end || SRE_IS_LINEBREAK(ctx->ptr[0]))
+ RETURN_FAILURE;
+ ctx->ptr++;
+ break;
+
+ case SRE_OP_ANY_ALL:
+ /* match anything */
+ /* <ANY_ALL> */
+ TRACE(("|%p|%p|ANY_ALL\n", ctx->pattern, ctx->ptr));
+ if (ctx->ptr >= end)
+ RETURN_FAILURE;
+ ctx->ptr++;
+ break;
+
+ case SRE_OP_IN:
+ /* match set member (or non_member) */
+ /* <IN> <skip> <set> */
+ TRACE(("|%p|%p|IN\n", ctx->pattern, ctx->ptr));
+ if (ctx->ptr >= end || !SRE_CHARSET(ctx->pattern + 1, *ctx->ptr))
+ RETURN_FAILURE;
+ ctx->pattern += ctx->pattern[0];
+ ctx->ptr++;
+ break;
+
+ case SRE_OP_LITERAL_IGNORE:
+ TRACE(("|%p|%p|LITERAL_IGNORE %d\n",
+ ctx->pattern, ctx->ptr, ctx->pattern[0]));
+ if (ctx->ptr >= end ||
+ state->lower(*ctx->ptr) != state->lower(*ctx->pattern))
+ RETURN_FAILURE;
+ ctx->pattern++;
+ ctx->ptr++;
+ break;
+
+ case SRE_OP_NOT_LITERAL_IGNORE:
+ TRACE(("|%p|%p|NOT_LITERAL_IGNORE %d\n",
+ ctx->pattern, ctx->ptr, *ctx->pattern));
+ if (ctx->ptr >= end ||
+ state->lower(*ctx->ptr) == state->lower(*ctx->pattern))
+ RETURN_FAILURE;
+ ctx->pattern++;
+ ctx->ptr++;
+ break;
+
+ case SRE_OP_IN_IGNORE:
+ TRACE(("|%p|%p|IN_IGNORE\n", ctx->pattern, ctx->ptr));
+ if (ctx->ptr >= end
+ || !SRE_CHARSET(ctx->pattern+1,
+ (SRE_CODE)state->lower(*ctx->ptr)))
+ RETURN_FAILURE;
+ ctx->pattern += ctx->pattern[0];
+ ctx->ptr++;
+ break;
+
+ case SRE_OP_JUMP:
+ case SRE_OP_INFO:
+ /* jump forward */
+ /* <JUMP> <offset> */
+ TRACE(("|%p|%p|JUMP %d\n", ctx->pattern,
+ ctx->ptr, ctx->pattern[0]));
+ ctx->pattern += ctx->pattern[0];
+ break;
+
+ case SRE_OP_BRANCH:
+ /* alternation */
+ /* <BRANCH> <0=skip> code <JUMP> ... <NULL> */
+ TRACE(("|%p|%p|BRANCH\n", ctx->pattern, ctx->ptr));
+ LASTMARK_SAVE();
+ ctx->u.rep = state->repeat;
+ if (ctx->u.rep)
+ MARK_PUSH(ctx->lastmark);
+ for (; ctx->pattern[0]; ctx->pattern += ctx->pattern[0]) {
+ if (ctx->pattern[1] == SRE_OP_LITERAL &&
+ (ctx->ptr >= end ||
+ (SRE_CODE) *ctx->ptr != ctx->pattern[2]))
+ continue;
+ if (ctx->pattern[1] == SRE_OP_IN &&
+ (ctx->ptr >= end ||
+ !SRE_CHARSET(ctx->pattern + 3, (SRE_CODE) *ctx->ptr)))
+ continue;
+ state->ptr = ctx->ptr;
+ DO_JUMP(JUMP_BRANCH, jump_branch, ctx->pattern+1);
+ if (ret) {
+ if (ctx->u.rep)
+ MARK_POP_DISCARD(ctx->lastmark);
+ RETURN_ON_ERROR(ret);
+ RETURN_SUCCESS;
+ }
+ if (ctx->u.rep)
+ MARK_POP_KEEP(ctx->lastmark);
+ LASTMARK_RESTORE();
+ }
+ if (ctx->u.rep)
+ MARK_POP_DISCARD(ctx->lastmark);
+ RETURN_FAILURE;
+
+ case SRE_OP_REPEAT_ONE:
+ /* match repeated sequence (maximizing regexp) */
+
+ /* this operator only works if the repeated item is
+ exactly one character wide, and we're not already
+ collecting backtracking points. for other cases,
+ use the MAX_REPEAT operator */
+
+ /* <REPEAT_ONE> <skip> <1=min> <2=max> item <SUCCESS> tail */
+
+ TRACE(("|%p|%p|REPEAT_ONE %d %d\n", ctx->pattern, ctx->ptr,
+ ctx->pattern[1], ctx->pattern[2]));
+
+ if ((Py_ssize_t) ctx->pattern[1] > end - ctx->ptr)
+ RETURN_FAILURE; /* cannot match */
+
+ state->ptr = ctx->ptr;
+
+ ret = SRE_COUNT(state, ctx->pattern+3, ctx->pattern[2]);
+ RETURN_ON_ERROR(ret);
+ DATA_LOOKUP_AT(SRE_MATCH_CONTEXT, ctx, ctx_pos);
+ ctx->count = ret;
+ ctx->ptr += ctx->count;
+
+ /* when we arrive here, count contains the number of
+ matches, and ctx->ptr points to the tail of the target
+ string. check if the rest of the pattern matches,
+ and backtrack if not. */
+
+ if (ctx->count < (Py_ssize_t) ctx->pattern[1])
+ RETURN_FAILURE;
+
+ if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS) {
+ /* tail is empty. we're finished */
+ state->ptr = ctx->ptr;
+ RETURN_SUCCESS;
+ }
+
+ LASTMARK_SAVE();
+
+ if (ctx->pattern[ctx->pattern[0]] == SRE_OP_LITERAL) {
+ /* tail starts with a literal. skip positions where
+ the rest of the pattern cannot possibly match */
+ ctx->u.chr = ctx->pattern[ctx->pattern[0]+1];
+ for (;;) {
+ while (ctx->count >= (Py_ssize_t) ctx->pattern[1] &&
+ (ctx->ptr >= end || *ctx->ptr != ctx->u.chr)) {
+ ctx->ptr--;
+ ctx->count--;
+ }
+ if (ctx->count < (Py_ssize_t) ctx->pattern[1])
+ break;
+ state->ptr = ctx->ptr;
+ DO_JUMP(JUMP_REPEAT_ONE_1, jump_repeat_one_1,
+ ctx->pattern+ctx->pattern[0]);
+ if (ret) {
+ RETURN_ON_ERROR(ret);
+ RETURN_SUCCESS;
+ }
+
+ LASTMARK_RESTORE();
+
+ ctx->ptr--;
+ ctx->count--;
+ }
+
+ } else {
+ /* general case */
+ while (ctx->count >= (Py_ssize_t) ctx->pattern[1]) {
+ state->ptr = ctx->ptr;
+ DO_JUMP(JUMP_REPEAT_ONE_2, jump_repeat_one_2,
+ ctx->pattern+ctx->pattern[0]);
+ if (ret) {
+ RETURN_ON_ERROR(ret);
+ RETURN_SUCCESS;
+ }
+ ctx->ptr--;
+ ctx->count--;
+ LASTMARK_RESTORE();
+ }
+ }
+ RETURN_FAILURE;
+
+ case SRE_OP_MIN_REPEAT_ONE:
+ /* match repeated sequence (minimizing regexp) */
+
+ /* this operator only works if the repeated item is
+ exactly one character wide, and we're not already
+ collecting backtracking points. for other cases,
+ use the MIN_REPEAT operator */
+
+ /* <MIN_REPEAT_ONE> <skip> <1=min> <2=max> item <SUCCESS> tail */
+
+ TRACE(("|%p|%p|MIN_REPEAT_ONE %d %d\n", ctx->pattern, ctx->ptr,
+ ctx->pattern[1], ctx->pattern[2]));
+
+ if ((Py_ssize_t) ctx->pattern[1] > end - ctx->ptr)
+ RETURN_FAILURE; /* cannot match */
+
+ state->ptr = ctx->ptr;
+
+ if (ctx->pattern[1] == 0)
+ ctx->count = 0;
+ else {
+ /* count using pattern min as the maximum */
+ ret = SRE_COUNT(state, ctx->pattern+3, ctx->pattern[1]);
+ RETURN_ON_ERROR(ret);
+ DATA_LOOKUP_AT(SRE_MATCH_CONTEXT, ctx, ctx_pos);
+ if (ret < (Py_ssize_t) ctx->pattern[1])
+ /* didn't match minimum number of times */
+ RETURN_FAILURE;
+ /* advance past minimum matches of repeat */
+ ctx->count = ret;
+ ctx->ptr += ctx->count;
+ }
+
+ if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS) {
+ /* tail is empty. we're finished */
+ state->ptr = ctx->ptr;
+ RETURN_SUCCESS;
+
+ } else {
+ /* general case */
+ LASTMARK_SAVE();
+ while ((Py_ssize_t)ctx->pattern[2] == SRE_MAXREPEAT
+ || ctx->count <= (Py_ssize_t)ctx->pattern[2]) {
+ state->ptr = ctx->ptr;
+ DO_JUMP(JUMP_MIN_REPEAT_ONE,jump_min_repeat_one,
+ ctx->pattern+ctx->pattern[0]);
+ if (ret) {
+ RETURN_ON_ERROR(ret);
+ RETURN_SUCCESS;
+ }
+ state->ptr = ctx->ptr;
+ ret = SRE_COUNT(state, ctx->pattern+3, 1);
+ RETURN_ON_ERROR(ret);
+ DATA_LOOKUP_AT(SRE_MATCH_CONTEXT, ctx, ctx_pos);
+ if (ret == 0)
+ break;
+ assert(ret == 1);
+ ctx->ptr++;
+ ctx->count++;
+ LASTMARK_RESTORE();
+ }
+ }
+ RETURN_FAILURE;
+
+ case SRE_OP_REPEAT:
+ /* create repeat context. all the hard work is done
+ by the UNTIL operator (MAX_UNTIL, MIN_UNTIL) */
+ /* <REPEAT> <skip> <1=min> <2=max> item <UNTIL> tail */
+ TRACE(("|%p|%p|REPEAT %d %d\n", ctx->pattern, ctx->ptr,
+ ctx->pattern[1], ctx->pattern[2]));
+
+ /* install new repeat context */
+ ctx->u.rep = (SRE_REPEAT*) PyObject_MALLOC(sizeof(*ctx->u.rep));
+ if (!ctx->u.rep) {
+ PyErr_NoMemory();
+ RETURN_FAILURE;
+ }
+ ctx->u.rep->count = -1;
+ ctx->u.rep->pattern = ctx->pattern;
+ ctx->u.rep->prev = state->repeat;
+ ctx->u.rep->last_ptr = NULL;
+ state->repeat = ctx->u.rep;
+
+ state->ptr = ctx->ptr;
+ DO_JUMP(JUMP_REPEAT, jump_repeat, ctx->pattern+ctx->pattern[0]);
+ state->repeat = ctx->u.rep->prev;
+ PyObject_FREE(ctx->u.rep);
+
+ if (ret) {
+ RETURN_ON_ERROR(ret);
+ RETURN_SUCCESS;
+ }
+ RETURN_FAILURE;
+
+ case SRE_OP_MAX_UNTIL:
+ /* maximizing repeat */
+ /* <REPEAT> <skip> <1=min> <2=max> item <MAX_UNTIL> tail */
+
+ /* FIXME: we probably need to deal with zero-width
+ matches in here... */
+
+ ctx->u.rep = state->repeat;
+ if (!ctx->u.rep)
+ RETURN_ERROR(SRE_ERROR_STATE);
+
+ state->ptr = ctx->ptr;
+
+ ctx->count = ctx->u.rep->count+1;
+
+ TRACE(("|%p|%p|MAX_UNTIL %" PY_FORMAT_SIZE_T "d\n", ctx->pattern,
+ ctx->ptr, ctx->count));
+
+ if (ctx->count < (Py_ssize_t) ctx->u.rep->pattern[1]) {
+ /* not enough matches */
+ ctx->u.rep->count = ctx->count;
+ DO_JUMP(JUMP_MAX_UNTIL_1, jump_max_until_1,
+ ctx->u.rep->pattern+3);
+ if (ret) {
+ RETURN_ON_ERROR(ret);
+ RETURN_SUCCESS;
+ }
+ ctx->u.rep->count = ctx->count-1;
+ state->ptr = ctx->ptr;
+ RETURN_FAILURE;
+ }
+
+ if ((ctx->count < (Py_ssize_t) ctx->u.rep->pattern[2] ||
+ ctx->u.rep->pattern[2] == SRE_MAXREPEAT) &&
+ state->ptr != ctx->u.rep->last_ptr) {
+ /* we may have enough matches, but if we can
+ match another item, do so */
+ ctx->u.rep->count = ctx->count;
+ LASTMARK_SAVE();
+ MARK_PUSH(ctx->lastmark);
+ /* zero-width match protection */
+ DATA_PUSH(&ctx->u.rep->last_ptr);
+ ctx->u.rep->last_ptr = state->ptr;
+ DO_JUMP(JUMP_MAX_UNTIL_2, jump_max_until_2,
+ ctx->u.rep->pattern+3);
+ DATA_POP(&ctx->u.rep->last_ptr);
+ if (ret) {
+ MARK_POP_DISCARD(ctx->lastmark);
+ RETURN_ON_ERROR(ret);
+ RETURN_SUCCESS;
+ }
+ MARK_POP(ctx->lastmark);
+ LASTMARK_RESTORE();
+ ctx->u.rep->count = ctx->count-1;
+ state->ptr = ctx->ptr;
+ }
+
+ /* cannot match more repeated items here. make sure the
+ tail matches */
+ state->repeat = ctx->u.rep->prev;
+ DO_JUMP(JUMP_MAX_UNTIL_3, jump_max_until_3, ctx->pattern);
+ RETURN_ON_SUCCESS(ret);
+ state->repeat = ctx->u.rep;
+ state->ptr = ctx->ptr;
+ RETURN_FAILURE;
+
+ case SRE_OP_MIN_UNTIL:
+ /* minimizing repeat */
+ /* <REPEAT> <skip> <1=min> <2=max> item <MIN_UNTIL> tail */
+
+ ctx->u.rep = state->repeat;
+ if (!ctx->u.rep)
+ RETURN_ERROR(SRE_ERROR_STATE);
+
+ state->ptr = ctx->ptr;
+
+ ctx->count = ctx->u.rep->count+1;
+
+ TRACE(("|%p|%p|MIN_UNTIL %" PY_FORMAT_SIZE_T "d %p\n", ctx->pattern,
+ ctx->ptr, ctx->count, ctx->u.rep->pattern));
+
+ if (ctx->count < (Py_ssize_t) ctx->u.rep->pattern[1]) {
+ /* not enough matches */
+ ctx->u.rep->count = ctx->count;
+ DO_JUMP(JUMP_MIN_UNTIL_1, jump_min_until_1,
+ ctx->u.rep->pattern+3);
+ if (ret) {
+ RETURN_ON_ERROR(ret);
+ RETURN_SUCCESS;
+ }
+ ctx->u.rep->count = ctx->count-1;
+ state->ptr = ctx->ptr;
+ RETURN_FAILURE;
+ }
+
+ LASTMARK_SAVE();
+
+ /* see if the tail matches */
+ state->repeat = ctx->u.rep->prev;
+ DO_JUMP(JUMP_MIN_UNTIL_2, jump_min_until_2, ctx->pattern);
+ if (ret) {
+ RETURN_ON_ERROR(ret);
+ RETURN_SUCCESS;
+ }
+
+ state->repeat = ctx->u.rep;
+ state->ptr = ctx->ptr;
+
+ LASTMARK_RESTORE();
+
+ if ((ctx->count >= (Py_ssize_t) ctx->u.rep->pattern[2]
+ && ctx->u.rep->pattern[2] != SRE_MAXREPEAT) ||
+ state->ptr == ctx->u.rep->last_ptr)
+ RETURN_FAILURE;
+
+ ctx->u.rep->count = ctx->count;
+ /* zero-width match protection */
+ DATA_PUSH(&ctx->u.rep->last_ptr);
+ ctx->u.rep->last_ptr = state->ptr;
+ DO_JUMP(JUMP_MIN_UNTIL_3,jump_min_until_3,
+ ctx->u.rep->pattern+3);
+ DATA_POP(&ctx->u.rep->last_ptr);
+ if (ret) {
+ RETURN_ON_ERROR(ret);
+ RETURN_SUCCESS;
+ }
+ ctx->u.rep->count = ctx->count-1;
+ state->ptr = ctx->ptr;
+ RETURN_FAILURE;
+
+ case SRE_OP_GROUPREF:
+ /* match backreference */
+ TRACE(("|%p|%p|GROUPREF %d\n", ctx->pattern,
+ ctx->ptr, ctx->pattern[0]));
+ i = ctx->pattern[0];
+ {
+ Py_ssize_t groupref = i+i;
+ if (groupref >= state->lastmark) {
+ RETURN_FAILURE;
+ } else {
+ SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
+ SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
+ if (!p || !e || e < p)
+ RETURN_FAILURE;
+ while (p < e) {
+ if (ctx->ptr >= end || *ctx->ptr != *p)
+ RETURN_FAILURE;
+ p++; ctx->ptr++;
+ }
+ }
+ }
+ ctx->pattern++;
+ break;
+
+ case SRE_OP_GROUPREF_IGNORE:
+ /* match backreference */
+ TRACE(("|%p|%p|GROUPREF_IGNORE %d\n", ctx->pattern,
+ ctx->ptr, ctx->pattern[0]));
+ i = ctx->pattern[0];
+ {
+ Py_ssize_t groupref = i+i;
+ if (groupref >= state->lastmark) {
+ RETURN_FAILURE;
+ } else {
+ SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
+ SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
+ if (!p || !e || e < p)
+ RETURN_FAILURE;
+ while (p < e) {
+ if (ctx->ptr >= end ||
+ state->lower(*ctx->ptr) != state->lower(*p))
+ RETURN_FAILURE;
+ p++; ctx->ptr++;
+ }
+ }
+ }
+ ctx->pattern++;
+ break;
+
+ case SRE_OP_GROUPREF_EXISTS:
+ TRACE(("|%p|%p|GROUPREF_EXISTS %d\n", ctx->pattern,
+ ctx->ptr, ctx->pattern[0]));
+ /* <GROUPREF_EXISTS> <group> <skip> codeyes <JUMP> codeno ... */
+ i = ctx->pattern[0];
+ {
+ Py_ssize_t groupref = i+i;
+ if (groupref >= state->lastmark) {
+ ctx->pattern += ctx->pattern[1];
+ break;
+ } else {
+ SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
+ SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
+ if (!p || !e || e < p) {
+ ctx->pattern += ctx->pattern[1];
+ break;
+ }
+ }
+ }
+ ctx->pattern += 2;
+ break;
+
+ case SRE_OP_ASSERT:
+ /* assert subpattern */
+ /* <ASSERT> <skip> <back> <pattern> */
+ TRACE(("|%p|%p|ASSERT %d\n", ctx->pattern,
+ ctx->ptr, ctx->pattern[1]));
+ state->ptr = ctx->ptr - ctx->pattern[1];
+ if (state->ptr < state->beginning)
+ RETURN_FAILURE;
+ DO_JUMP(JUMP_ASSERT, jump_assert, ctx->pattern+2);
+ RETURN_ON_FAILURE(ret);
+ ctx->pattern += ctx->pattern[0];
+ break;
+
+ case SRE_OP_ASSERT_NOT:
+ /* assert not subpattern */
+ /* <ASSERT_NOT> <skip> <back> <pattern> */
+ TRACE(("|%p|%p|ASSERT_NOT %d\n", ctx->pattern,
+ ctx->ptr, ctx->pattern[1]));
+ state->ptr = ctx->ptr - ctx->pattern[1];
+ if (state->ptr >= state->beginning) {
+ DO_JUMP(JUMP_ASSERT_NOT, jump_assert_not, ctx->pattern+2);
+ if (ret) {
+ RETURN_ON_ERROR(ret);
+ RETURN_FAILURE;
+ }
+ }
+ ctx->pattern += ctx->pattern[0];
+ break;
+
+ case SRE_OP_FAILURE:
+ /* immediate failure */
+ TRACE(("|%p|%p|FAILURE\n", ctx->pattern, ctx->ptr));
+ RETURN_FAILURE;
+
+ default:
+ TRACE(("|%p|%p|UNKNOWN %d\n", ctx->pattern, ctx->ptr,
+ ctx->pattern[-1]));
+ RETURN_ERROR(SRE_ERROR_ILLEGAL);
+ }
+ }
+
+exit:
+ ctx_pos = ctx->last_ctx_pos;
+ jump = ctx->jump;
+ DATA_POP_DISCARD(ctx);
+ if (ctx_pos == -1)
+ return ret;
+ DATA_LOOKUP_AT(SRE_MATCH_CONTEXT, ctx, ctx_pos);
+
+ switch (jump) {
+ case JUMP_MAX_UNTIL_2:
+ TRACE(("|%p|%p|JUMP_MAX_UNTIL_2\n", ctx->pattern, ctx->ptr));
+ goto jump_max_until_2;
+ case JUMP_MAX_UNTIL_3:
+ TRACE(("|%p|%p|JUMP_MAX_UNTIL_3\n", ctx->pattern, ctx->ptr));
+ goto jump_max_until_3;
+ case JUMP_MIN_UNTIL_2:
+ TRACE(("|%p|%p|JUMP_MIN_UNTIL_2\n", ctx->pattern, ctx->ptr));
+ goto jump_min_until_2;
+ case JUMP_MIN_UNTIL_3:
+ TRACE(("|%p|%p|JUMP_MIN_UNTIL_3\n", ctx->pattern, ctx->ptr));
+ goto jump_min_until_3;
+ case JUMP_BRANCH:
+ TRACE(("|%p|%p|JUMP_BRANCH\n", ctx->pattern, ctx->ptr));
+ goto jump_branch;
+ case JUMP_MAX_UNTIL_1:
+ TRACE(("|%p|%p|JUMP_MAX_UNTIL_1\n", ctx->pattern, ctx->ptr));
+ goto jump_max_until_1;
+ case JUMP_MIN_UNTIL_1:
+ TRACE(("|%p|%p|JUMP_MIN_UNTIL_1\n", ctx->pattern, ctx->ptr));
+ goto jump_min_until_1;
+ case JUMP_REPEAT:
+ TRACE(("|%p|%p|JUMP_REPEAT\n", ctx->pattern, ctx->ptr));
+ goto jump_repeat;
+ case JUMP_REPEAT_ONE_1:
+ TRACE(("|%p|%p|JUMP_REPEAT_ONE_1\n", ctx->pattern, ctx->ptr));
+ goto jump_repeat_one_1;
+ case JUMP_REPEAT_ONE_2:
+ TRACE(("|%p|%p|JUMP_REPEAT_ONE_2\n", ctx->pattern, ctx->ptr));
+ goto jump_repeat_one_2;
+ case JUMP_MIN_REPEAT_ONE:
+ TRACE(("|%p|%p|JUMP_MIN_REPEAT_ONE\n", ctx->pattern, ctx->ptr));
+ goto jump_min_repeat_one;
+ case JUMP_ASSERT:
+ TRACE(("|%p|%p|JUMP_ASSERT\n", ctx->pattern, ctx->ptr));
+ goto jump_assert;
+ case JUMP_ASSERT_NOT:
+ TRACE(("|%p|%p|JUMP_ASSERT_NOT\n", ctx->pattern, ctx->ptr));
+ goto jump_assert_not;
+ case JUMP_NONE:
+ TRACE(("|%p|%p|RETURN %" PY_FORMAT_SIZE_T "d\n", ctx->pattern,
+ ctx->ptr, ret));
+ break;
+ }
+
+ return ret; /* should never get here */
+}
+
+LOCAL(Py_ssize_t)
+SRE_SEARCH(SRE_STATE* state, SRE_CODE* pattern)
+{
+ SRE_CHAR* ptr = (SRE_CHAR *)state->start;
+ SRE_CHAR* end = (SRE_CHAR *)state->end;
+ Py_ssize_t status = 0;
+ Py_ssize_t prefix_len = 0;
+ Py_ssize_t prefix_skip = 0;
+ SRE_CODE* prefix = NULL;
+ SRE_CODE* charset = NULL;
+ SRE_CODE* overlap = NULL;
+ int flags = 0;
+
+ if (pattern[0] == SRE_OP_INFO) {
+ /* optimization info block */
+ /* <INFO> <1=skip> <2=flags> <3=min> <4=max> <5=prefix info> */
+
+ flags = pattern[2];
+
+ if (pattern[3] > 1) {
+ /* adjust end point (but make sure we leave at least one
+ character in there, so literal search will work) */
+ end -= pattern[3]-1;
+ if (end <= ptr)
+ end = ptr+1;
+ }
+
+ if (flags & SRE_INFO_PREFIX) {
+ /* pattern starts with a known prefix */
+ /* <length> <skip> <prefix data> <overlap data> */
+ prefix_len = pattern[5];
+ prefix_skip = pattern[6];
+ prefix = pattern + 7;
+ overlap = prefix + prefix_len - 1;
+ } else if (flags & SRE_INFO_CHARSET)
+ /* pattern starts with a character from a known set */
+ /* <charset> */
+ charset = pattern + 5;
+
+ pattern += 1 + pattern[1];
+ }
+
+ TRACE(("prefix = %p %" PY_FORMAT_SIZE_T "d %" PY_FORMAT_SIZE_T "d\n",
+ prefix, prefix_len, prefix_skip));
+ TRACE(("charset = %p\n", charset));
+
+#if defined(USE_FAST_SEARCH)
+ if (prefix_len > 1) {
+ /* pattern starts with a known prefix. use the overlap
+ table to skip forward as fast as we possibly can */
+ Py_ssize_t i = 0;
+ end = (SRE_CHAR *)state->end;
+ while (ptr < end) {
+ for (;;) {
+ if ((SRE_CODE) ptr[0] != prefix[i]) {
+ if (!i)
+ break;
+ else
+ i = overlap[i];
+ } else {
+ if (++i == prefix_len) {
+ /* found a potential match */
+ TRACE(("|%p|%p|SEARCH SCAN\n", pattern, ptr));
+ state->start = ptr + 1 - prefix_len;
+ state->ptr = ptr + 1 - prefix_len + prefix_skip;
+ if (flags & SRE_INFO_LITERAL)
+ return 1; /* we got all of it */
+ status = SRE_MATCH(state, pattern + 2*prefix_skip);
+ if (status != 0)
+ return status;
+ /* close but no cigar -- try again */
+ i = overlap[i];
+ }
+ break;
+ }
+ }
+ ptr++;
+ }
+ return 0;
+ }
+#endif
+
+ if (pattern[0] == SRE_OP_LITERAL) {
+ /* pattern starts with a literal character. this is used
+ for short prefixes, and if fast search is disabled */
+ SRE_CODE chr = pattern[1];
+ end = (SRE_CHAR *)state->end;
+ for (;;) {
+ while (ptr < end && (SRE_CODE) ptr[0] != chr)
+ ptr++;
+ if (ptr >= end)
+ return 0;
+ TRACE(("|%p|%p|SEARCH LITERAL\n", pattern, ptr));
+ state->start = ptr;
+ state->ptr = ++ptr;
+ if (flags & SRE_INFO_LITERAL)
+ return 1; /* we got all of it */
+ status = SRE_MATCH(state, pattern + 2);
+ if (status != 0)
+ break;
+ }
+ } else if (charset) {
+ /* pattern starts with a character from a known set */
+ end = (SRE_CHAR *)state->end;
+ for (;;) {
+ while (ptr < end && !SRE_CHARSET(charset, ptr[0]))
+ ptr++;
+ if (ptr >= end)
+ return 0;
+ TRACE(("|%p|%p|SEARCH CHARSET\n", pattern, ptr));
+ state->start = ptr;
+ state->ptr = ptr;
+ status = SRE_MATCH(state, pattern);
+ if (status != 0)
+ break;
+ ptr++;
+ }
+ } else
+ /* general case */
+ while (ptr <= end) {
+ TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
+ state->start = state->ptr = ptr++;
+ status = SRE_MATCH(state, pattern);
+ if (status != 0)
+ break;
+ }
+
+ return status;
+}
+
+LOCAL(int)
+SRE_LITERAL_TEMPLATE(SRE_CHAR* ptr, Py_ssize_t len)
+{
+ /* check if given string is a literal template (i.e. no escapes) */
+ while (len-- > 0)
+ if (*ptr++ == '\\')
+ return 0;
+ return 1;
+}
+
+#if !defined(SRE_RECURSIVE)
+
+/* -------------------------------------------------------------------- */
+/* factories and destructors */
+
+/* see sre.h for object declarations */
+static PyObject*pattern_new_match(PatternObject*, SRE_STATE*, int);
+static PyObject*pattern_scanner(PatternObject*, PyObject*);
+
+static PyObject *
+sre_codesize(PyObject* self, PyObject *unused)
+{
+ return PyInt_FromSize_t(sizeof(SRE_CODE));
+}
+
+static PyObject *
+sre_getlower(PyObject* self, PyObject* args)
+{
+ int character, flags;
+ if (!PyArg_ParseTuple(args, "ii", &character, &flags))
+ return NULL;
+ if (flags & SRE_FLAG_LOCALE)
+ return Py_BuildValue("i", sre_lower_locale(character));
+ if (flags & SRE_FLAG_UNICODE)
+#if defined(HAVE_UNICODE)
+ return Py_BuildValue("i", sre_lower_unicode(character));
+#else
+ return Py_BuildValue("i", sre_lower_locale(character));
+#endif
+ return Py_BuildValue("i", sre_lower(character));
+}
+
+LOCAL(void)
+state_reset(SRE_STATE* state)
+{
+ /* FIXME: dynamic! */
+ /*memset(state->mark, 0, sizeof(*state->mark) * SRE_MARK_SIZE);*/
+
+ state->lastmark = -1;
+ state->lastindex = -1;
+
+ state->repeat = NULL;
+
+ data_stack_dealloc(state);
+}
+
+static void*
+getstring(PyObject* string, Py_ssize_t* p_length, int* p_charsize)
+{
+ /* given a python object, return a data pointer, a length (in
+ characters), and a character size. return NULL if the object
+ is not a string (or not compatible) */
+
+ PyBufferProcs *buffer;
+ Py_ssize_t size, bytes;
+ int charsize;
+ void* ptr;
+
+#if defined(HAVE_UNICODE)
+ if (PyUnicode_Check(string)) {
+ /* unicode strings doesn't always support the buffer interface */
+ ptr = (void*) PyUnicode_AS_DATA(string);
+ /* bytes = PyUnicode_GET_DATA_SIZE(string); */
+ size = PyUnicode_GET_SIZE(string);
+ charsize = sizeof(Py_UNICODE);
+
+ } else {
+#endif
+
+ /* get pointer to string buffer */
+ buffer = Py_TYPE(string)->tp_as_buffer;
+ if (!buffer || !buffer->bf_getreadbuffer || !buffer->bf_getsegcount ||
+ buffer->bf_getsegcount(string, NULL) != 1) {
+ PyErr_SetString(PyExc_TypeError, "expected string or buffer");
+ return NULL;
+ }
+
+ /* determine buffer size */
+ bytes = buffer->bf_getreadbuffer(string, 0, &ptr);
+ if (bytes < 0) {
+ PyErr_SetString(PyExc_TypeError, "buffer has negative size");
+ return NULL;
+ }
+
+ /* determine character size */
+#if PY_VERSION_HEX >= 0x01060000
+ size = PyObject_Size(string);
+#else
+ size = PyObject_Length(string);
+#endif
+
+ if (PyString_Check(string) || bytes == size)
+ charsize = 1;
+#if defined(HAVE_UNICODE)
+ else if (bytes == (Py_ssize_t) (size * sizeof(Py_UNICODE)))
+ charsize = sizeof(Py_UNICODE);
+#endif
+ else {
+ PyErr_SetString(PyExc_TypeError, "buffer size mismatch");
+ return NULL;
+ }
+
+#if defined(HAVE_UNICODE)
+ }
+#endif
+
+ *p_length = size;
+ *p_charsize = charsize;
+
+ return ptr;
+}
+
+LOCAL(PyObject*)
+state_init(SRE_STATE* state, PatternObject* pattern, PyObject* string,
+ Py_ssize_t start, Py_ssize_t end)
+{
+ /* prepare state object */
+
+ Py_ssize_t length;
+ int charsize;
+ void* ptr;
+
+ memset(state, 0, sizeof(SRE_STATE));
+
+ state->lastmark = -1;
+ state->lastindex = -1;
+
+ ptr = getstring(string, &length, &charsize);
+ if (!ptr)
+ return NULL;
+
+ /* adjust boundaries */
+ if (start < 0)
+ start = 0;
+ else if (start > length)
+ start = length;
+
+ if (end < 0)
+ end = 0;
+ else if (end > length)
+ end = length;
+
+ state->charsize = charsize;
+
+ state->beginning = ptr;
+
+ state->start = (void*) ((char*) ptr + start * state->charsize);
+ state->end = (void*) ((char*) ptr + end * state->charsize);
+
+ Py_INCREF(string);
+ state->string = string;
+ state->pos = start;
+ state->endpos = end;
+
+ if (pattern->flags & SRE_FLAG_LOCALE)
+ state->lower = sre_lower_locale;
+ else if (pattern->flags & SRE_FLAG_UNICODE)
+#if defined(HAVE_UNICODE)
+ state->lower = sre_lower_unicode;
+#else
+ state->lower = sre_lower_locale;
+#endif
+ else
+ state->lower = sre_lower;
+
+ return string;
+}
+
+LOCAL(void)
+state_fini(SRE_STATE* state)
+{
+ Py_XDECREF(state->string);
+ data_stack_dealloc(state);
+}
+
+/* calculate offset from start of string */
+#define STATE_OFFSET(state, member)\
+ (((char*)(member) - (char*)(state)->beginning) / (state)->charsize)
+
+LOCAL(PyObject*)
+state_getslice(SRE_STATE* state, Py_ssize_t index, PyObject* string, int empty)
+{
+ Py_ssize_t i, j;
+
+ index = (index - 1) * 2;
+
+ if (string == Py_None || index >= state->lastmark || !state->mark[index] || !state->mark[index+1]) {
+ if (empty)
+ /* want empty string */
+ i = j = 0;
+ else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ } else {
+ i = STATE_OFFSET(state, state->mark[index]);
+ j = STATE_OFFSET(state, state->mark[index+1]);
+ }
+
+ return PySequence_GetSlice(string, i, j);
+}
+
+static void
+pattern_error(int status)
+{
+ switch (status) {
+ case SRE_ERROR_RECURSION_LIMIT:
+ PyErr_SetString(
+ PyExc_RuntimeError,
+ "maximum recursion limit exceeded"
+ );
+ break;
+ case SRE_ERROR_MEMORY:
+ PyErr_NoMemory();
+ break;
+ case SRE_ERROR_INTERRUPTED:
+ /* An exception has already been raised, so let it fly */
+ break;
+ default:
+ /* other error codes indicate compiler/engine bugs */
+ PyErr_SetString(
+ PyExc_RuntimeError,
+ "internal error in regular expression engine"
+ );
+ }
+}
+
+static void
+pattern_dealloc(PatternObject* self)
+{
+ if (self->weakreflist != NULL)
+ PyObject_ClearWeakRefs((PyObject *) self);
+ Py_XDECREF(self->pattern);
+ Py_XDECREF(self->groupindex);
+ Py_XDECREF(self->indexgroup);
+ PyObject_DEL(self);
+}
+
+static int
+check_args_size(const char *name, PyObject* args, PyObject* kw, int n)
+{
+ Py_ssize_t m = PyTuple_GET_SIZE(args) + (kw ? PyDict_Size(kw) : 0);
+ if (m <= n)
+ return 1;
+ PyErr_Format(PyExc_TypeError,
+ "%s() takes at most %d positional arguments (%zd given)",
+ name, n, m);
+ return 0;
+}
+
+static PyObject*
+fix_string_param(PyObject *string, PyObject *string2, const char *oldname)
+{
+ if (string2 != NULL) {
+ char buf[100];
+ if (string != NULL) {
+ PyErr_Format(PyExc_TypeError,
+ "Argument given by name ('%s') and position (1)",
+ oldname);
+ return NULL;
+ }
+ sprintf(buf, "The '%s' keyword parameter name is deprecated. "
+ "Use 'string' instead.", oldname);
+ if (PyErr_Warn(PyExc_DeprecationWarning, buf) < 0)
+ return NULL;
+ return string2;
+ }
+ if (string == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "Required argument 'string' (pos 1) not found");
+ return NULL;
+ }
+ return string;
+}
+
+static PyObject*
+pattern_match(PatternObject* self, PyObject* args, PyObject* kw)
+{
+ SRE_STATE state;
+ int status;
+
+ PyObject *string = NULL, *string2 = NULL;
+ Py_ssize_t start = 0;
+ Py_ssize_t end = PY_SSIZE_T_MAX;
+ static char* kwlist[] = { "string", "pos", "endpos", "pattern", NULL };
+ if (!check_args_size("match", args, kw, 3))
+ return NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "|OnnO:match", kwlist,
+ &string, &start, &end, &string2))
+ return NULL;
+
+ string = fix_string_param(string, string2, "pattern");
+ if (!string)
+ return NULL;
+
+ string = state_init(&state, self, string, start, end);
+ if (!string)
+ return NULL;
+
+ state.ptr = state.start;
+
+ TRACE(("|%p|%p|MATCH\n", PatternObject_GetCode(self), state.ptr));
+
+ if (state.charsize == 1) {
+ status = sre_match(&state, PatternObject_GetCode(self));
+ } else {
+#if defined(HAVE_UNICODE)
+ status = sre_umatch(&state, PatternObject_GetCode(self));
+#endif
+ }
+
+ TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr));
+ if (PyErr_Occurred())
+ return NULL;
+
+ state_fini(&state);
+
+ return pattern_new_match(self, &state, status);
+}
+
+static PyObject*
+pattern_search(PatternObject* self, PyObject* args, PyObject* kw)
+{
+ SRE_STATE state;
+ int status;
+
+ PyObject *string = NULL, *string2 = NULL;
+ Py_ssize_t start = 0;
+ Py_ssize_t end = PY_SSIZE_T_MAX;
+ static char* kwlist[] = { "string", "pos", "endpos", "pattern", NULL };
+ if (!check_args_size("search", args, kw, 3))
+ return NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "|OnnO:search", kwlist,
+ &string, &start, &end, &string2))
+ return NULL;
+
+ string = fix_string_param(string, string2, "pattern");
+ if (!string)
+ return NULL;
+
+ string = state_init(&state, self, string, start, end);
+ if (!string)
+ return NULL;
+
+ TRACE(("|%p|%p|SEARCH\n", PatternObject_GetCode(self), state.ptr));
+
+ if (state.charsize == 1) {
+ status = sre_search(&state, PatternObject_GetCode(self));
+ } else {
+#if defined(HAVE_UNICODE)
+ status = sre_usearch(&state, PatternObject_GetCode(self));
+#endif
+ }
+
+ TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr));
+
+ state_fini(&state);
+
+ if (PyErr_Occurred())
+ return NULL;
+
+ return pattern_new_match(self, &state, status);
+}
+
+static PyObject*
+call(char* module, char* function, PyObject* args)
+{
+ PyObject* name;
+ PyObject* mod;
+ PyObject* func;
+ PyObject* result;
+
+ if (!args)
+ return NULL;
+ name = PyString_FromString(module);
+ if (!name)
+ return NULL;
+ mod = PyImport_Import(name);
+ Py_DECREF(name);
+ if (!mod)
+ return NULL;
+ func = PyObject_GetAttrString(mod, function);
+ Py_DECREF(mod);
+ if (!func)
+ return NULL;
+ result = PyObject_CallObject(func, args);
+ Py_DECREF(func);
+ Py_DECREF(args);
+ return result;
+}
+
+#ifdef USE_BUILTIN_COPY
+static int
+deepcopy(PyObject** object, PyObject* memo)
+{
+ PyObject* copy;
+
+ copy = call(
+ "copy", "deepcopy",
+ PyTuple_Pack(2, *object, memo)
+ );
+ if (!copy)
+ return 0;
+
+ Py_DECREF(*object);
+ *object = copy;
+
+ return 1; /* success */
+}
+#endif
+
+static PyObject*
+join_list(PyObject* list, PyObject* string)
+{
+ /* join list elements */
+
+ PyObject* joiner;
+#if PY_VERSION_HEX >= 0x01060000
+ PyObject* function;
+ PyObject* args;
+#endif
+ PyObject* result;
+
+ joiner = PySequence_GetSlice(string, 0, 0);
+ if (!joiner)
+ return NULL;
+
+ if (PyList_GET_SIZE(list) == 0) {
+ Py_DECREF(list);
+ return joiner;
+ }
+
+#if PY_VERSION_HEX >= 0x01060000
+ function = PyObject_GetAttrString(joiner, "join");
+ if (!function) {
+ Py_DECREF(joiner);
+ return NULL;
+ }
+ args = PyTuple_New(1);
+ if (!args) {
+ Py_DECREF(function);
+ Py_DECREF(joiner);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(args, 0, list);
+ result = PyObject_CallObject(function, args);
+ Py_DECREF(args); /* also removes list */
+ Py_DECREF(function);
+#else
+ result = call(
+ "string", "join",
+ PyTuple_Pack(2, list, joiner)
+ );
+#endif
+ Py_DECREF(joiner);
+
+ return result;
+}
+
+static PyObject*
+pattern_findall(PatternObject* self, PyObject* args, PyObject* kw)
+{
+ SRE_STATE state;
+ PyObject* list;
+ int status;
+ Py_ssize_t i, b, e;
+
+ PyObject *string = NULL, *string2 = NULL;
+ Py_ssize_t start = 0;
+ Py_ssize_t end = PY_SSIZE_T_MAX;
+ static char* kwlist[] = { "string", "pos", "endpos", "source", NULL };
+ if (!check_args_size("findall", args, kw, 3))
+ return NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "|OnnO:findall", kwlist,
+ &string, &start, &end, &string2))
+ return NULL;
+
+ string = fix_string_param(string, string2, "source");
+ if (!string)
+ return NULL;
+
+ string = state_init(&state, self, string, start, end);
+ if (!string)
+ return NULL;
+
+ list = PyList_New(0);
+ if (!list) {
+ state_fini(&state);
+ return NULL;
+ }
+
+ while (state.start <= state.end) {
+
+ PyObject* item;
+
+ state_reset(&state);
+
+ state.ptr = state.start;
+
+ if (state.charsize == 1) {
+ status = sre_search(&state, PatternObject_GetCode(self));
+ } else {
+#if defined(HAVE_UNICODE)
+ status = sre_usearch(&state, PatternObject_GetCode(self));
+#endif
+ }
+
+ if (PyErr_Occurred())
+ goto error;
+
+ if (status <= 0) {
+ if (status == 0)
+ break;
+ pattern_error(status);
+ goto error;
+ }
+
+ /* don't bother to build a match object */
+ switch (self->groups) {
+ case 0:
+ b = STATE_OFFSET(&state, state.start);
+ e = STATE_OFFSET(&state, state.ptr);
+ item = PySequence_GetSlice(string, b, e);
+ if (!item)
+ goto error;
+ break;
+ case 1:
+ item = state_getslice(&state, 1, string, 1);
+ if (!item)
+ goto error;
+ break;
+ default:
+ item = PyTuple_New(self->groups);
+ if (!item)
+ goto error;
+ for (i = 0; i < self->groups; i++) {
+ PyObject* o = state_getslice(&state, i+1, string, 1);
+ if (!o) {
+ Py_DECREF(item);
+ goto error;
+ }
+ PyTuple_SET_ITEM(item, i, o);
+ }
+ break;
+ }
+
+ status = PyList_Append(list, item);
+ Py_DECREF(item);
+ if (status < 0)
+ goto error;
+
+ if (state.ptr == state.start)
+ state.start = (void*) ((char*) state.ptr + state.charsize);
+ else
+ state.start = state.ptr;
+
+ }
+
+ state_fini(&state);
+ return list;
+
+error:
+ Py_DECREF(list);
+ state_fini(&state);
+ return NULL;
+
+}
+
+#if PY_VERSION_HEX >= 0x02020000
+static PyObject*
+pattern_finditer(PatternObject* pattern, PyObject* args)
+{
+ PyObject* scanner;
+ PyObject* search;
+ PyObject* iterator;
+
+ scanner = pattern_scanner(pattern, args);
+ if (!scanner)
+ return NULL;
+
+ search = PyObject_GetAttrString(scanner, "search");
+ Py_DECREF(scanner);
+ if (!search)
+ return NULL;
+
+ iterator = PyCallIter_New(search, Py_None);
+ Py_DECREF(search);
+
+ return iterator;
+}
+#endif
+
+static PyObject*
+pattern_split(PatternObject* self, PyObject* args, PyObject* kw)
+{
+ SRE_STATE state;
+ PyObject* list;
+ PyObject* item;
+ int status;
+ Py_ssize_t n;
+ Py_ssize_t i;
+ void* last;
+
+ PyObject *string = NULL, *string2 = NULL;
+ Py_ssize_t maxsplit = 0;
+ static char* kwlist[] = { "string", "maxsplit", "source", NULL };
+ if (!check_args_size("split", args, kw, 2))
+ return NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "|OnO:split", kwlist,
+ &string, &maxsplit, &string2))
+ return NULL;
+
+ string = fix_string_param(string, string2, "source");
+ if (!string)
+ return NULL;
+
+ string = state_init(&state, self, string, 0, PY_SSIZE_T_MAX);
+ if (!string)
+ return NULL;
+
+ list = PyList_New(0);
+ if (!list) {
+ state_fini(&state);
+ return NULL;
+ }
+
+ n = 0;
+ last = state.start;
+
+ while (!maxsplit || n < maxsplit) {
+
+ state_reset(&state);
+
+ state.ptr = state.start;
+
+ if (state.charsize == 1) {
+ status = sre_search(&state, PatternObject_GetCode(self));
+ } else {
+#if defined(HAVE_UNICODE)
+ status = sre_usearch(&state, PatternObject_GetCode(self));
+#endif
+ }
+
+ if (PyErr_Occurred())
+ goto error;
+
+ if (status <= 0) {
+ if (status == 0)
+ break;
+ pattern_error(status);
+ goto error;
+ }
+
+ if (state.start == state.ptr) {
+ if (last == state.end)
+ break;
+ /* skip one character */
+ state.start = (void*) ((char*) state.ptr + state.charsize);
+ continue;
+ }
+
+ /* get segment before this match */
+ item = PySequence_GetSlice(
+ string, STATE_OFFSET(&state, last),
+ STATE_OFFSET(&state, state.start)
+ );
+ if (!item)
+ goto error;
+ status = PyList_Append(list, item);
+ Py_DECREF(item);
+ if (status < 0)
+ goto error;
+
+ /* add groups (if any) */
+ for (i = 0; i < self->groups; i++) {
+ item = state_getslice(&state, i+1, string, 0);
+ if (!item)
+ goto error;
+ status = PyList_Append(list, item);
+ Py_DECREF(item);
+ if (status < 0)
+ goto error;
+ }
+
+ n = n + 1;
+
+ last = state.start = state.ptr;
+
+ }
+
+ /* get segment following last match (even if empty) */
+ item = PySequence_GetSlice(
+ string, STATE_OFFSET(&state, last), state.endpos
+ );
+ if (!item)
+ goto error;
+ status = PyList_Append(list, item);
+ Py_DECREF(item);
+ if (status < 0)
+ goto error;
+
+ state_fini(&state);
+ return list;
+
+error:
+ Py_DECREF(list);
+ state_fini(&state);
+ return NULL;
+
+}
+
+static PyObject*
+pattern_subx(PatternObject* self, PyObject* ptemplate, PyObject* string,
+ Py_ssize_t count, Py_ssize_t subn)
+{
+ SRE_STATE state;
+ PyObject* list;
+ PyObject* item;
+ PyObject* filter;
+ PyObject* args;
+ PyObject* match;
+ void* ptr;
+ int status;
+ Py_ssize_t n;
+ Py_ssize_t i, b, e;
+ int bint;
+ int filter_is_callable;
+
+ if (PyCallable_Check(ptemplate)) {
+ /* sub/subn takes either a function or a template */
+ filter = ptemplate;
+ Py_INCREF(filter);
+ filter_is_callable = 1;
+ } else {
+ /* if not callable, check if it's a literal string */
+ int literal;
+ ptr = getstring(ptemplate, &n, &bint);
+ b = bint;
+ if (ptr) {
+ if (b == 1) {
+ literal = sre_literal_template((unsigned char *)ptr, n);
+ } else {
+#if defined(HAVE_UNICODE)
+ literal = sre_uliteral_template((Py_UNICODE *)ptr, n);
+#endif
+ }
+ } else {
+ PyErr_Clear();
+ literal = 0;
+ }
+ if (literal) {
+ filter = ptemplate;
+ Py_INCREF(filter);
+ filter_is_callable = 0;
+ } else {
+ /* not a literal; hand it over to the template compiler */
+ filter = call(
+ SRE_PY_MODULE, "_subx",
+ PyTuple_Pack(2, self, ptemplate)
+ );
+ if (!filter)
+ return NULL;
+ filter_is_callable = PyCallable_Check(filter);
+ }
+ }
+
+ string = state_init(&state, self, string, 0, PY_SSIZE_T_MAX);
+ if (!string) {
+ Py_DECREF(filter);
+ return NULL;
+ }
+
+ list = PyList_New(0);
+ if (!list) {
+ Py_DECREF(filter);
+ state_fini(&state);
+ return NULL;
+ }
+
+ n = i = 0;
+
+ while (!count || n < count) {
+
+ state_reset(&state);
+
+ state.ptr = state.start;
+
+ if (state.charsize == 1) {
+ status = sre_search(&state, PatternObject_GetCode(self));
+ } else {
+#if defined(HAVE_UNICODE)
+ status = sre_usearch(&state, PatternObject_GetCode(self));
+#endif
+ }
+
+ if (PyErr_Occurred())
+ goto error;
+
+ if (status <= 0) {
+ if (status == 0)
+ break;
+ pattern_error(status);
+ goto error;
+ }
+
+ b = STATE_OFFSET(&state, state.start);
+ e = STATE_OFFSET(&state, state.ptr);
+
+ if (i < b) {
+ /* get segment before this match */
+ item = PySequence_GetSlice(string, i, b);
+ if (!item)
+ goto error;
+ status = PyList_Append(list, item);
+ Py_DECREF(item);
+ if (status < 0)
+ goto error;
+
+ } else if (i == b && i == e && n > 0)
+ /* ignore empty match on latest position */
+ goto next;
+
+ if (filter_is_callable) {
+ /* pass match object through filter */
+ match = pattern_new_match(self, &state, 1);
+ if (!match)
+ goto error;
+ args = PyTuple_Pack(1, match);
+ if (!args) {
+ Py_DECREF(match);
+ goto error;
+ }
+ item = PyObject_CallObject(filter, args);
+ Py_DECREF(args);
+ Py_DECREF(match);
+ if (!item)
+ goto error;
+ } else {
+ /* filter is literal string */
+ item = filter;
+ Py_INCREF(item);
+ }
+
+ /* add to list */
+ if (item != Py_None) {
+ status = PyList_Append(list, item);
+ Py_DECREF(item);
+ if (status < 0)
+ goto error;
+ }
+
+ i = e;
+ n = n + 1;
+
+next:
+ /* move on */
+ if (state.ptr == state.start)
+ state.start = (void*) ((char*) state.ptr + state.charsize);
+ else
+ state.start = state.ptr;
+
+ }
+
+ /* get segment following last match */
+ if (i < state.endpos) {
+ item = PySequence_GetSlice(string, i, state.endpos);
+ if (!item)
+ goto error;
+ status = PyList_Append(list, item);
+ Py_DECREF(item);
+ if (status < 0)
+ goto error;
+ }
+
+ state_fini(&state);
+
+ Py_DECREF(filter);
+
+ /* convert list to single string (also removes list) */
+ item = join_list(list, string);
+
+ if (!item)
+ return NULL;
+
+ if (subn)
+ return Py_BuildValue("Nn", item, n);
+
+ return item;
+
+error:
+ Py_DECREF(list);
+ state_fini(&state);
+ Py_DECREF(filter);
+ return NULL;
+
+}
+
+static PyObject*
+pattern_sub(PatternObject* self, PyObject* args, PyObject* kw)
+{
+ PyObject* ptemplate;
+ PyObject* string;
+ Py_ssize_t count = 0;
+ static char* kwlist[] = { "repl", "string", "count", NULL };
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|n:sub", kwlist,
+ &ptemplate, &string, &count))
+ return NULL;
+
+ return pattern_subx(self, ptemplate, string, count, 0);
+}
+
+static PyObject*
+pattern_subn(PatternObject* self, PyObject* args, PyObject* kw)
+{
+ PyObject* ptemplate;
+ PyObject* string;
+ Py_ssize_t count = 0;
+ static char* kwlist[] = { "repl", "string", "count", NULL };
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|n:subn", kwlist,
+ &ptemplate, &string, &count))
+ return NULL;
+
+ return pattern_subx(self, ptemplate, string, count, 1);
+}
+
+static PyObject*
+pattern_copy(PatternObject* self, PyObject *unused)
+{
+#ifdef USE_BUILTIN_COPY
+ PatternObject* copy;
+ int offset;
+
+ copy = PyObject_NEW_VAR(PatternObject, &Pattern_Type, self->codesize);
+ if (!copy)
+ return NULL;
+
+ offset = offsetof(PatternObject, groups);
+
+ Py_XINCREF(self->groupindex);
+ Py_XINCREF(self->indexgroup);
+ Py_XINCREF(self->pattern);
+
+ memcpy((char*) copy + offset, (char*) self + offset,
+ sizeof(PatternObject) + self->codesize * sizeof(SRE_CODE) - offset);
+ copy->weakreflist = NULL;
+
+ return (PyObject*) copy;
+#else
+ PyErr_SetString(PyExc_TypeError, "cannot copy this pattern object");
+ return NULL;
+#endif
+}
+
+static PyObject*
+pattern_deepcopy(PatternObject* self, PyObject* memo)
+{
+#ifdef USE_BUILTIN_COPY
+ PatternObject* copy;
+
+ copy = (PatternObject*) pattern_copy(self);
+ if (!copy)
+ return NULL;
+
+ if (!deepcopy(©->groupindex, memo) ||
+ !deepcopy(©->indexgroup, memo) ||
+ !deepcopy(©->pattern, memo)) {
+ Py_DECREF(copy);
+ return NULL;
+ }
+
+#else
+ PyErr_SetString(PyExc_TypeError, "cannot deepcopy this pattern object");
+ return NULL;
+#endif
+}
+
+PyDoc_STRVAR(pattern_match_doc,
+"match(string[, pos[, endpos]]) --> match object or None.\n\
+ Matches zero or more characters at the beginning of the string");
+
+PyDoc_STRVAR(pattern_search_doc,
+"search(string[, pos[, endpos]]) --> match object or None.\n\
+ Scan through string looking for a match, and return a corresponding\n\
+ match object instance. Return None if no position in the string matches.");
+
+PyDoc_STRVAR(pattern_split_doc,
+"split(string[, maxsplit = 0]) --> list.\n\
+ Split string by the occurrences of pattern.");
+
+PyDoc_STRVAR(pattern_findall_doc,
+"findall(string[, pos[, endpos]]) --> list.\n\
+ Return a list of all non-overlapping matches of pattern in string.");
+
+PyDoc_STRVAR(pattern_finditer_doc,
+"finditer(string[, pos[, endpos]]) --> iterator.\n\
+ Return an iterator over all non-overlapping matches for the \n\
+ RE pattern in string. For each match, the iterator returns a\n\
+ match object.");
+
+PyDoc_STRVAR(pattern_sub_doc,
+"sub(repl, string[, count = 0]) --> newstring\n\
+ Return the string obtained by replacing the leftmost non-overlapping\n\
+ occurrences of pattern in string by the replacement repl.");
+
+PyDoc_STRVAR(pattern_subn_doc,
+"subn(repl, string[, count = 0]) --> (newstring, number of subs)\n\
+ Return the tuple (new_string, number_of_subs_made) found by replacing\n\
+ the leftmost non-overlapping occurrences of pattern with the\n\
+ replacement repl.");
+
+PyDoc_STRVAR(pattern_doc, "Compiled regular expression objects");
+
+static PyMethodDef pattern_methods[] = {
+ {"match", (PyCFunction) pattern_match, METH_VARARGS|METH_KEYWORDS,
+ pattern_match_doc},
+ {"search", (PyCFunction) pattern_search, METH_VARARGS|METH_KEYWORDS,
+ pattern_search_doc},
+ {"sub", (PyCFunction) pattern_sub, METH_VARARGS|METH_KEYWORDS,
+ pattern_sub_doc},
+ {"subn", (PyCFunction) pattern_subn, METH_VARARGS|METH_KEYWORDS,
+ pattern_subn_doc},
+ {"split", (PyCFunction) pattern_split, METH_VARARGS|METH_KEYWORDS,
+ pattern_split_doc},
+ {"findall", (PyCFunction) pattern_findall, METH_VARARGS|METH_KEYWORDS,
+ pattern_findall_doc},
+#if PY_VERSION_HEX >= 0x02020000
+ {"finditer", (PyCFunction) pattern_finditer, METH_VARARGS,
+ pattern_finditer_doc},
+#endif
+ {"scanner", (PyCFunction) pattern_scanner, METH_VARARGS},
+ {"__copy__", (PyCFunction) pattern_copy, METH_NOARGS},
+ {"__deepcopy__", (PyCFunction) pattern_deepcopy, METH_O},
+ {NULL, NULL}
+};
+
+#define PAT_OFF(x) offsetof(PatternObject, x)
+static PyMemberDef pattern_members[] = {
+ {"pattern", T_OBJECT, PAT_OFF(pattern), READONLY},
+ {"flags", T_INT, PAT_OFF(flags), READONLY},
+ {"groups", T_PYSSIZET, PAT_OFF(groups), READONLY},
+ {"groupindex", T_OBJECT, PAT_OFF(groupindex), READONLY},
+ {NULL} /* Sentinel */
+};
+
+statichere PyTypeObject Pattern_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, "_" SRE_MODULE ".SRE_Pattern",
+ sizeof(PatternObject), sizeof(SRE_CODE),
+ (destructor)pattern_dealloc, /*tp_dealloc*/
+ 0, /* tp_print */
+ 0, /* tp_getattrn */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ pattern_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ offsetof(PatternObject, weakreflist), /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ pattern_methods, /* tp_methods */
+ pattern_members, /* tp_members */
+};
+
+static int _validate(PatternObject *self); /* Forward */
+
+static PyObject *
+_compile(PyObject* self_, PyObject* args)
+{
+ /* "compile" pattern descriptor to pattern object */
+
+ PatternObject* self;
+ Py_ssize_t i, n;
+
+ PyObject* pattern;
+ int flags = 0;
+ PyObject* code;
+ Py_ssize_t groups = 0;
+ PyObject* groupindex = NULL;
+ PyObject* indexgroup = NULL;
+ if (!PyArg_ParseTuple(args, "OiO!|nOO", &pattern, &flags,
+ &PyList_Type, &code, &groups,
+ &groupindex, &indexgroup))
+ return NULL;
+
+ n = PyList_GET_SIZE(code);
+ /* coverity[ampersand_in_size] */
+ self = PyObject_NEW_VAR(PatternObject, &Pattern_Type, n);
+ if (!self)
+ return NULL;
+ self->weakreflist = NULL;
+ self->pattern = NULL;
+ self->groupindex = NULL;
+ self->indexgroup = NULL;
+
+ self->codesize = n;
+
+ for (i = 0; i < n; i++) {
+ PyObject *o = PyList_GET_ITEM(code, i);
+ unsigned long value = PyInt_Check(o) ? (unsigned long)PyInt_AsLong(o)
+ : PyLong_AsUnsignedLong(o);
+ if (value == (unsigned long)-1 && PyErr_Occurred()) {
+ if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
+ PyErr_SetString(PyExc_OverflowError,
+ "regular expression code size limit exceeded");
+ }
+ break;
+ }
+ self->code[i] = (SRE_CODE) value;
+ if ((unsigned long) self->code[i] != value) {
+ PyErr_SetString(PyExc_OverflowError,
+ "regular expression code size limit exceeded");
+ break;
+ }
+ }
+
+ if (PyErr_Occurred()) {
+ Py_DECREF(self);
+ return NULL;
+ }
+
+ Py_INCREF(pattern);
+ self->pattern = pattern;
+
+ self->flags = flags;
+
+ self->groups = groups;
+
+ Py_XINCREF(groupindex);
+ self->groupindex = groupindex;
+
+ Py_XINCREF(indexgroup);
+ self->indexgroup = indexgroup;
+
+ self->weakreflist = NULL;
+
+ if (!_validate(self)) {
+ Py_DECREF(self);
+ return NULL;
+ }
+
+ return (PyObject*) self;
+}
+
+/* -------------------------------------------------------------------- */
+/* Code validation */
+
+/* To learn more about this code, have a look at the _compile() function in
+ Lib/sre_compile.py. The validation functions below checks the code array
+ for conformance with the code patterns generated there.
+
+ The nice thing about the generated code is that it is position-independent:
+ all jumps are relative jumps forward. Also, jumps don't cross each other:
+ the target of a later jump is always earlier than the target of an earlier
+ jump. IOW, this is okay:
+
+ J---------J-------T--------T
+ \ \_____/ /
+ \______________________/
+
+ but this is not:
+
+ J---------J-------T--------T
+ \_________\_____/ /
+ \____________/
+
+ It also helps that SRE_CODE is always an unsigned type.
+*/
+
+/* Defining this one enables tracing of the validator */
+#undef VVERBOSE
+
+/* Trace macro for the validator */
+#if defined(VVERBOSE)
+#define VTRACE(v) printf v
+#else
+#define VTRACE(v) do {} while(0) /* do nothing */
+#endif
+
+/* Report failure */
+#define FAIL do { VTRACE(("FAIL: %d\n", __LINE__)); return 0; } while (0)
+
+/* Extract opcode, argument, or skip count from code array */
+#define GET_OP \
+ do { \
+ VTRACE(("%p: ", code)); \
+ if (code >= end) FAIL; \
+ op = *code++; \
+ VTRACE(("%lu (op)\n", (unsigned long)op)); \
+ } while (0)
+#define GET_ARG \
+ do { \
+ VTRACE(("%p= ", code)); \
+ if (code >= end) FAIL; \
+ arg = *code++; \
+ VTRACE(("%lu (arg)\n", (unsigned long)arg)); \
+ } while (0)
+#define GET_SKIP_ADJ(adj) \
+ do { \
+ VTRACE(("%p= ", code)); \
+ if (code >= end) FAIL; \
+ skip = *code; \
+ VTRACE(("%lu (skip to %p)\n", \
+ (unsigned long)skip, code+skip)); \
+ if (skip-adj > end-code) \
+ FAIL; \
+ code++; \
+ } while (0)
+#define GET_SKIP GET_SKIP_ADJ(0)
+
+static int
+_validate_charset(SRE_CODE *code, SRE_CODE *end)
+{
+ /* Some variables are manipulated by the macros above */
+ SRE_CODE op;
+ SRE_CODE arg;
+ SRE_CODE offset;
+ int i;
+
+ while (code < end) {
+ GET_OP;
+ switch (op) {
+
+ case SRE_OP_NEGATE:
+ break;
+
+ case SRE_OP_LITERAL:
+ GET_ARG;
+ break;
+
+ case SRE_OP_RANGE:
+ GET_ARG;
+ GET_ARG;
+ break;
+
+ case SRE_OP_CHARSET:
+ offset = 32/sizeof(SRE_CODE); /* 32-byte bitmap */
+ if (offset > end-code)
+ FAIL;
+ code += offset;
+ break;
+
+ case SRE_OP_BIGCHARSET:
+ GET_ARG; /* Number of blocks */
+ offset = 256/sizeof(SRE_CODE); /* 256-byte table */
+ if (offset > end-code)
+ FAIL;
+ /* Make sure that each byte points to a valid block */
+ for (i = 0; i < 256; i++) {
+ if (((unsigned char *)code)[i] >= arg)
+ FAIL;
+ }
+ code += offset;
+ offset = arg * 32/sizeof(SRE_CODE); /* 32-byte bitmap times arg */
+ if (offset > end-code)
+ FAIL;
+ code += offset;
+ break;
+
+ case SRE_OP_CATEGORY:
+ GET_ARG;
+ switch (arg) {
+ case SRE_CATEGORY_DIGIT:
+ case SRE_CATEGORY_NOT_DIGIT:
+ case SRE_CATEGORY_SPACE:
+ case SRE_CATEGORY_NOT_SPACE:
+ case SRE_CATEGORY_WORD:
+ case SRE_CATEGORY_NOT_WORD:
+ case SRE_CATEGORY_LINEBREAK:
+ case SRE_CATEGORY_NOT_LINEBREAK:
+ case SRE_CATEGORY_LOC_WORD:
+ case SRE_CATEGORY_LOC_NOT_WORD:
+ case SRE_CATEGORY_UNI_DIGIT:
+ case SRE_CATEGORY_UNI_NOT_DIGIT:
+ case SRE_CATEGORY_UNI_SPACE:
+ case SRE_CATEGORY_UNI_NOT_SPACE:
+ case SRE_CATEGORY_UNI_WORD:
+ case SRE_CATEGORY_UNI_NOT_WORD:
+ case SRE_CATEGORY_UNI_LINEBREAK:
+ case SRE_CATEGORY_UNI_NOT_LINEBREAK:
+ break;
+ default:
+ FAIL;
+ }
+ break;
+
+ default:
+ FAIL;
+
+ }
+ }
+
+ return 1;
+}
+
+static int
+_validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups)
+{
+ /* Some variables are manipulated by the macros above */
+ SRE_CODE op;
+ SRE_CODE arg;
+ SRE_CODE skip;
+
+ VTRACE(("code=%p, end=%p\n", code, end));
+
+ if (code > end)
+ FAIL;
+
+ while (code < end) {
+ GET_OP;
+ switch (op) {
+
+ case SRE_OP_MARK:
+ /* We don't check whether marks are properly nested; the
+ sre_match() code is robust even if they don't, and the worst
+ you can get is nonsensical match results. */
+ GET_ARG;
+ if (arg > 2*groups+1) {
+ VTRACE(("arg=%d, groups=%d\n", (int)arg, (int)groups));
+ FAIL;
+ }
+ break;
+
+ case SRE_OP_LITERAL:
+ case SRE_OP_NOT_LITERAL:
+ case SRE_OP_LITERAL_IGNORE:
+ case SRE_OP_NOT_LITERAL_IGNORE:
+ GET_ARG;
+ /* The arg is just a character, nothing to check */
+ break;
+
+ case SRE_OP_SUCCESS:
+ case SRE_OP_FAILURE:
+ /* Nothing to check; these normally end the matching process */
+ break;
+
+ case SRE_OP_AT:
+ GET_ARG;
+ switch (arg) {
+ case SRE_AT_BEGINNING:
+ case SRE_AT_BEGINNING_STRING:
+ case SRE_AT_BEGINNING_LINE:
+ case SRE_AT_END:
+ case SRE_AT_END_LINE:
+ case SRE_AT_END_STRING:
+ case SRE_AT_BOUNDARY:
+ case SRE_AT_NON_BOUNDARY:
+ case SRE_AT_LOC_BOUNDARY:
+ case SRE_AT_LOC_NON_BOUNDARY:
+ case SRE_AT_UNI_BOUNDARY:
+ case SRE_AT_UNI_NON_BOUNDARY:
+ break;
+ default:
+ FAIL;
+ }
+ break;
+
+ case SRE_OP_ANY:
+ case SRE_OP_ANY_ALL:
+ /* These have no operands */
+ break;
+
+ case SRE_OP_IN:
+ case SRE_OP_IN_IGNORE:
+ GET_SKIP;
+ /* Stop 1 before the end; we check the FAILURE below */
+ if (!_validate_charset(code, code+skip-2))
+ FAIL;
+ if (code[skip-2] != SRE_OP_FAILURE)
+ FAIL;
+ code += skip-1;
+ break;
+
+ case SRE_OP_INFO:
+ {
+ /* A minimal info field is
+ <INFO> <1=skip> <2=flags> <3=min> <4=max>;
+ If SRE_INFO_PREFIX or SRE_INFO_CHARSET is in the flags,
+ more follows. */
+ SRE_CODE flags, i;
+ SRE_CODE *newcode;
+ GET_SKIP;
+ newcode = code+skip-1;
+ GET_ARG; flags = arg;
+ GET_ARG; /* min */
+ GET_ARG; /* max */
+ /* Check that only valid flags are present */
+ if ((flags & ~(SRE_INFO_PREFIX |
+ SRE_INFO_LITERAL |
+ SRE_INFO_CHARSET)) != 0)
+ FAIL;
+ /* PREFIX and CHARSET are mutually exclusive */
+ if ((flags & SRE_INFO_PREFIX) &&
+ (flags & SRE_INFO_CHARSET))
+ FAIL;
+ /* LITERAL implies PREFIX */
+ if ((flags & SRE_INFO_LITERAL) &&
+ !(flags & SRE_INFO_PREFIX))
+ FAIL;
+ /* Validate the prefix */
+ if (flags & SRE_INFO_PREFIX) {
+ SRE_CODE prefix_len;
+ GET_ARG; prefix_len = arg;
+ GET_ARG; /* prefix skip */
+ /* Here comes the prefix string */
+ if (prefix_len > newcode-code)
+ FAIL;
+ code += prefix_len;
+ /* And here comes the overlap table */
+ if (prefix_len > newcode-code)
+ FAIL;
+ /* Each overlap value should be < prefix_len */
+ for (i = 0; i < prefix_len; i++) {
+ if (code[i] >= prefix_len)
+ FAIL;
+ }
+ code += prefix_len;
+ }
+ /* Validate the charset */
+ if (flags & SRE_INFO_CHARSET) {
+ if (!_validate_charset(code, newcode-1))
+ FAIL;
+ if (newcode[-1] != SRE_OP_FAILURE)
+ FAIL;
+ code = newcode;
+ }
+ else if (code != newcode) {
+ VTRACE(("code=%p, newcode=%p\n", code, newcode));
+ FAIL;
+ }
+ }
+ break;
+
+ case SRE_OP_BRANCH:
+ {
+ SRE_CODE *target = NULL;
+ for (;;) {
+ GET_SKIP;
+ if (skip == 0)
+ break;
+ /* Stop 2 before the end; we check the JUMP below */
+ if (!_validate_inner(code, code+skip-3, groups))
+ FAIL;
+ code += skip-3;
+ /* Check that it ends with a JUMP, and that each JUMP
+ has the same target */
+ GET_OP;
+ if (op != SRE_OP_JUMP)
+ FAIL;
+ GET_SKIP;
+ if (target == NULL)
+ target = code+skip-1;
+ else if (code+skip-1 != target)
+ FAIL;
+ }
+ }
+ break;
+
+ case SRE_OP_REPEAT_ONE:
+ case SRE_OP_MIN_REPEAT_ONE:
+ {
+ SRE_CODE min, max;
+ GET_SKIP;
+ GET_ARG; min = arg;
+ GET_ARG; max = arg;
+ if (min > max)
+ FAIL;
+ if (max > SRE_MAXREPEAT)
+ FAIL;
+ if (!_validate_inner(code, code+skip-4, groups))
+ FAIL;
+ code += skip-4;
+ GET_OP;
+ if (op != SRE_OP_SUCCESS)
+ FAIL;
+ }
+ break;
+
+ case SRE_OP_REPEAT:
+ {
+ SRE_CODE min, max;
+ GET_SKIP;
+ GET_ARG; min = arg;
+ GET_ARG; max = arg;
+ if (min > max)
+ FAIL;
+ if (max > SRE_MAXREPEAT)
+ FAIL;
+ if (!_validate_inner(code, code+skip-3, groups))
+ FAIL;
+ code += skip-3;
+ GET_OP;
+ if (op != SRE_OP_MAX_UNTIL && op != SRE_OP_MIN_UNTIL)
+ FAIL;
+ }
+ break;
+
+ case SRE_OP_GROUPREF:
+ case SRE_OP_GROUPREF_IGNORE:
+ GET_ARG;
+ if (arg >= groups)
+ FAIL;
+ break;
+
+ case SRE_OP_GROUPREF_EXISTS:
+ /* The regex syntax for this is: '(?(group)then|else)', where
+ 'group' is either an integer group number or a group name,
+ 'then' and 'else' are sub-regexes, and 'else' is optional. */
+ GET_ARG;
+ if (arg >= groups)
+ FAIL;
+ GET_SKIP_ADJ(1);
+ code--; /* The skip is relative to the first arg! */
+ /* There are two possibilities here: if there is both a 'then'
+ part and an 'else' part, the generated code looks like:
+
+ GROUPREF_EXISTS
+ <group>
+ <skipyes>
+ ...then part...
+ JUMP
+ <skipno>
+ (<skipyes> jumps here)
+ ...else part...
+ (<skipno> jumps here)
+
+ If there is only a 'then' part, it looks like:
+
+ GROUPREF_EXISTS
+ <group>
+ <skip>
+ ...then part...
+ (<skip> jumps here)
+
+ There is no direct way to decide which it is, and we don't want
+ to allow arbitrary jumps anywhere in the code; so we just look
+ for a JUMP opcode preceding our skip target.
+ */
+ if (skip >= 3 && skip-3 < end-code &&
+ code[skip-3] == SRE_OP_JUMP)
+ {
+ VTRACE(("both then and else parts present\n"));
+ if (!_validate_inner(code+1, code+skip-3, groups))
+ FAIL;
+ code += skip-2; /* Position after JUMP, at <skipno> */
+ GET_SKIP;
+ if (!_validate_inner(code, code+skip-1, groups))
+ FAIL;
+ code += skip-1;
+ }
+ else {
+ VTRACE(("only a then part present\n"));
+ if (!_validate_inner(code+1, code+skip-1, groups))
+ FAIL;
+ code += skip-1;
+ }
+ break;
+
+ case SRE_OP_ASSERT:
+ case SRE_OP_ASSERT_NOT:
+ GET_SKIP;
+ GET_ARG; /* 0 for lookahead, width for lookbehind */
+ code--; /* Back up over arg to simplify math below */
+ if (arg & 0x80000000)
+ FAIL; /* Width too large */
+ /* Stop 1 before the end; we check the SUCCESS below */
+ if (!_validate_inner(code+1, code+skip-2, groups))
+ FAIL;
+ code += skip-2;
+ GET_OP;
+ if (op != SRE_OP_SUCCESS)
+ FAIL;
+ break;
+
+ default:
+ FAIL;
+
+ }
+ }
+
+ VTRACE(("okay\n"));
+ return 1;
+}
+
+static int
+_validate_outer(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups)
+{
+ if (groups < 0 || groups > 100 || code >= end || end[-1] != SRE_OP_SUCCESS)
+ FAIL;
+ if (groups == 0) /* fix for simplejson */
+ groups = 100; /* 100 groups should always be safe */
+ return _validate_inner(code, end-1, groups);
+}
+
+static int
+_validate(PatternObject *self)
+{
+ if (!_validate_outer(self->code, self->code+self->codesize, self->groups))
+ {
+ PyErr_SetString(PyExc_RuntimeError, "invalid SRE code");
+ return 0;
+ }
+ else
+ VTRACE(("Success!\n"));
+ return 1;
+}
+
+/* -------------------------------------------------------------------- */
+/* match methods */
+
+static void
+match_dealloc(MatchObject* self)
+{
+ Py_XDECREF(self->regs);
+ Py_XDECREF(self->string);
+ Py_DECREF(self->pattern);
+ PyObject_DEL(self);
+}
+
+static PyObject*
+match_getslice_by_index(MatchObject* self, Py_ssize_t index, PyObject* def)
+{
+ if (index < 0 || index >= self->groups) {
+ /* raise IndexError if we were given a bad group number */
+ PyErr_SetString(
+ PyExc_IndexError,
+ "no such group"
+ );
+ return NULL;
+ }
+
+ index *= 2;
+
+ if (self->string == Py_None || self->mark[index] < 0) {
+ /* return default value if the string or group is undefined */
+ Py_INCREF(def);
+ return def;
+ }
+
+ return PySequence_GetSlice(
+ self->string, self->mark[index], self->mark[index+1]
+ );
+}
+
+static Py_ssize_t
+match_getindex(MatchObject* self, PyObject* index)
+{
+ Py_ssize_t i;
+
+ if (PyInt_Check(index) || PyLong_Check(index))
+ return PyInt_AsSsize_t(index);
+
+ i = -1;
+
+ if (self->pattern->groupindex) {
+ index = PyObject_GetItem(self->pattern->groupindex, index);
+ if (index) {
+ if (PyInt_Check(index) || PyLong_Check(index))
+ i = PyInt_AsSsize_t(index);
+ Py_DECREF(index);
+ } else
+ PyErr_Clear();
+ }
+
+ return i;
+}
+
+static PyObject*
+match_getslice(MatchObject* self, PyObject* index, PyObject* def)
+{
+ return match_getslice_by_index(self, match_getindex(self, index), def);
+}
+
+static PyObject*
+match_expand(MatchObject* self, PyObject* ptemplate)
+{
+ /* delegate to Python code */
+ return call(
+ SRE_PY_MODULE, "_expand",
+ PyTuple_Pack(3, self->pattern, self, ptemplate)
+ );
+}
+
+static PyObject*
+match_group(MatchObject* self, PyObject* args)
+{
+ PyObject* result;
+ Py_ssize_t i, size;
+
+ size = PyTuple_GET_SIZE(args);
+
+ switch (size) {
+ case 0:
+ result = match_getslice(self, Py_False, Py_None);
+ break;
+ case 1:
+ result = match_getslice(self, PyTuple_GET_ITEM(args, 0), Py_None);
+ break;
+ default:
+ /* fetch multiple items */
+ result = PyTuple_New(size);
+ if (!result)
+ return NULL;
+ for (i = 0; i < size; i++) {
+ PyObject* item = match_getslice(
+ self, PyTuple_GET_ITEM(args, i), Py_None
+ );
+ if (!item) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(result, i, item);
+ }
+ break;
+ }
+ return result;
+}
+
+static PyObject*
+match_groups(MatchObject* self, PyObject* args, PyObject* kw)
+{
+ PyObject* result;
+ Py_ssize_t index;
+
+ PyObject* def = Py_None;
+ static char* kwlist[] = { "default", NULL };
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "|O:groups", kwlist, &def))
+ return NULL;
+
+ result = PyTuple_New(self->groups-1);
+ if (!result)
+ return NULL;
+
+ for (index = 1; index < self->groups; index++) {
+ PyObject* item;
+ item = match_getslice_by_index(self, index, def);
+ if (!item) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(result, index-1, item);
+ }
+
+ return result;
+}
+
+static PyObject*
+match_groupdict(MatchObject* self, PyObject* args, PyObject* kw)
+{
+ PyObject* result;
+ PyObject* keys;
+ Py_ssize_t index;
+
+ PyObject* def = Py_None;
+ static char* kwlist[] = { "default", NULL };
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "|O:groupdict", kwlist, &def))
+ return NULL;
+
+ result = PyDict_New();
+ if (!result || !self->pattern->groupindex)
+ return result;
+
+ keys = PyMapping_Keys(self->pattern->groupindex);
+ if (!keys)
+ goto failed;
+
+ for (index = 0; index < PyList_GET_SIZE(keys); index++) {
+ int status;
+ PyObject* key;
+ PyObject* value;
+ key = PyList_GET_ITEM(keys, index);
+ if (!key)
+ goto failed;
+ value = match_getslice(self, key, def);
+ if (!value) {
+ Py_DECREF(key);
+ goto failed;
+ }
+ status = PyDict_SetItem(result, key, value);
+ Py_DECREF(value);
+ if (status < 0)
+ goto failed;
+ }
+
+ Py_DECREF(keys);
+
+ return result;
+
+failed:
+ Py_XDECREF(keys);
+ Py_DECREF(result);
+ return NULL;
+}
+
+static PyObject*
+match_start(MatchObject* self, PyObject* args)
+{
+ Py_ssize_t index;
+
+ PyObject* index_ = Py_False; /* zero */
+ if (!PyArg_UnpackTuple(args, "start", 0, 1, &index_))
+ return NULL;
+
+ index = match_getindex(self, index_);
+
+ if (index < 0 || index >= self->groups) {
+ PyErr_SetString(
+ PyExc_IndexError,
+ "no such group"
+ );
+ return NULL;
+ }
+
+ /* mark is -1 if group is undefined */
+ return PyInt_FromSsize_t(self->mark[index*2]);
+}
+
+static PyObject*
+match_end(MatchObject* self, PyObject* args)
+{
+ Py_ssize_t index;
+
+ PyObject* index_ = Py_False; /* zero */
+ if (!PyArg_UnpackTuple(args, "end", 0, 1, &index_))
+ return NULL;
+
+ index = match_getindex(self, index_);
+
+ if (index < 0 || index >= self->groups) {
+ PyErr_SetString(
+ PyExc_IndexError,
+ "no such group"
+ );
+ return NULL;
+ }
+
+ /* mark is -1 if group is undefined */
+ return PyInt_FromSsize_t(self->mark[index*2+1]);
+}
+
+LOCAL(PyObject*)
+_pair(Py_ssize_t i1, Py_ssize_t i2)
+{
+ PyObject* pair;
+ PyObject* item;
+
+ pair = PyTuple_New(2);
+ if (!pair)
+ return NULL;
+
+ item = PyInt_FromSsize_t(i1);
+ if (!item)
+ goto error;
+ PyTuple_SET_ITEM(pair, 0, item);
+
+ item = PyInt_FromSsize_t(i2);
+ if (!item)
+ goto error;
+ PyTuple_SET_ITEM(pair, 1, item);
+
+ return pair;
+
+ error:
+ Py_DECREF(pair);
+ return NULL;
+}
+
+static PyObject*
+match_span(MatchObject* self, PyObject* args)
+{
+ Py_ssize_t index;
+
+ PyObject* index_ = Py_False; /* zero */
+ if (!PyArg_UnpackTuple(args, "span", 0, 1, &index_))
+ return NULL;
+
+ index = match_getindex(self, index_);
+
+ if (index < 0 || index >= self->groups) {
+ PyErr_SetString(
+ PyExc_IndexError,
+ "no such group"
+ );
+ return NULL;
+ }
+
+ /* marks are -1 if group is undefined */
+ return _pair(self->mark[index*2], self->mark[index*2+1]);
+}
+
+static PyObject*
+match_regs(MatchObject* self)
+{
+ PyObject* regs;
+ PyObject* item;
+ Py_ssize_t index;
+
+ regs = PyTuple_New(self->groups);
+ if (!regs)
+ return NULL;
+
+ for (index = 0; index < self->groups; index++) {
+ item = _pair(self->mark[index*2], self->mark[index*2+1]);
+ if (!item) {
+ Py_DECREF(regs);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(regs, index, item);
+ }
+
+ Py_INCREF(regs);
+ self->regs = regs;
+
+ return regs;
+}
+
+static PyObject*
+match_copy(MatchObject* self, PyObject *unused)
+{
+#ifdef USE_BUILTIN_COPY
+ MatchObject* copy;
+ Py_ssize_t slots, offset;
+
+ slots = 2 * (self->pattern->groups+1);
+
+ copy = PyObject_NEW_VAR(MatchObject, &Match_Type, slots);
+ if (!copy)
+ return NULL;
+
+ /* this value a constant, but any compiler should be able to
+ figure that out all by itself */
+ offset = offsetof(MatchObject, string);
+
+ Py_XINCREF(self->pattern);
+ Py_XINCREF(self->string);
+ Py_XINCREF(self->regs);
+
+ memcpy((char*) copy + offset, (char*) self + offset,
+ sizeof(MatchObject) + slots * sizeof(Py_ssize_t) - offset);
+
+ return (PyObject*) copy;
+#else
+ PyErr_SetString(PyExc_TypeError, "cannot copy this match object");
+ return NULL;
+#endif
+}
+
+static PyObject*
+match_deepcopy(MatchObject* self, PyObject* memo)
+{
+#ifdef USE_BUILTIN_COPY
+ MatchObject* copy;
+
+ copy = (MatchObject*) match_copy(self);
+ if (!copy)
+ return NULL;
+
+ if (!deepcopy((PyObject**) ©->pattern, memo) ||
+ !deepcopy(©->string, memo) ||
+ !deepcopy(©->regs, memo)) {
+ Py_DECREF(copy);
+ return NULL;
+ }
+
+#else
+ PyErr_SetString(PyExc_TypeError, "cannot deepcopy this match object");
+ return NULL;
+#endif
+}
+
+PyDoc_STRVAR(match_doc,
+"The result of re.match() and re.search().\n\
+Match objects always have a boolean value of True.");
+
+PyDoc_STRVAR(match_group_doc,
+"group([group1, ...]) -> str or tuple.\n\
+ Return subgroup(s) of the match by indices or names.\n\
+ For 0 returns the entire match.");
+
+PyDoc_STRVAR(match_start_doc,
+"start([group=0]) -> int.\n\
+ Return index of the start of the substring matched by group.");
+
+PyDoc_STRVAR(match_end_doc,
+"end([group=0]) -> int.\n\
+ Return index of the end of the substring matched by group.");
+
+PyDoc_STRVAR(match_span_doc,
+"span([group]) -> tuple.\n\
+ For MatchObject m, return the 2-tuple (m.start(group), m.end(group)).");
+
+PyDoc_STRVAR(match_groups_doc,
+"groups([default=None]) -> tuple.\n\
+ Return a tuple containing all the subgroups of the match, from 1.\n\
+ The default argument is used for groups\n\
+ that did not participate in the match");
+
+PyDoc_STRVAR(match_groupdict_doc,
+"groupdict([default=None]) -> dict.\n\
+ Return a dictionary containing all the named subgroups of the match,\n\
+ keyed by the subgroup name. The default argument is used for groups\n\
+ that did not participate in the match");
+
+PyDoc_STRVAR(match_expand_doc,
+"expand(template) -> str.\n\
+ Return the string obtained by doing backslash substitution\n\
+ on the string template, as done by the sub() method.");
+
+static PyMethodDef match_methods[] = {
+ {"group", (PyCFunction) match_group, METH_VARARGS, match_group_doc},
+ {"start", (PyCFunction) match_start, METH_VARARGS, match_start_doc},
+ {"end", (PyCFunction) match_end, METH_VARARGS, match_end_doc},
+ {"span", (PyCFunction) match_span, METH_VARARGS, match_span_doc},
+ {"groups", (PyCFunction) match_groups, METH_VARARGS|METH_KEYWORDS,
+ match_groups_doc},
+ {"groupdict", (PyCFunction) match_groupdict, METH_VARARGS|METH_KEYWORDS,
+ match_groupdict_doc},
+ {"expand", (PyCFunction) match_expand, METH_O, match_expand_doc},
+ {"__copy__", (PyCFunction) match_copy, METH_NOARGS},
+ {"__deepcopy__", (PyCFunction) match_deepcopy, METH_O},
+ {NULL, NULL}
+};
+
+static PyObject *
+match_lastindex_get(MatchObject *self)
+{
+ if (self->lastindex >= 0)
+ return PyInt_FromSsize_t(self->lastindex);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+match_lastgroup_get(MatchObject *self)
+{
+ if (self->pattern->indexgroup && self->lastindex >= 0) {
+ PyObject* result = PySequence_GetItem(
+ self->pattern->indexgroup, self->lastindex
+ );
+ if (result)
+ return result;
+ PyErr_Clear();
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+match_regs_get(MatchObject *self)
+{
+ if (self->regs) {
+ Py_INCREF(self->regs);
+ return self->regs;
+ } else
+ return match_regs(self);
+}
+
+static PyGetSetDef match_getset[] = {
+ {"lastindex", (getter)match_lastindex_get, (setter)NULL},
+ {"lastgroup", (getter)match_lastgroup_get, (setter)NULL},
+ {"regs", (getter)match_regs_get, (setter)NULL},
+ {NULL}
+};
+
+#define MATCH_OFF(x) offsetof(MatchObject, x)
+static PyMemberDef match_members[] = {
+ {"string", T_OBJECT, MATCH_OFF(string), READONLY},
+ {"re", T_OBJECT, MATCH_OFF(pattern), READONLY},
+ {"pos", T_PYSSIZET, MATCH_OFF(pos), READONLY},
+ {"endpos", T_PYSSIZET, MATCH_OFF(endpos), READONLY},
+ {NULL}
+};
+
+
+/* FIXME: implement setattr("string", None) as a special case (to
+ detach the associated string, if any */
+
+static PyTypeObject Match_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "_" SRE_MODULE ".SRE_Match",
+ sizeof(MatchObject), sizeof(Py_ssize_t),
+ (destructor)match_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT,
+ match_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ match_methods, /* tp_methods */
+ match_members, /* tp_members */
+ match_getset, /* tp_getset */
+};
+
+static PyObject*
+pattern_new_match(PatternObject* pattern, SRE_STATE* state, int status)
+{
+ /* create match object (from state object) */
+
+ MatchObject* match;
+ Py_ssize_t i, j;
+ char* base;
+ int n;
+
+ if (status > 0) {
+
+ /* create match object (with room for extra group marks) */
+ /* coverity[ampersand_in_size] */
+ match = PyObject_NEW_VAR(MatchObject, &Match_Type,
+ 2*(pattern->groups+1));
+ if (!match)
+ return NULL;
+
+ Py_INCREF(pattern);
+ match->pattern = pattern;
+
+ Py_INCREF(state->string);
+ match->string = state->string;
+
+ match->regs = NULL;
+ match->groups = pattern->groups+1;
+
+ /* fill in group slices */
+
+ base = (char*) state->beginning;
+ n = state->charsize;
+
+ match->mark[0] = ((char*) state->start - base) / n;
+ match->mark[1] = ((char*) state->ptr - base) / n;
+
+ for (i = j = 0; i < pattern->groups; i++, j+=2)
+ if (j+1 <= state->lastmark && state->mark[j] && state->mark[j+1]) {
+ match->mark[j+2] = ((char*) state->mark[j] - base) / n;
+ match->mark[j+3] = ((char*) state->mark[j+1] - base) / n;
+ } else
+ match->mark[j+2] = match->mark[j+3] = -1; /* undefined */
+
+ match->pos = state->pos;
+ match->endpos = state->endpos;
+
+ match->lastindex = state->lastindex;
+
+ return (PyObject*) match;
+
+ } else if (status == 0) {
+
+ /* no match */
+ Py_INCREF(Py_None);
+ return Py_None;
+
+ }
+
+ /* internal error */
+ pattern_error(status);
+ return NULL;
+}
+
+
+/* -------------------------------------------------------------------- */
+/* scanner methods (experimental) */
+
+static void
+scanner_dealloc(ScannerObject* self)
+{
+ state_fini(&self->state);
+ Py_XDECREF(self->pattern);
+ PyObject_DEL(self);
+}
+
+static PyObject*
+scanner_match(ScannerObject* self, PyObject *unused)
+{
+ SRE_STATE* state = &self->state;
+ PyObject* match;
+ int status;
+
+ state_reset(state);
+
+ state->ptr = state->start;
+
+ if (state->charsize == 1) {
+ status = sre_match(state, PatternObject_GetCode(self->pattern));
+ } else {
+#if defined(HAVE_UNICODE)
+ status = sre_umatch(state, PatternObject_GetCode(self->pattern));
+#endif
+ }
+ if (PyErr_Occurred())
+ return NULL;
+
+ match = pattern_new_match((PatternObject*) self->pattern,
+ state, status);
+
+ if (status == 0 || state->ptr == state->start)
+ state->start = (void*) ((char*) state->ptr + state->charsize);
+ else
+ state->start = state->ptr;
+
+ return match;
+}
+
+
+static PyObject*
+scanner_search(ScannerObject* self, PyObject *unused)
+{
+ SRE_STATE* state = &self->state;
+ PyObject* match;
+ int status;
+
+ state_reset(state);
+
+ state->ptr = state->start;
+
+ if (state->charsize == 1) {
+ status = sre_search(state, PatternObject_GetCode(self->pattern));
+ } else {
+#if defined(HAVE_UNICODE)
+ status = sre_usearch(state, PatternObject_GetCode(self->pattern));
+#endif
+ }
+ if (PyErr_Occurred())
+ return NULL;
+
+ match = pattern_new_match((PatternObject*) self->pattern,
+ state, status);
+
+ if (status == 0 || state->ptr == state->start)
+ state->start = (void*) ((char*) state->ptr + state->charsize);
+ else
+ state->start = state->ptr;
+
+ return match;
+}
+
+static PyMethodDef scanner_methods[] = {
+ {"match", (PyCFunction) scanner_match, METH_NOARGS},
+ {"search", (PyCFunction) scanner_search, METH_NOARGS},
+ {NULL, NULL}
+};
+
+#define SCAN_OFF(x) offsetof(ScannerObject, x)
+static PyMemberDef scanner_members[] = {
+ {"pattern", T_OBJECT, SCAN_OFF(pattern), READONLY},
+ {NULL} /* Sentinel */
+};
+
+statichere PyTypeObject Scanner_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, "_" SRE_MODULE ".SRE_Scanner",
+ sizeof(ScannerObject), 0,
+ (destructor)scanner_dealloc, /*tp_dealloc*/
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ scanner_methods, /* tp_methods */
+ scanner_members, /* tp_members */
+ 0, /* tp_getset */
+};
+
+static PyObject*
+pattern_scanner(PatternObject* pattern, PyObject* args)
+{
+ /* create search state object */
+
+ ScannerObject* self;
+
+ PyObject* string;
+ Py_ssize_t start = 0;
+ Py_ssize_t end = PY_SSIZE_T_MAX;
+ if (!PyArg_ParseTuple(args, "O|nn:scanner", &string, &start, &end))
+ return NULL;
+
+ /* create scanner object */
+ self = PyObject_NEW(ScannerObject, &Scanner_Type);
+ if (!self)
+ return NULL;
+ self->pattern = NULL;
+
+ string = state_init(&self->state, pattern, string, start, end);
+ if (!string) {
+ Py_DECREF(self);
+ return NULL;
+ }
+
+ Py_INCREF(pattern);
+ self->pattern = (PyObject*) pattern;
+
+ return (PyObject*) self;
+}
+
+static PyMethodDef _functions[] = {
+ {"compile", _compile, METH_VARARGS},
+ {"getcodesize", sre_codesize, METH_NOARGS},
+ {"getlower", sre_getlower, METH_VARARGS},
+ {NULL, NULL}
+};
+
+#if PY_VERSION_HEX < 0x02030000
+DL_EXPORT(void) init_sre(void)
+#else
+PyMODINIT_FUNC init_sre(void)
+#endif
+{
+ PyObject* m;
+ PyObject* d;
+ PyObject* x;
+
+ /* Patch object types */
+ if (PyType_Ready(&Pattern_Type) || PyType_Ready(&Match_Type) ||
+ PyType_Ready(&Scanner_Type))
+ return;
+
+ m = Py_InitModule("_" SRE_MODULE, _functions);
+ if (m == NULL)
+ return;
+ d = PyModule_GetDict(m);
+
+ x = PyInt_FromLong(SRE_MAGIC);
+ if (x) {
+ PyDict_SetItemString(d, "MAGIC", x);
+ Py_DECREF(x);
+ }
+
+ x = PyInt_FromLong(sizeof(SRE_CODE));
+ if (x) {
+ PyDict_SetItemString(d, "CODESIZE", x);
+ Py_DECREF(x);
+ }
+
+ x = PyLong_FromUnsignedLong(SRE_MAXREPEAT);
+ if (x) {
+ PyDict_SetItemString(d, "MAXREPEAT", x);
+ Py_DECREF(x);
+ }
+
+ x = PyString_FromString(copyright);
+ if (x) {
+ PyDict_SetItemString(d, "copyright", x);
+ Py_DECREF(x);
+ }
+}
+
+#endif /* !defined(SRE_RECURSIVE) */
+
+/* vim:ts=4:sw=4:et
+*/
diff --git a/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/addrinfo.h b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/addrinfo.h new file mode 100644 index 0000000000..6f8b496658 --- /dev/null +++ b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/addrinfo.h @@ -0,0 +1,176 @@ +/*
+ * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef HAVE_GETADDRINFO
+
+/*
+ * Error return codes from getaddrinfo()
+ */
+#ifdef EAI_ADDRFAMILY
+/* If this is defined, there is a conflicting implementation
+ in the C library, which can't be used for some reason.
+ Make sure it won't interfere with this emulation. */
+
+#undef EAI_ADDRFAMILY
+#undef EAI_AGAIN
+#undef EAI_BADFLAGS
+#undef EAI_FAIL
+#undef EAI_FAMILY
+#undef EAI_MEMORY
+#undef EAI_NODATA
+#undef EAI_NONAME
+#undef EAI_SERVICE
+#undef EAI_SOCKTYPE
+#undef EAI_SYSTEM
+#undef EAI_BADHINTS
+#undef EAI_PROTOCOL
+#undef EAI_MAX
+#undef getaddrinfo
+#define getaddrinfo fake_getaddrinfo
+#endif /* EAI_ADDRFAMILY */
+
+#define EAI_ADDRFAMILY 1 /* address family for hostname not supported */
+#define EAI_AGAIN 2 /* temporary failure in name resolution */
+#define EAI_BADFLAGS 3 /* invalid value for ai_flags */
+#define EAI_FAIL 4 /* non-recoverable failure in name resolution */
+#define EAI_FAMILY 5 /* ai_family not supported */
+#define EAI_MEMORY 6 /* memory allocation failure */
+#define EAI_NODATA 7 /* no address associated with hostname */
+#define EAI_NONAME 8 /* hostname nor servname provided, or not known */
+#define EAI_SERVICE 9 /* servname not supported for ai_socktype */
+#define EAI_SOCKTYPE 10 /* ai_socktype not supported */
+#define EAI_SYSTEM 11 /* system error returned in errno */
+#define EAI_BADHINTS 12
+#define EAI_PROTOCOL 13
+#define EAI_MAX 14
+
+/*
+ * Flag values for getaddrinfo()
+ */
+#ifdef AI_PASSIVE
+#undef AI_PASSIVE
+#undef AI_CANONNAME
+#undef AI_NUMERICHOST
+#undef AI_MASK
+#undef AI_ALL
+#undef AI_V4MAPPED_CFG
+#undef AI_ADDRCONFIG
+#undef AI_V4MAPPED
+#undef AI_DEFAULT
+#endif /* AI_PASSIVE */
+
+#define AI_PASSIVE 0x00000001 /* get address to use bind() */
+#define AI_CANONNAME 0x00000002 /* fill ai_canonname */
+#define AI_NUMERICHOST 0x00000004 /* prevent name resolution */
+/* valid flags for addrinfo */
+#define AI_MASK (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST)
+
+#define AI_ALL 0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */
+#define AI_V4MAPPED_CFG 0x00000200 /* accept IPv4-mapped if kernel supports */
+#define AI_ADDRCONFIG 0x00000400 /* only if any address is assigned */
+#define AI_V4MAPPED 0x00000800 /* accept IPv4-mapped IPv6 address */
+/* special recommended flags for getipnodebyname */
+#define AI_DEFAULT (AI_V4MAPPED_CFG | AI_ADDRCONFIG)
+
+#endif /* !HAVE_GETADDRINFO */
+
+#ifndef HAVE_GETNAMEINFO
+
+/*
+ * Constants for getnameinfo()
+ */
+#ifndef NI_MAXHOST
+#define NI_MAXHOST 1025
+#define NI_MAXSERV 32
+#endif /* !NI_MAXHOST */
+
+/*
+ * Flag values for getnameinfo()
+ */
+#ifndef NI_NOFQDN
+#define NI_NOFQDN 0x00000001
+#define NI_NUMERICHOST 0x00000002
+#define NI_NAMEREQD 0x00000004
+#define NI_NUMERICSERV 0x00000008
+#define NI_DGRAM 0x00000010
+#endif /* !NI_NOFQDN */
+
+#endif /* !HAVE_GETNAMEINFO */
+
+#ifndef HAVE_ADDRINFO
+struct addrinfo {
+ int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
+ int ai_family; /* PF_xxx */
+ int ai_socktype; /* SOCK_xxx */
+ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+ size_t ai_addrlen; /* length of ai_addr */
+ char *ai_canonname; /* canonical name for hostname */
+ struct sockaddr *ai_addr; /* binary address */
+ struct addrinfo *ai_next; /* next structure in linked list */
+};
+#endif /* !HAVE_ADDRINFO */
+
+#ifndef HAVE_SOCKADDR_STORAGE
+/*
+ * RFC 2553: protocol-independent placeholder for socket addresses
+ */
+#define _SS_MAXSIZE 128
+#ifdef HAVE_LONG_LONG
+#define _SS_ALIGNSIZE (sizeof(PY_LONG_LONG))
+#else
+#define _SS_ALIGNSIZE (sizeof(double))
+#endif /* HAVE_LONG_LONG */
+#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(u_char) * 2)
+#define _SS_PAD2SIZE (_SS_MAXSIZE - sizeof(u_char) * 2 - \
+ _SS_PAD1SIZE - _SS_ALIGNSIZE)
+
+struct sockaddr_storage {
+#ifdef HAVE_SOCKADDR_SA_LEN
+ unsigned char ss_len; /* address length */
+ unsigned char ss_family; /* address family */
+#else
+ unsigned short ss_family; /* address family */
+#endif /* HAVE_SOCKADDR_SA_LEN */
+ char __ss_pad1[_SS_PAD1SIZE];
+#ifdef HAVE_LONG_LONG
+ PY_LONG_LONG __ss_align; /* force desired structure storage alignment */
+#else
+ double __ss_align; /* force desired structure storage alignment */
+#endif /* HAVE_LONG_LONG */
+ char __ss_pad2[_SS_PAD2SIZE];
+};
+#endif /* !HAVE_SOCKADDR_STORAGE */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern void freehostent Py_PROTO((struct hostent *));
+#ifdef __cplusplus
+}
+#endif
diff --git a/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/config.c b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/config.c new file mode 100644 index 0000000000..7cc021c964 --- /dev/null +++ b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/config.c @@ -0,0 +1,155 @@ +/** @file
+ Python Module configuration.
+
+ Copyright (c) 2011-2012, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+/* This file contains the table of built-in modules.
+ See init_builtin() in import.c. */
+
+#include "Python.h"
+
+extern void initarray(void);
+extern void init_ast(void);
+extern void initbinascii(void);
+extern void init_bisect(void);
+extern void initcmath(void);
+extern void init_codecs(void);
+extern void init_collections(void);
+extern void initcPickle(void);
+extern void initcStringIO(void);
+extern void init_csv(void);
+extern void init_ctypes(void);
+extern void initdatetime(void);
+extern void initedk2(void);
+extern void initerrno(void);
+extern void init_functools(void);
+extern void initfuture_builtins(void);
+extern void initgc(void);
+extern void init_heapq(void);
+extern void init_hotshot(void);
+extern void initimp(void);
+extern void init_io(void);
+extern void inititertools(void);
+extern void init_json(void);
+extern void init_lsprof(void);
+extern void initmath(void);
+extern void init_md5(void);
+extern void initmmap(void);
+extern void initoperator(void);
+extern void initparser(void);
+extern void initpyexpat(void);
+extern void init_random(void);
+extern void initselect(void);
+extern void init_sha(void);
+extern void init_sha256(void);
+extern void init_sha512(void);
+extern void initsignal(void);
+extern void init_socket(void);
+extern void init_sre(void);
+extern void initstrop(void);
+extern void init_struct(void);
+extern void init_subprocess(void);
+extern void init_symtable(void);
+extern void initthread(void);
+extern void inittime(void);
+extern void initunicodedata(void);
+extern void init_weakref(void);
+extern void init_winreg(void);
+extern void initxxsubtype(void);
+extern void initzipimport(void);
+extern void initzlib(void);
+
+extern void PyMarshal_Init(void);
+extern void _PyWarnings_Init(void);
+
+extern void init_multibytecodec(void);
+extern void init_codecs_cn(void);
+extern void init_codecs_hk(void);
+extern void init_codecs_iso2022(void);
+extern void init_codecs_jp(void);
+extern void init_codecs_kr(void);
+extern void init_codecs_tw(void);
+
+struct _inittab _PyImport_Inittab[] = {
+
+ //{"_ast", init_ast},
+ //{"_bisect", init_bisect}, /* A fast version of bisect.py */
+ //{"_csv", init_csv},
+ //{"_heapq", init_heapq}, /* A fast version of heapq.py */
+ //{"_io", init_io},
+ //{"_json", init_json},
+ //{"_md5", init_md5},
+ //{"_sha", init_sha},
+ //{"_sha256", init_sha256},
+ //{"_sha512", init_sha512},
+ //{"_socket", init_socket},
+ //{"_symtable", init_symtable},
+
+ //{"array", initarray},
+ //{"cmath", initcmath},
+ //{"cPickle", initcPickle},
+ //{"datetime", initdatetime},
+ //{"future_builtins", initfuture_builtins},
+ //{"parser", initparser},
+ //{"pyexpat", initpyexpat},
+ //{"select", initselect},
+ //{"signal", initsignal},
+ //{"strop", initstrop}, /* redefines some string operations that are 100-1000 times faster */
+ //{"unicodedata", initunicodedata},
+ //{"xxsubtype", initxxsubtype},
+ //{"zipimport", initzipimport},
+ //{"zlib", initzlib},
+
+ /* CJK codecs */
+ //{"_multibytecodec", init_multibytecodec},
+ //{"_codecs_cn", init_codecs_cn},
+ //{"_codecs_hk", init_codecs_hk},
+ //{"_codecs_iso2022", init_codecs_iso2022},
+ //{"_codecs_jp", init_codecs_jp},
+ //{"_codecs_kr", init_codecs_kr},
+ //{"_codecs_tw", init_codecs_tw},
+
+#ifdef WITH_THREAD
+ {"thread", initthread},
+#endif
+
+ /* These modules are required for the full built-in help() facility provided by pydoc. */
+ {"_codecs", init_codecs},
+ {"_collections", init_collections},
+ {"_functools", init_functools},
+ {"_random", init_random},
+ {"_sre", init_sre},
+ {"_struct", init_struct}, /* Required by the logging package. */
+ {"_weakref", init_weakref},
+ {"binascii", initbinascii},
+ {"cStringIO", initcStringIO}, /* Required by several modules, such as logging. */
+ {"gc", initgc},
+ {"itertools", inititertools},
+ {"math", initmath},
+ {"operator", initoperator},
+ {"time", inittime},
+
+ /* These four modules should always be built in. */
+ {"edk2", initedk2},
+ {"errno", initerrno},
+ {"imp", initimp}, /* We get this for free from Python/import.c */
+ {"marshal", PyMarshal_Init}, /* We get this for free from Python/marshal.c */
+
+ /* These entries are here for sys.builtin_module_names */
+ {"__main__", NULL},
+ {"__builtin__", NULL},
+ {"sys", NULL},
+ {"exceptions", NULL},
+ {"_warnings", _PyWarnings_Init},
+
+ /* Sentinel */
+ {0, 0}
+};
diff --git a/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/edk2module.c b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/edk2module.c new file mode 100644 index 0000000000..037849504f --- /dev/null +++ b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/edk2module.c @@ -0,0 +1,7420 @@ +/** @file
+ OS-specific module implementation for EDK II and UEFI.
+ Derived from posixmodule.c in Python 2.7.2.
+
+ Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#define PY_SSIZE_T_CLEAN
+
+#include "Python.h"
+#include "structseq.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <sys/syslimits.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+PyDoc_STRVAR(edk2__doc__,
+ "This module provides access to UEFI firmware functionality that is\n\
+ standardized by the C Standard and the POSIX standard (a thinly\n\
+ disguised Unix interface). Refer to the library manual and\n\
+ corresponding UEFI Specification entries for more information on calls.");
+
+#ifndef Py_USING_UNICODE
+ /* This is used in signatures of functions. */
+ #define Py_UNICODE void
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+ #include <sys/types.h>
+#endif /* HAVE_SYS_TYPES_H */
+
+#ifdef HAVE_SYS_STAT_H
+ #include <sys/stat.h>
+#endif /* HAVE_SYS_STAT_H */
+
+#ifdef HAVE_SYS_WAIT_H
+ #include <sys/wait.h> /* For WNOHANG */
+#endif
+
+#ifdef HAVE_SIGNAL_H
+ #include <signal.h>
+#endif
+
+#ifdef HAVE_FCNTL_H
+ #include <fcntl.h>
+#endif /* HAVE_FCNTL_H */
+
+#ifdef HAVE_GRP_H
+ #include <grp.h>
+#endif
+
+#ifdef HAVE_SYSEXITS_H
+ #include <sysexits.h>
+#endif /* HAVE_SYSEXITS_H */
+
+#ifdef HAVE_SYS_LOADAVG_H
+ #include <sys/loadavg.h>
+#endif
+
+#ifdef HAVE_UTIME_H
+ #include <utime.h>
+#endif /* HAVE_UTIME_H */
+
+#ifdef HAVE_SYS_UTIME_H
+ #include <sys/utime.h>
+ #define HAVE_UTIME_H /* pretend we do for the rest of this file */
+#endif /* HAVE_SYS_UTIME_H */
+
+#ifdef HAVE_SYS_TIMES_H
+ #include <sys/times.h>
+#endif /* HAVE_SYS_TIMES_H */
+
+#ifdef HAVE_SYS_PARAM_H
+ #include <sys/param.h>
+#endif /* HAVE_SYS_PARAM_H */
+
+#ifdef HAVE_SYS_UTSNAME_H
+ #include <sys/utsname.h>
+#endif /* HAVE_SYS_UTSNAME_H */
+
+#ifdef HAVE_DIRENT_H
+ #include <dirent.h>
+ #define NAMLEN(dirent) wcslen((dirent)->FileName)
+#else
+ #define dirent direct
+ #define NAMLEN(dirent) (dirent)->d_namlen
+ #ifdef HAVE_SYS_NDIR_H
+ #include <sys/ndir.h>
+ #endif
+ #ifdef HAVE_SYS_DIR_H
+ #include <sys/dir.h>
+ #endif
+ #ifdef HAVE_NDIR_H
+ #include <ndir.h>
+ #endif
+#endif
+
+#ifndef MAXPATHLEN
+ #if defined(PATH_MAX) && PATH_MAX > 1024
+ #define MAXPATHLEN PATH_MAX
+ #else
+ #define MAXPATHLEN 1024
+ #endif
+#endif /* MAXPATHLEN */
+
+#define WAIT_TYPE int
+#define WAIT_STATUS_INT(s) (s)
+
+/* Issue #1983: pid_t can be longer than a C long on some systems */
+#if !defined(SIZEOF_PID_T) || SIZEOF_PID_T == SIZEOF_INT
+ #define PARSE_PID "i"
+ #define PyLong_FromPid PyInt_FromLong
+ #define PyLong_AsPid PyInt_AsLong
+#elif SIZEOF_PID_T == SIZEOF_LONG
+ #define PARSE_PID "l"
+ #define PyLong_FromPid PyInt_FromLong
+ #define PyLong_AsPid PyInt_AsLong
+#elif defined(SIZEOF_LONG_LONG) && SIZEOF_PID_T == SIZEOF_LONG_LONG
+ #define PARSE_PID "L"
+ #define PyLong_FromPid PyLong_FromLongLong
+ #define PyLong_AsPid PyInt_AsLongLong
+#else
+ #error "sizeof(pid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)"
+#endif /* SIZEOF_PID_T */
+
+/* Don't use the "_r" form if we don't need it (also, won't have a
+ prototype for it, at least on Solaris -- maybe others as well?). */
+#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
+ #define USE_CTERMID_R
+#endif
+
+#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
+ #define USE_TMPNAM_R
+#endif
+
+/* choose the appropriate stat and fstat functions and return structs */
+#undef STAT
+#undef FSTAT
+#undef STRUCT_STAT
+#define STAT stat
+#define FSTAT fstat
+#define STRUCT_STAT struct stat
+
+/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
+#define _PyVerify_fd_dup2(A, B) (1)
+
+#ifndef UEFI_C_SOURCE
+/* Return a dictionary corresponding to the POSIX environment table */
+extern char **environ;
+
+static PyObject *
+convertenviron(void)
+{
+ PyObject *d;
+ char **e;
+ d = PyDict_New();
+ if (d == NULL)
+ return NULL;
+ if (environ == NULL)
+ return d;
+ /* This part ignores errors */
+ for (e = environ; *e != NULL; e++) {
+ PyObject *k;
+ PyObject *v;
+ char *p = strchr(*e, '=');
+ if (p == NULL)
+ continue;
+ k = PyString_FromStringAndSize(*e, (int)(p-*e));
+ if (k == NULL) {
+ PyErr_Clear();
+ continue;
+ }
+ v = PyString_FromString(p+1);
+ if (v == NULL) {
+ PyErr_Clear();
+ Py_DECREF(k);
+ continue;
+ }
+ if (PyDict_GetItem(d, k) == NULL) {
+ if (PyDict_SetItem(d, k, v) != 0)
+ PyErr_Clear();
+ }
+ Py_DECREF(k);
+ Py_DECREF(v);
+ }
+ return d;
+}
+#endif /* UEFI_C_SOURCE */
+
+/* Set a POSIX-specific error from errno, and return NULL */
+
+static PyObject *
+posix_error(void)
+{
+ return PyErr_SetFromErrno(PyExc_OSError);
+}
+static PyObject *
+posix_error_with_filename(char* name)
+{
+ return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
+}
+
+
+static PyObject *
+posix_error_with_allocated_filename(char* name)
+{
+ PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
+ PyMem_Free(name);
+ return rc;
+}
+
+/* POSIX generic methods */
+
+#ifndef UEFI_C_SOURCE
+ static PyObject *
+ posix_fildes(PyObject *fdobj, int (*func)(int))
+ {
+ int fd;
+ int res;
+ fd = PyObject_AsFileDescriptor(fdobj);
+ if (fd < 0)
+ return NULL;
+ if (!_PyVerify_fd(fd))
+ return posix_error();
+ Py_BEGIN_ALLOW_THREADS
+ res = (*func)(fd);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+#endif /* UEFI_C_SOURCE */
+
+static PyObject *
+posix_1str(PyObject *args, char *format, int (*func)(const char*))
+{
+ char *path1 = NULL;
+ int res;
+ if (!PyArg_ParseTuple(args, format,
+ Py_FileSystemDefaultEncoding, &path1))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = (*func)(path1);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return posix_error_with_allocated_filename(path1);
+ PyMem_Free(path1);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyObject *
+posix_2str(PyObject *args,
+ char *format,
+ int (*func)(const char *, const char *))
+{
+ char *path1 = NULL, *path2 = NULL;
+ int res;
+ if (!PyArg_ParseTuple(args, format,
+ Py_FileSystemDefaultEncoding, &path1,
+ Py_FileSystemDefaultEncoding, &path2))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = (*func)(path1, path2);
+ Py_END_ALLOW_THREADS
+ PyMem_Free(path1);
+ PyMem_Free(path2);
+ if (res != 0)
+ /* XXX how to report both path1 and path2??? */
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(stat_result__doc__,
+"stat_result: Result from stat or lstat.\n\n\
+This object may be accessed either as a tuple of\n\
+ (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
+or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
+\n\
+Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
+or st_flags, they are available as attributes only.\n\
+\n\
+See os.stat for more information.");
+
+static PyStructSequence_Field stat_result_fields[] = {
+ {"st_mode", "protection bits"},
+ //{"st_ino", "inode"},
+ //{"st_dev", "device"},
+ //{"st_nlink", "number of hard links"},
+ //{"st_uid", "user ID of owner"},
+ //{"st_gid", "group ID of owner"},
+ {"st_size", "total size, in bytes"},
+ /* The NULL is replaced with PyStructSequence_UnnamedField later. */
+ {NULL, "integer time of last access"},
+ {NULL, "integer time of last modification"},
+ {NULL, "integer time of last change"},
+ {"st_atime", "time of last access"},
+ {"st_mtime", "time of last modification"},
+ {"st_ctime", "time of last change"},
+#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
+ {"st_blksize", "blocksize for filesystem I/O"},
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
+ {"st_blocks", "number of blocks allocated"},
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_RDEV
+ {"st_rdev", "device type (if inode device)"},
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_FLAGS
+ {"st_flags", "user defined flags for file"},
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_GEN
+ {"st_gen", "generation number"},
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
+ {"st_birthtime", "time of creation"},
+#endif
+ {0}
+};
+
+#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
+#define ST_BLKSIZE_IDX 8
+#else
+#define ST_BLKSIZE_IDX 12
+#endif
+
+#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
+#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
+#else
+#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
+#endif
+
+#ifdef HAVE_STRUCT_STAT_ST_RDEV
+#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
+#else
+#define ST_RDEV_IDX ST_BLOCKS_IDX
+#endif
+
+#ifdef HAVE_STRUCT_STAT_ST_FLAGS
+#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
+#else
+#define ST_FLAGS_IDX ST_RDEV_IDX
+#endif
+
+#ifdef HAVE_STRUCT_STAT_ST_GEN
+#define ST_GEN_IDX (ST_FLAGS_IDX+1)
+#else
+#define ST_GEN_IDX ST_FLAGS_IDX
+#endif
+
+#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
+#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
+#else
+#define ST_BIRTHTIME_IDX ST_GEN_IDX
+#endif
+
+static PyStructSequence_Desc stat_result_desc = {
+ "stat_result", /* name */
+ stat_result__doc__, /* doc */
+ stat_result_fields,
+ 10
+};
+
+#ifndef UEFI_C_SOURCE /* Not in UEFI */
+PyDoc_STRVAR(statvfs_result__doc__,
+"statvfs_result: Result from statvfs or fstatvfs.\n\n\
+This object may be accessed either as a tuple of\n\
+ (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
+or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
+\n\
+See os.statvfs for more information.");
+
+static PyStructSequence_Field statvfs_result_fields[] = {
+ {"f_bsize", },
+ {"f_frsize", },
+ {"f_blocks", },
+ {"f_bfree", },
+ {"f_bavail", },
+ {"f_files", },
+ {"f_ffree", },
+ {"f_favail", },
+ {"f_flag", },
+ {"f_namemax",},
+ {0}
+};
+
+static PyStructSequence_Desc statvfs_result_desc = {
+ "statvfs_result", /* name */
+ statvfs_result__doc__, /* doc */
+ statvfs_result_fields,
+ 10
+};
+
+static PyTypeObject StatVFSResultType;
+#endif
+
+static int initialized;
+static PyTypeObject StatResultType;
+static newfunc structseq_new;
+
+static PyObject *
+statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyStructSequence *result;
+ int i;
+
+ result = (PyStructSequence*)structseq_new(type, args, kwds);
+ if (!result)
+ return NULL;
+ /* If we have been initialized from a tuple,
+ st_?time might be set to None. Initialize it
+ from the int slots. */
+ for (i = 7; i <= 9; i++) {
+ if (result->ob_item[i+3] == Py_None) {
+ Py_DECREF(Py_None);
+ Py_INCREF(result->ob_item[i]);
+ result->ob_item[i+3] = result->ob_item[i];
+ }
+ }
+ return (PyObject*)result;
+}
+
+
+
+/* If true, st_?time is float. */
+#if defined(UEFI_C_SOURCE)
+ static int _stat_float_times = 0;
+#else
+ static int _stat_float_times = 1;
+
+PyDoc_STRVAR(stat_float_times__doc__,
+"stat_float_times([newval]) -> oldval\n\n\
+Determine whether os.[lf]stat represents time stamps as float objects.\n\
+If newval is True, future calls to stat() return floats, if it is False,\n\
+future calls return ints. \n\
+If newval is omitted, return the current setting.\n");
+
+static PyObject*
+stat_float_times(PyObject* self, PyObject *args)
+{
+ int newval = -1;
+
+ if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
+ return NULL;
+ if (newval == -1)
+ /* Return old value */
+ return PyBool_FromLong(_stat_float_times);
+ _stat_float_times = newval;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif /* UEFI_C_SOURCE */
+
+static void
+fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
+{
+ PyObject *fval,*ival;
+#if SIZEOF_TIME_T > SIZEOF_LONG
+ ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
+#else
+ ival = PyInt_FromLong((long)sec);
+#endif
+ if (!ival)
+ return;
+ if (_stat_float_times) {
+ fval = PyFloat_FromDouble(sec + 1e-9*nsec);
+ } else {
+ fval = ival;
+ Py_INCREF(fval);
+ }
+ PyStructSequence_SET_ITEM(v, index, ival);
+ PyStructSequence_SET_ITEM(v, index+3, fval);
+}
+
+/* pack a system stat C structure into the Python stat tuple
+ (used by posix_stat() and posix_fstat()) */
+static PyObject*
+_pystat_fromstructstat(STRUCT_STAT *st)
+{
+ unsigned long ansec, mnsec, cnsec;
+ PyObject *v = PyStructSequence_New(&StatResultType);
+ if (v == NULL)
+ return NULL;
+
+ PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
+ PyStructSequence_SET_ITEM(v, 1,
+ PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
+
+ ansec = mnsec = cnsec = 0;
+ /* The index used by fill_time is the index of the integer time.
+ fill_time will add 3 to the index to get the floating time index.
+ */
+ fill_time(v, 2, st->st_atime, ansec);
+ fill_time(v, 3, st->st_mtime, mnsec);
+ fill_time(v, 4, st->st_mtime, cnsec);
+
+#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
+ PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
+ PyInt_FromLong((long)st->st_blksize));
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
+ PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
+ PyInt_FromLong((long)st->st_blocks));
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_RDEV
+ PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
+ PyInt_FromLong((long)st->st_rdev));
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_GEN
+ PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
+ PyInt_FromLong((long)st->st_gen));
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
+ {
+ PyObject *val;
+ unsigned long bsec,bnsec;
+ bsec = (long)st->st_birthtime;
+#ifdef HAVE_STAT_TV_NSEC2
+ bnsec = st->st_birthtimespec.tv_nsec;
+#else
+ bnsec = 0;
+#endif
+ if (_stat_float_times) {
+ val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
+ } else {
+ val = PyInt_FromLong((long)bsec);
+ }
+ PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
+ val);
+ }
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_FLAGS
+ PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
+ PyInt_FromLong((long)st->st_flags));
+#endif
+
+ if (PyErr_Occurred()) {
+ Py_DECREF(v);
+ return NULL;
+ }
+
+ return v;
+}
+
+static PyObject *
+posix_do_stat(PyObject *self, PyObject *args,
+ char *format,
+ int (*statfunc)(const char *, STRUCT_STAT *),
+ char *wformat,
+ int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
+{
+ STRUCT_STAT st;
+ char *path = NULL; /* pass this to stat; do not free() it */
+ char *pathfree = NULL; /* this memory must be free'd */
+ int res;
+ PyObject *result;
+
+ if (!PyArg_ParseTuple(args, format,
+ Py_FileSystemDefaultEncoding, &path))
+ return NULL;
+ pathfree = path;
+
+ Py_BEGIN_ALLOW_THREADS
+ res = (*statfunc)(path, &st);
+ Py_END_ALLOW_THREADS
+
+ if (res != 0) {
+ result = posix_error_with_filename(pathfree);
+ }
+ else
+ result = _pystat_fromstructstat(&st);
+
+ PyMem_Free(pathfree);
+ return result;
+}
+
+/* POSIX methods */
+
+PyDoc_STRVAR(posix_access__doc__,
+"access(path, mode) -> True if granted, False otherwise\n\n\
+Use the real uid/gid to test for access to a path. Note that most\n\
+operations will use the effective uid/gid, therefore this routine can\n\
+be used in a suid/sgid environment to test if the invoking user has the\n\
+specified access to the path. The mode argument can be F_OK to test\n\
+existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
+
+static PyObject *
+posix_access(PyObject *self, PyObject *args)
+{
+ char *path;
+ int mode;
+
+ int res;
+ if (!PyArg_ParseTuple(args, "eti:access",
+ Py_FileSystemDefaultEncoding, &path, &mode))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = access(path, mode);
+ Py_END_ALLOW_THREADS
+ PyMem_Free(path);
+ return PyBool_FromLong(res == 0);
+}
+
+#ifndef F_OK
+ #define F_OK 0
+#endif
+#ifndef R_OK
+ #define R_OK 4
+#endif
+#ifndef W_OK
+ #define W_OK 2
+#endif
+#ifndef X_OK
+ #define X_OK 1
+#endif
+
+PyDoc_STRVAR(posix_chdir__doc__,
+"chdir(path)\n\n\
+Change the current working directory to the specified path.");
+
+static PyObject *
+posix_chdir(PyObject *self, PyObject *args)
+{
+ return posix_1str(args, "et:chdir", chdir);
+}
+
+PyDoc_STRVAR(posix_chmod__doc__,
+"chmod(path, mode)\n\n\
+Change the access permissions of a file.");
+
+static PyObject *
+posix_chmod(PyObject *self, PyObject *args)
+{
+ char *path = NULL;
+ int i;
+ int res;
+ if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
+ &path, &i))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = chmod(path, i);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return posix_error_with_allocated_filename(path);
+ PyMem_Free(path);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+#ifdef HAVE_FCHMOD
+PyDoc_STRVAR(posix_fchmod__doc__,
+"fchmod(fd, mode)\n\n\
+Change the access permissions of the file given by file\n\
+descriptor fd.");
+
+static PyObject *
+posix_fchmod(PyObject *self, PyObject *args)
+{
+ int fd, mode, res;
+ if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = fchmod(fd, mode);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return posix_error();
+ Py_RETURN_NONE;
+}
+#endif /* HAVE_FCHMOD */
+
+#ifdef HAVE_LCHMOD
+PyDoc_STRVAR(posix_lchmod__doc__,
+"lchmod(path, mode)\n\n\
+Change the access permissions of a file. If path is a symlink, this\n\
+affects the link itself rather than the target.");
+
+static PyObject *
+posix_lchmod(PyObject *self, PyObject *args)
+{
+ char *path = NULL;
+ int i;
+ int res;
+ if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
+ &path, &i))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = lchmod(path, i);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return posix_error_with_allocated_filename(path);
+ PyMem_Free(path);
+ Py_RETURN_NONE;
+}
+#endif /* HAVE_LCHMOD */
+
+
+#ifdef HAVE_CHFLAGS
+PyDoc_STRVAR(posix_chflags__doc__,
+"chflags(path, flags)\n\n\
+Set file flags.");
+
+static PyObject *
+posix_chflags(PyObject *self, PyObject *args)
+{
+ char *path;
+ unsigned long flags;
+ int res;
+ if (!PyArg_ParseTuple(args, "etk:chflags",
+ Py_FileSystemDefaultEncoding, &path, &flags))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = chflags(path, flags);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return posix_error_with_allocated_filename(path);
+ PyMem_Free(path);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif /* HAVE_CHFLAGS */
+
+#ifdef HAVE_LCHFLAGS
+PyDoc_STRVAR(posix_lchflags__doc__,
+"lchflags(path, flags)\n\n\
+Set file flags.\n\
+This function will not follow symbolic links.");
+
+static PyObject *
+posix_lchflags(PyObject *self, PyObject *args)
+{
+ char *path;
+ unsigned long flags;
+ int res;
+ if (!PyArg_ParseTuple(args, "etk:lchflags",
+ Py_FileSystemDefaultEncoding, &path, &flags))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = lchflags(path, flags);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return posix_error_with_allocated_filename(path);
+ PyMem_Free(path);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif /* HAVE_LCHFLAGS */
+
+#ifdef HAVE_CHROOT
+PyDoc_STRVAR(posix_chroot__doc__,
+"chroot(path)\n\n\
+Change root directory to path.");
+
+static PyObject *
+posix_chroot(PyObject *self, PyObject *args)
+{
+ return posix_1str(args, "et:chroot", chroot);
+}
+#endif
+
+#ifdef HAVE_FSYNC
+PyDoc_STRVAR(posix_fsync__doc__,
+"fsync(fildes)\n\n\
+force write of file with filedescriptor to disk.");
+
+static PyObject *
+posix_fsync(PyObject *self, PyObject *fdobj)
+{
+ return posix_fildes(fdobj, fsync);
+}
+#endif /* HAVE_FSYNC */
+
+#ifdef HAVE_FDATASYNC
+
+#ifdef __hpux
+extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
+#endif
+
+PyDoc_STRVAR(posix_fdatasync__doc__,
+"fdatasync(fildes)\n\n\
+force write of file with filedescriptor to disk.\n\
+ does not force update of metadata.");
+
+static PyObject *
+posix_fdatasync(PyObject *self, PyObject *fdobj)
+{
+ return posix_fildes(fdobj, fdatasync);
+}
+#endif /* HAVE_FDATASYNC */
+
+
+#ifdef HAVE_CHOWN
+PyDoc_STRVAR(posix_chown__doc__,
+"chown(path, uid, gid)\n\n\
+Change the owner and group id of path to the numeric uid and gid.");
+
+static PyObject *
+posix_chown(PyObject *self, PyObject *args)
+{
+ char *path = NULL;
+ long uid, gid;
+ int res;
+ if (!PyArg_ParseTuple(args, "etll:chown",
+ Py_FileSystemDefaultEncoding, &path,
+ &uid, &gid))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = chown(path, (uid_t) uid, (gid_t) gid);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return posix_error_with_allocated_filename(path);
+ PyMem_Free(path);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif /* HAVE_CHOWN */
+
+#ifdef HAVE_FCHOWN
+PyDoc_STRVAR(posix_fchown__doc__,
+"fchown(fd, uid, gid)\n\n\
+Change the owner and group id of the file given by file descriptor\n\
+fd to the numeric uid and gid.");
+
+static PyObject *
+posix_fchown(PyObject *self, PyObject *args)
+{
+ int fd;
+ long uid, gid;
+ int res;
+ if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = fchown(fd, (uid_t) uid, (gid_t) gid);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return posix_error();
+ Py_RETURN_NONE;
+}
+#endif /* HAVE_FCHOWN */
+
+#ifdef HAVE_LCHOWN
+PyDoc_STRVAR(posix_lchown__doc__,
+"lchown(path, uid, gid)\n\n\
+Change the owner and group id of path to the numeric uid and gid.\n\
+This function will not follow symbolic links.");
+
+static PyObject *
+posix_lchown(PyObject *self, PyObject *args)
+{
+ char *path = NULL;
+ long uid, gid;
+ int res;
+ if (!PyArg_ParseTuple(args, "etll:lchown",
+ Py_FileSystemDefaultEncoding, &path,
+ &uid, &gid))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = lchown(path, (uid_t) uid, (gid_t) gid);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return posix_error_with_allocated_filename(path);
+ PyMem_Free(path);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif /* HAVE_LCHOWN */
+
+
+#ifdef HAVE_GETCWD
+PyDoc_STRVAR(posix_getcwd__doc__,
+"getcwd() -> path\n\n\
+Return a string representing the current working directory.");
+
+static PyObject *
+posix_getcwd(PyObject *self, PyObject *noargs)
+{
+ int bufsize_incr = 1024;
+ int bufsize = 0;
+ char *tmpbuf = NULL;
+ char *res = NULL;
+ PyObject *dynamic_return;
+
+ Py_BEGIN_ALLOW_THREADS
+ do {
+ bufsize = bufsize + bufsize_incr;
+ tmpbuf = malloc(bufsize);
+ if (tmpbuf == NULL) {
+ break;
+ }
+ res = getcwd(tmpbuf, bufsize);
+ if (res == NULL) {
+ free(tmpbuf);
+ }
+ } while ((res == NULL) && (errno == ERANGE));
+ Py_END_ALLOW_THREADS
+
+ if (res == NULL)
+ return posix_error();
+
+ dynamic_return = PyString_FromString(tmpbuf);
+ free(tmpbuf);
+
+ return dynamic_return;
+}
+
+#ifdef Py_USING_UNICODE
+PyDoc_STRVAR(posix_getcwdu__doc__,
+"getcwdu() -> path\n\n\
+Return a unicode string representing the current working directory.");
+
+static PyObject *
+posix_getcwdu(PyObject *self, PyObject *noargs)
+{
+ char buf[1026];
+ char *res;
+
+ Py_BEGIN_ALLOW_THREADS
+ res = getcwd(buf, sizeof buf);
+ Py_END_ALLOW_THREADS
+ if (res == NULL)
+ return posix_error();
+ return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
+}
+#endif /* Py_USING_UNICODE */
+#endif /* HAVE_GETCWD */
+
+
+PyDoc_STRVAR(posix_listdir__doc__,
+"listdir(path) -> list_of_strings\n\n\
+Return a list containing the names of the entries in the directory.\n\
+\n\
+ path: path of directory to list\n\
+\n\
+The list is in arbitrary order. It does not include the special\n\
+entries '.' and '..' even if they are present in the directory.");
+
+static PyObject *
+posix_listdir(PyObject *self, PyObject *args)
+{
+ /* XXX Should redo this putting the (now four) versions of opendir
+ in separate files instead of having them all here... */
+
+ char *name = NULL;
+ char *MBname;
+ PyObject *d, *v;
+ DIR *dirp;
+ struct dirent *ep;
+ int arg_is_unicode = 1;
+
+ errno = 0;
+ if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
+ arg_is_unicode = 0;
+ PyErr_Clear();
+ }
+ if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ dirp = opendir(name);
+ Py_END_ALLOW_THREADS
+ if (dirp == NULL) {
+ return posix_error_with_allocated_filename(name);
+ }
+ if ((d = PyList_New(0)) == NULL) {
+ Py_BEGIN_ALLOW_THREADS
+ closedir(dirp);
+ Py_END_ALLOW_THREADS
+ PyMem_Free(name);
+ return NULL;
+ }
+ if((MBname = malloc(NAME_MAX)) == NULL) {
+ Py_BEGIN_ALLOW_THREADS
+ closedir(dirp);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(d);
+ PyMem_Free(name);
+ return NULL;
+ }
+ for (;;) {
+ errno = 0;
+ Py_BEGIN_ALLOW_THREADS
+ ep = readdir(dirp);
+ Py_END_ALLOW_THREADS
+ if (ep == NULL) {
+ if ((errno == 0) || (errno == EISDIR)) {
+ break;
+ } else {
+ Py_BEGIN_ALLOW_THREADS
+ closedir(dirp);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(d);
+ return posix_error_with_allocated_filename(name);
+ }
+ }
+ if (ep->FileName[0] == L'.' &&
+ (NAMLEN(ep) == 1 ||
+ (ep->FileName[1] == L'.' && NAMLEN(ep) == 2)))
+ continue;
+ if(wcstombs(MBname, ep->FileName, NAME_MAX) == -1) {
+ free(MBname);
+ Py_BEGIN_ALLOW_THREADS
+ closedir(dirp);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(d);
+ PyMem_Free(name);
+ return NULL;
+ }
+ v = PyString_FromStringAndSize(MBname, strlen(MBname));
+ if (v == NULL) {
+ Py_DECREF(d);
+ d = NULL;
+ break;
+ }
+#ifdef Py_USING_UNICODE
+ if (arg_is_unicode) {
+ PyObject *w;
+
+ w = PyUnicode_FromEncodedObject(v,
+ Py_FileSystemDefaultEncoding,
+ "strict");
+ if (w != NULL) {
+ Py_DECREF(v);
+ v = w;
+ }
+ else {
+ /* fall back to the original byte string, as
+ discussed in patch #683592 */
+ PyErr_Clear();
+ }
+ }
+#endif
+ if (PyList_Append(d, v) != 0) {
+ Py_DECREF(v);
+ Py_DECREF(d);
+ d = NULL;
+ break;
+ }
+ Py_DECREF(v);
+ }
+ Py_BEGIN_ALLOW_THREADS
+ closedir(dirp);
+ Py_END_ALLOW_THREADS
+ PyMem_Free(name);
+ if(MBname != NULL) {
+ free(MBname);
+ }
+
+ return d;
+
+} /* end of posix_listdir */
+
+#ifdef MS_WINDOWS
+/* A helper function for abspath on win32 */
+static PyObject *
+posix__getfullpathname(PyObject *self, PyObject *args)
+{
+ /* assume encoded strings won't more than double no of chars */
+ char inbuf[MAX_PATH*2];
+ char *inbufp = inbuf;
+ Py_ssize_t insize = sizeof(inbuf);
+ char outbuf[MAX_PATH*2];
+ char *temp;
+
+ PyUnicodeObject *po;
+ if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
+ Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
+ Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
+ Py_UNICODE *wtemp;
+ DWORD result;
+ PyObject *v;
+ result = GetFullPathNameW(wpath,
+ sizeof(woutbuf)/sizeof(woutbuf[0]),
+ woutbuf, &wtemp);
+ if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
+ woutbufp = malloc(result * sizeof(Py_UNICODE));
+ if (!woutbufp)
+ return PyErr_NoMemory();
+ result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
+ }
+ if (result)
+ v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
+ else
+ v = win32_error_unicode("GetFullPathNameW", wpath);
+ if (woutbufp != woutbuf)
+ free(woutbufp);
+ return v;
+ }
+ /* Drop the argument parsing error as narrow strings
+ are also valid. */
+ PyErr_Clear();
+
+ if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
+ Py_FileSystemDefaultEncoding, &inbufp,
+ &insize))
+ return NULL;
+ if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
+ outbuf, &temp))
+ return win32_error("GetFullPathName", inbuf);
+ if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
+ return PyUnicode_Decode(outbuf, strlen(outbuf),
+ Py_FileSystemDefaultEncoding, NULL);
+ }
+ return PyString_FromString(outbuf);
+} /* end of posix__getfullpathname */
+#endif /* MS_WINDOWS */
+
+PyDoc_STRVAR(posix_mkdir__doc__,
+"mkdir(path [, mode=0777])\n\n\
+Create a directory.");
+
+static PyObject *
+posix_mkdir(PyObject *self, PyObject *args)
+{
+ int res;
+ char *path = NULL;
+ int mode = 0777;
+
+ if (!PyArg_ParseTuple(args, "et|i:mkdir",
+ Py_FileSystemDefaultEncoding, &path, &mode))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = mkdir(path, mode);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return posix_error_with_allocated_filename(path);
+ PyMem_Free(path);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
+#if defined(HAVE_SYS_RESOURCE_H)
+#include <sys/resource.h>
+#endif
+
+
+#ifdef HAVE_NICE
+PyDoc_STRVAR(posix_nice__doc__,
+"nice(inc) -> new_priority\n\n\
+Decrease the priority of process by inc and return the new priority.");
+
+static PyObject *
+posix_nice(PyObject *self, PyObject *args)
+{
+ int increment, value;
+
+ if (!PyArg_ParseTuple(args, "i:nice", &increment))
+ return NULL;
+
+ /* There are two flavours of 'nice': one that returns the new
+ priority (as required by almost all standards out there) and the
+ Linux/FreeBSD/BSDI one, which returns '0' on success and advices
+ the use of getpriority() to get the new priority.
+
+ If we are of the nice family that returns the new priority, we
+ need to clear errno before the call, and check if errno is filled
+ before calling posix_error() on a returnvalue of -1, because the
+ -1 may be the actual new priority! */
+
+ errno = 0;
+ value = nice(increment);
+#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
+ if (value == 0)
+ value = getpriority(PRIO_PROCESS, 0);
+#endif
+ if (value == -1 && errno != 0)
+ /* either nice() or getpriority() returned an error */
+ return posix_error();
+ return PyInt_FromLong((long) value);
+}
+#endif /* HAVE_NICE */
+
+PyDoc_STRVAR(posix_rename__doc__,
+"rename(old, new)\n\n\
+Rename a file or directory.");
+
+static PyObject *
+posix_rename(PyObject *self, PyObject *args)
+{
+ return posix_2str(args, "etet:rename", rename);
+}
+
+
+PyDoc_STRVAR(posix_rmdir__doc__,
+"rmdir(path)\n\n\
+Remove a directory.");
+
+static PyObject *
+posix_rmdir(PyObject *self, PyObject *args)
+{
+ return posix_1str(args, "et:rmdir", rmdir);
+}
+
+
+PyDoc_STRVAR(posix_stat__doc__,
+"stat(path) -> stat result\n\n\
+Perform a stat system call on the given path.");
+
+static PyObject *
+posix_stat(PyObject *self, PyObject *args)
+{
+ return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
+}
+
+
+#ifdef HAVE_SYSTEM
+PyDoc_STRVAR(posix_system__doc__,
+"system(command) -> exit_status\n\n\
+Execute the command (a string) in a subshell.");
+
+static PyObject *
+posix_system(PyObject *self, PyObject *args)
+{
+ char *command;
+ long sts;
+ if (!PyArg_ParseTuple(args, "s:system", &command))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ sts = system(command);
+ Py_END_ALLOW_THREADS
+ return PyInt_FromLong(sts);
+}
+#endif
+
+
+PyDoc_STRVAR(posix_umask__doc__,
+"umask(new_mask) -> old_mask\n\n\
+Set the current numeric umask and return the previous umask.");
+
+static PyObject *
+posix_umask(PyObject *self, PyObject *args)
+{
+ int i;
+ if (!PyArg_ParseTuple(args, "i:umask", &i))
+ return NULL;
+ i = (int)umask(i);
+ if (i < 0)
+ return posix_error();
+ return PyInt_FromLong((long)i);
+}
+
+
+PyDoc_STRVAR(posix_unlink__doc__,
+"unlink(path)\n\n\
+Remove a file (same as remove(path)).");
+
+PyDoc_STRVAR(posix_remove__doc__,
+"remove(path)\n\n\
+Remove a file (same as unlink(path)).");
+
+static PyObject *
+posix_unlink(PyObject *self, PyObject *args)
+{
+ return posix_1str(args, "et:remove", unlink);
+}
+
+
+static int
+extract_time(PyObject *t, time_t* sec, long* usec)
+{
+ time_t intval;
+ if (PyFloat_Check(t)) {
+ double tval = PyFloat_AsDouble(t);
+ PyObject *intobj = PyNumber_Long(t);
+ if (!intobj)
+ return -1;
+#if SIZEOF_TIME_T > SIZEOF_LONG
+ intval = PyInt_AsUnsignedLongLongMask(intobj);
+#else
+ intval = PyInt_AsLong(intobj);
+#endif
+ Py_DECREF(intobj);
+ if (intval == -1 && PyErr_Occurred())
+ return -1;
+ *sec = intval;
+ *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
+ if (*usec < 0)
+ /* If rounding gave us a negative number,
+ truncate. */
+ *usec = 0;
+ return 0;
+ }
+#if SIZEOF_TIME_T > SIZEOF_LONG
+ intval = PyInt_AsUnsignedLongLongMask(t);
+#else
+ intval = PyInt_AsLong(t);
+#endif
+ if (intval == -1 && PyErr_Occurred())
+ return -1;
+ *sec = intval;
+ *usec = 0;
+ return 0;
+}
+
+PyDoc_STRVAR(posix_utime__doc__,
+"utime(path, (atime, mtime))\n\
+utime(path, None)\n\n\
+Set the access and modified time of the file to the given values. If the\n\
+second form is used, set the access and modified times to the current time.");
+
+static PyObject *
+posix_utime(PyObject *self, PyObject *args)
+{
+ char *path = NULL;
+ time_t atime, mtime;
+ long ausec, musec;
+ int res;
+ PyObject* arg;
+
+#if defined(HAVE_UTIMES)
+ struct timeval buf[2];
+#define ATIME buf[0].tv_sec
+#define MTIME buf[1].tv_sec
+#elif defined(HAVE_UTIME_H)
+/* XXX should define struct utimbuf instead, above */
+ struct utimbuf buf;
+#define ATIME buf.actime
+#define MTIME buf.modtime
+#define UTIME_ARG &buf
+#else /* HAVE_UTIMES */
+ time_t buf[2];
+#define ATIME buf[0]
+#define MTIME buf[1]
+#define UTIME_ARG buf
+#endif /* HAVE_UTIMES */
+
+
+ if (!PyArg_ParseTuple(args, "etO:utime",
+ Py_FileSystemDefaultEncoding, &path, &arg))
+ return NULL;
+ if (arg == Py_None) {
+ /* optional time values not given */
+ Py_BEGIN_ALLOW_THREADS
+ res = utime(path, NULL);
+ Py_END_ALLOW_THREADS
+ }
+ else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
+ PyErr_SetString(PyExc_TypeError,
+ "utime() arg 2 must be a tuple (atime, mtime)");
+ PyMem_Free(path);
+ return NULL;
+ }
+ else {
+ if (extract_time(PyTuple_GET_ITEM(arg, 0),
+ &atime, &ausec) == -1) {
+ PyMem_Free(path);
+ return NULL;
+ }
+ if (extract_time(PyTuple_GET_ITEM(arg, 1),
+ &mtime, &musec) == -1) {
+ PyMem_Free(path);
+ return NULL;
+ }
+ ATIME = atime;
+ MTIME = mtime;
+#ifdef HAVE_UTIMES
+ buf[0].tv_usec = ausec;
+ buf[1].tv_usec = musec;
+ Py_BEGIN_ALLOW_THREADS
+ res = utimes(path, buf);
+ Py_END_ALLOW_THREADS
+#else
+ Py_BEGIN_ALLOW_THREADS
+ res = utime(path, UTIME_ARG);
+ Py_END_ALLOW_THREADS
+#endif /* HAVE_UTIMES */
+ }
+ if (res < 0) {
+ return posix_error_with_allocated_filename(path);
+ }
+ PyMem_Free(path);
+ Py_INCREF(Py_None);
+ return Py_None;
+#undef UTIME_ARG
+#undef ATIME
+#undef MTIME
+}
+
+
+/* Process operations */
+
+PyDoc_STRVAR(posix__exit__doc__,
+"_exit(status)\n\n\
+Exit to the system with specified status, without normal exit processing.");
+
+static PyObject *
+posix__exit(PyObject *self, PyObject *args)
+{
+ int sts;
+ if (!PyArg_ParseTuple(args, "i:_exit", &sts))
+ return NULL;
+ _Exit(sts);
+ return NULL; /* Make gcc -Wall happy */
+}
+
+#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
+static void
+free_string_array(char **array, Py_ssize_t count)
+{
+ Py_ssize_t i;
+ for (i = 0; i < count; i++)
+ PyMem_Free(array[i]);
+ PyMem_DEL(array);
+}
+#endif
+
+
+#ifdef HAVE_EXECV
+PyDoc_STRVAR(posix_execv__doc__,
+"execv(path, args)\n\n\
+Execute an executable path with arguments, replacing current process.\n\
+\n\
+ path: path of executable file\n\
+ args: tuple or list of strings");
+
+static PyObject *
+posix_execv(PyObject *self, PyObject *args)
+{
+ char *path;
+ PyObject *argv;
+ char **argvlist;
+ Py_ssize_t i, argc;
+ PyObject *(*getitem)(PyObject *, Py_ssize_t);
+
+ /* execv has two arguments: (path, argv), where
+ argv is a list or tuple of strings. */
+
+ if (!PyArg_ParseTuple(args, "etO:execv",
+ Py_FileSystemDefaultEncoding,
+ &path, &argv))
+ return NULL;
+ if (PyList_Check(argv)) {
+ argc = PyList_Size(argv);
+ getitem = PyList_GetItem;
+ }
+ else if (PyTuple_Check(argv)) {
+ argc = PyTuple_Size(argv);
+ getitem = PyTuple_GetItem;
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
+ PyMem_Free(path);
+ return NULL;
+ }
+ if (argc < 1) {
+ PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
+ PyMem_Free(path);
+ return NULL;
+ }
+
+ argvlist = PyMem_NEW(char *, argc+1);
+ if (argvlist == NULL) {
+ PyMem_Free(path);
+ return PyErr_NoMemory();
+ }
+ for (i = 0; i < argc; i++) {
+ if (!PyArg_Parse((*getitem)(argv, i), "et",
+ Py_FileSystemDefaultEncoding,
+ &argvlist[i])) {
+ free_string_array(argvlist, i);
+ PyErr_SetString(PyExc_TypeError,
+ "execv() arg 2 must contain only strings");
+ PyMem_Free(path);
+ return NULL;
+
+ }
+ }
+ argvlist[argc] = NULL;
+
+ execv(path, argvlist);
+
+ /* If we get here it's definitely an error */
+
+ free_string_array(argvlist, argc);
+ PyMem_Free(path);
+ return posix_error();
+}
+
+
+PyDoc_STRVAR(posix_execve__doc__,
+"execve(path, args, env)\n\n\
+Execute a path with arguments and environment, replacing current process.\n\
+\n\
+ path: path of executable file\n\
+ args: tuple or list of arguments\n\
+ env: dictionary of strings mapping to strings");
+
+static PyObject *
+posix_execve(PyObject *self, PyObject *args)
+{
+ char *path;
+ PyObject *argv, *env;
+ char **argvlist;
+ char **envlist;
+ PyObject *key, *val, *keys=NULL, *vals=NULL;
+ Py_ssize_t i, pos, argc, envc;
+ PyObject *(*getitem)(PyObject *, Py_ssize_t);
+ Py_ssize_t lastarg = 0;
+
+ /* execve has three arguments: (path, argv, env), where
+ argv is a list or tuple of strings and env is a dictionary
+ like posix.environ. */
+
+ if (!PyArg_ParseTuple(args, "etOO:execve",
+ Py_FileSystemDefaultEncoding,
+ &path, &argv, &env))
+ return NULL;
+ if (PyList_Check(argv)) {
+ argc = PyList_Size(argv);
+ getitem = PyList_GetItem;
+ }
+ else if (PyTuple_Check(argv)) {
+ argc = PyTuple_Size(argv);
+ getitem = PyTuple_GetItem;
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "execve() arg 2 must be a tuple or list");
+ goto fail_0;
+ }
+ if (!PyMapping_Check(env)) {
+ PyErr_SetString(PyExc_TypeError,
+ "execve() arg 3 must be a mapping object");
+ goto fail_0;
+ }
+
+ argvlist = PyMem_NEW(char *, argc+1);
+ if (argvlist == NULL) {
+ PyErr_NoMemory();
+ goto fail_0;
+ }
+ for (i = 0; i < argc; i++) {
+ if (!PyArg_Parse((*getitem)(argv, i),
+ "et;execve() arg 2 must contain only strings",
+ Py_FileSystemDefaultEncoding,
+ &argvlist[i]))
+ {
+ lastarg = i;
+ goto fail_1;
+ }
+ }
+ lastarg = argc;
+ argvlist[argc] = NULL;
+
+ i = PyMapping_Size(env);
+ if (i < 0)
+ goto fail_1;
+ envlist = PyMem_NEW(char *, i + 1);
+ if (envlist == NULL) {
+ PyErr_NoMemory();
+ goto fail_1;
+ }
+ envc = 0;
+ keys = PyMapping_Keys(env);
+ vals = PyMapping_Values(env);
+ if (!keys || !vals)
+ goto fail_2;
+ if (!PyList_Check(keys) || !PyList_Check(vals)) {
+ PyErr_SetString(PyExc_TypeError,
+ "execve(): env.keys() or env.values() is not a list");
+ goto fail_2;
+ }
+
+ for (pos = 0; pos < i; pos++) {
+ char *p, *k, *v;
+ size_t len;
+
+ key = PyList_GetItem(keys, pos);
+ val = PyList_GetItem(vals, pos);
+ if (!key || !val)
+ goto fail_2;
+
+ if (!PyArg_Parse(
+ key,
+ "s;execve() arg 3 contains a non-string key",
+ &k) ||
+ !PyArg_Parse(
+ val,
+ "s;execve() arg 3 contains a non-string value",
+ &v))
+ {
+ goto fail_2;
+ }
+
+#if defined(PYOS_OS2)
+ /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
+ if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
+#endif
+ len = PyString_Size(key) + PyString_Size(val) + 2;
+ p = PyMem_NEW(char, len);
+ if (p == NULL) {
+ PyErr_NoMemory();
+ goto fail_2;
+ }
+ PyOS_snprintf(p, len, "%s=%s", k, v);
+ envlist[envc++] = p;
+#if defined(PYOS_OS2)
+ }
+#endif
+ }
+ envlist[envc] = 0;
+
+ execve(path, argvlist, envlist);
+
+ /* If we get here it's definitely an error */
+
+ (void) posix_error();
+
+ fail_2:
+ while (--envc >= 0)
+ PyMem_DEL(envlist[envc]);
+ PyMem_DEL(envlist);
+ fail_1:
+ free_string_array(argvlist, lastarg);
+ Py_XDECREF(vals);
+ Py_XDECREF(keys);
+ fail_0:
+ PyMem_Free(path);
+ return NULL;
+}
+#endif /* HAVE_EXECV */
+
+
+#ifdef HAVE_SPAWNV
+PyDoc_STRVAR(posix_spawnv__doc__,
+"spawnv(mode, path, args)\n\n\
+Execute the program 'path' in a new process.\n\
+\n\
+ mode: mode of process creation\n\
+ path: path of executable file\n\
+ args: tuple or list of strings");
+
+static PyObject *
+posix_spawnv(PyObject *self, PyObject *args)
+{
+ char *path;
+ PyObject *argv;
+ char **argvlist;
+ int mode, i;
+ Py_ssize_t argc;
+ Py_intptr_t spawnval;
+ PyObject *(*getitem)(PyObject *, Py_ssize_t);
+
+ /* spawnv has three arguments: (mode, path, argv), where
+ argv is a list or tuple of strings. */
+
+ if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
+ Py_FileSystemDefaultEncoding,
+ &path, &argv))
+ return NULL;
+ if (PyList_Check(argv)) {
+ argc = PyList_Size(argv);
+ getitem = PyList_GetItem;
+ }
+ else if (PyTuple_Check(argv)) {
+ argc = PyTuple_Size(argv);
+ getitem = PyTuple_GetItem;
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "spawnv() arg 2 must be a tuple or list");
+ PyMem_Free(path);
+ return NULL;
+ }
+
+ argvlist = PyMem_NEW(char *, argc+1);
+ if (argvlist == NULL) {
+ PyMem_Free(path);
+ return PyErr_NoMemory();
+ }
+ for (i = 0; i < argc; i++) {
+ if (!PyArg_Parse((*getitem)(argv, i), "et",
+ Py_FileSystemDefaultEncoding,
+ &argvlist[i])) {
+ free_string_array(argvlist, i);
+ PyErr_SetString(
+ PyExc_TypeError,
+ "spawnv() arg 2 must contain only strings");
+ PyMem_Free(path);
+ return NULL;
+ }
+ }
+ argvlist[argc] = NULL;
+
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+ Py_BEGIN_ALLOW_THREADS
+ spawnval = spawnv(mode, path, argvlist);
+ Py_END_ALLOW_THREADS
+#else
+ if (mode == _OLD_P_OVERLAY)
+ mode = _P_OVERLAY;
+
+ Py_BEGIN_ALLOW_THREADS
+ spawnval = _spawnv(mode, path, argvlist);
+ Py_END_ALLOW_THREADS
+#endif
+
+ free_string_array(argvlist, argc);
+ PyMem_Free(path);
+
+ if (spawnval == -1)
+ return posix_error();
+ else
+#if SIZEOF_LONG == SIZEOF_VOID_P
+ return Py_BuildValue("l", (long) spawnval);
+#else
+ return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
+#endif
+}
+
+
+PyDoc_STRVAR(posix_spawnve__doc__,
+"spawnve(mode, path, args, env)\n\n\
+Execute the program 'path' in a new process.\n\
+\n\
+ mode: mode of process creation\n\
+ path: path of executable file\n\
+ args: tuple or list of arguments\n\
+ env: dictionary of strings mapping to strings");
+
+static PyObject *
+posix_spawnve(PyObject *self, PyObject *args)
+{
+ char *path;
+ PyObject *argv, *env;
+ char **argvlist;
+ char **envlist;
+ PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
+ int mode, pos, envc;
+ Py_ssize_t argc, i;
+ Py_intptr_t spawnval;
+ PyObject *(*getitem)(PyObject *, Py_ssize_t);
+ Py_ssize_t lastarg = 0;
+
+ /* spawnve has four arguments: (mode, path, argv, env), where
+ argv is a list or tuple of strings and env is a dictionary
+ like posix.environ. */
+
+ if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
+ Py_FileSystemDefaultEncoding,
+ &path, &argv, &env))
+ return NULL;
+ if (PyList_Check(argv)) {
+ argc = PyList_Size(argv);
+ getitem = PyList_GetItem;
+ }
+ else if (PyTuple_Check(argv)) {
+ argc = PyTuple_Size(argv);
+ getitem = PyTuple_GetItem;
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "spawnve() arg 2 must be a tuple or list");
+ goto fail_0;
+ }
+ if (!PyMapping_Check(env)) {
+ PyErr_SetString(PyExc_TypeError,
+ "spawnve() arg 3 must be a mapping object");
+ goto fail_0;
+ }
+
+ argvlist = PyMem_NEW(char *, argc+1);
+ if (argvlist == NULL) {
+ PyErr_NoMemory();
+ goto fail_0;
+ }
+ for (i = 0; i < argc; i++) {
+ if (!PyArg_Parse((*getitem)(argv, i),
+ "et;spawnve() arg 2 must contain only strings",
+ Py_FileSystemDefaultEncoding,
+ &argvlist[i]))
+ {
+ lastarg = i;
+ goto fail_1;
+ }
+ }
+ lastarg = argc;
+ argvlist[argc] = NULL;
+
+ i = PyMapping_Size(env);
+ if (i < 0)
+ goto fail_1;
+ envlist = PyMem_NEW(char *, i + 1);
+ if (envlist == NULL) {
+ PyErr_NoMemory();
+ goto fail_1;
+ }
+ envc = 0;
+ keys = PyMapping_Keys(env);
+ vals = PyMapping_Values(env);
+ if (!keys || !vals)
+ goto fail_2;
+ if (!PyList_Check(keys) || !PyList_Check(vals)) {
+ PyErr_SetString(PyExc_TypeError,
+ "spawnve(): env.keys() or env.values() is not a list");
+ goto fail_2;
+ }
+
+ for (pos = 0; pos < i; pos++) {
+ char *p, *k, *v;
+ size_t len;
+
+ key = PyList_GetItem(keys, pos);
+ val = PyList_GetItem(vals, pos);
+ if (!key || !val)
+ goto fail_2;
+
+ if (!PyArg_Parse(
+ key,
+ "s;spawnve() arg 3 contains a non-string key",
+ &k) ||
+ !PyArg_Parse(
+ val,
+ "s;spawnve() arg 3 contains a non-string value",
+ &v))
+ {
+ goto fail_2;
+ }
+ len = PyString_Size(key) + PyString_Size(val) + 2;
+ p = PyMem_NEW(char, len);
+ if (p == NULL) {
+ PyErr_NoMemory();
+ goto fail_2;
+ }
+ PyOS_snprintf(p, len, "%s=%s", k, v);
+ envlist[envc++] = p;
+ }
+ envlist[envc] = 0;
+
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+ Py_BEGIN_ALLOW_THREADS
+ spawnval = spawnve(mode, path, argvlist, envlist);
+ Py_END_ALLOW_THREADS
+#else
+ if (mode == _OLD_P_OVERLAY)
+ mode = _P_OVERLAY;
+
+ Py_BEGIN_ALLOW_THREADS
+ spawnval = _spawnve(mode, path, argvlist, envlist);
+ Py_END_ALLOW_THREADS
+#endif
+
+ if (spawnval == -1)
+ (void) posix_error();
+ else
+#if SIZEOF_LONG == SIZEOF_VOID_P
+ res = Py_BuildValue("l", (long) spawnval);
+#else
+ res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
+#endif
+
+ fail_2:
+ while (--envc >= 0)
+ PyMem_DEL(envlist[envc]);
+ PyMem_DEL(envlist);
+ fail_1:
+ free_string_array(argvlist, lastarg);
+ Py_XDECREF(vals);
+ Py_XDECREF(keys);
+ fail_0:
+ PyMem_Free(path);
+ return res;
+}
+
+/* OS/2 supports spawnvp & spawnvpe natively */
+#if defined(PYOS_OS2)
+PyDoc_STRVAR(posix_spawnvp__doc__,
+"spawnvp(mode, file, args)\n\n\
+Execute the program 'file' in a new process, using the environment\n\
+search path to find the file.\n\
+\n\
+ mode: mode of process creation\n\
+ file: executable file name\n\
+ args: tuple or list of strings");
+
+static PyObject *
+posix_spawnvp(PyObject *self, PyObject *args)
+{
+ char *path;
+ PyObject *argv;
+ char **argvlist;
+ int mode, i, argc;
+ Py_intptr_t spawnval;
+ PyObject *(*getitem)(PyObject *, Py_ssize_t);
+
+ /* spawnvp has three arguments: (mode, path, argv), where
+ argv is a list or tuple of strings. */
+
+ if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
+ Py_FileSystemDefaultEncoding,
+ &path, &argv))
+ return NULL;
+ if (PyList_Check(argv)) {
+ argc = PyList_Size(argv);
+ getitem = PyList_GetItem;
+ }
+ else if (PyTuple_Check(argv)) {
+ argc = PyTuple_Size(argv);
+ getitem = PyTuple_GetItem;
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "spawnvp() arg 2 must be a tuple or list");
+ PyMem_Free(path);
+ return NULL;
+ }
+
+ argvlist = PyMem_NEW(char *, argc+1);
+ if (argvlist == NULL) {
+ PyMem_Free(path);
+ return PyErr_NoMemory();
+ }
+ for (i = 0; i < argc; i++) {
+ if (!PyArg_Parse((*getitem)(argv, i), "et",
+ Py_FileSystemDefaultEncoding,
+ &argvlist[i])) {
+ free_string_array(argvlist, i);
+ PyErr_SetString(
+ PyExc_TypeError,
+ "spawnvp() arg 2 must contain only strings");
+ PyMem_Free(path);
+ return NULL;
+ }
+ }
+ argvlist[argc] = NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+#if defined(PYCC_GCC)
+ spawnval = spawnvp(mode, path, argvlist);
+#else
+ spawnval = _spawnvp(mode, path, argvlist);
+#endif
+ Py_END_ALLOW_THREADS
+
+ free_string_array(argvlist, argc);
+ PyMem_Free(path);
+
+ if (spawnval == -1)
+ return posix_error();
+ else
+ return Py_BuildValue("l", (long) spawnval);
+}
+
+
+PyDoc_STRVAR(posix_spawnvpe__doc__,
+"spawnvpe(mode, file, args, env)\n\n\
+Execute the program 'file' in a new process, using the environment\n\
+search path to find the file.\n\
+\n\
+ mode: mode of process creation\n\
+ file: executable file name\n\
+ args: tuple or list of arguments\n\
+ env: dictionary of strings mapping to strings");
+
+static PyObject *
+posix_spawnvpe(PyObject *self, PyObject *args)
+{
+ char *path;
+ PyObject *argv, *env;
+ char **argvlist;
+ char **envlist;
+ PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
+ int mode, i, pos, argc, envc;
+ Py_intptr_t spawnval;
+ PyObject *(*getitem)(PyObject *, Py_ssize_t);
+ int lastarg = 0;
+
+ /* spawnvpe has four arguments: (mode, path, argv, env), where
+ argv is a list or tuple of strings and env is a dictionary
+ like posix.environ. */
+
+ if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
+ Py_FileSystemDefaultEncoding,
+ &path, &argv, &env))
+ return NULL;
+ if (PyList_Check(argv)) {
+ argc = PyList_Size(argv);
+ getitem = PyList_GetItem;
+ }
+ else if (PyTuple_Check(argv)) {
+ argc = PyTuple_Size(argv);
+ getitem = PyTuple_GetItem;
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "spawnvpe() arg 2 must be a tuple or list");
+ goto fail_0;
+ }
+ if (!PyMapping_Check(env)) {
+ PyErr_SetString(PyExc_TypeError,
+ "spawnvpe() arg 3 must be a mapping object");
+ goto fail_0;
+ }
+
+ argvlist = PyMem_NEW(char *, argc+1);
+ if (argvlist == NULL) {
+ PyErr_NoMemory();
+ goto fail_0;
+ }
+ for (i = 0; i < argc; i++) {
+ if (!PyArg_Parse((*getitem)(argv, i),
+ "et;spawnvpe() arg 2 must contain only strings",
+ Py_FileSystemDefaultEncoding,
+ &argvlist[i]))
+ {
+ lastarg = i;
+ goto fail_1;
+ }
+ }
+ lastarg = argc;
+ argvlist[argc] = NULL;
+
+ i = PyMapping_Size(env);
+ if (i < 0)
+ goto fail_1;
+ envlist = PyMem_NEW(char *, i + 1);
+ if (envlist == NULL) {
+ PyErr_NoMemory();
+ goto fail_1;
+ }
+ envc = 0;
+ keys = PyMapping_Keys(env);
+ vals = PyMapping_Values(env);
+ if (!keys || !vals)
+ goto fail_2;
+ if (!PyList_Check(keys) || !PyList_Check(vals)) {
+ PyErr_SetString(PyExc_TypeError,
+ "spawnvpe(): env.keys() or env.values() is not a list");
+ goto fail_2;
+ }
+
+ for (pos = 0; pos < i; pos++) {
+ char *p, *k, *v;
+ size_t len;
+
+ key = PyList_GetItem(keys, pos);
+ val = PyList_GetItem(vals, pos);
+ if (!key || !val)
+ goto fail_2;
+
+ if (!PyArg_Parse(
+ key,
+ "s;spawnvpe() arg 3 contains a non-string key",
+ &k) ||
+ !PyArg_Parse(
+ val,
+ "s;spawnvpe() arg 3 contains a non-string value",
+ &v))
+ {
+ goto fail_2;
+ }
+ len = PyString_Size(key) + PyString_Size(val) + 2;
+ p = PyMem_NEW(char, len);
+ if (p == NULL) {
+ PyErr_NoMemory();
+ goto fail_2;
+ }
+ PyOS_snprintf(p, len, "%s=%s", k, v);
+ envlist[envc++] = p;
+ }
+ envlist[envc] = 0;
+
+ Py_BEGIN_ALLOW_THREADS
+#if defined(PYCC_GCC)
+ spawnval = spawnvpe(mode, path, argvlist, envlist);
+#else
+ spawnval = _spawnvpe(mode, path, argvlist, envlist);
+#endif
+ Py_END_ALLOW_THREADS
+
+ if (spawnval == -1)
+ (void) posix_error();
+ else
+ res = Py_BuildValue("l", (long) spawnval);
+
+ fail_2:
+ while (--envc >= 0)
+ PyMem_DEL(envlist[envc]);
+ PyMem_DEL(envlist);
+ fail_1:
+ free_string_array(argvlist, lastarg);
+ Py_XDECREF(vals);
+ Py_XDECREF(keys);
+ fail_0:
+ PyMem_Free(path);
+ return res;
+}
+#endif /* PYOS_OS2 */
+#endif /* HAVE_SPAWNV */
+
+
+#ifdef HAVE_FORK1
+PyDoc_STRVAR(posix_fork1__doc__,
+"fork1() -> pid\n\n\
+Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
+\n\
+Return 0 to child process and PID of child to parent process.");
+
+static PyObject *
+posix_fork1(PyObject *self, PyObject *noargs)
+{
+ pid_t pid;
+ int result = 0;
+ _PyImport_AcquireLock();
+ pid = fork1();
+ if (pid == 0) {
+ /* child: this clobbers and resets the import lock. */
+ PyOS_AfterFork();
+ } else {
+ /* parent: release the import lock. */
+ result = _PyImport_ReleaseLock();
+ }
+ if (pid == -1)
+ return posix_error();
+ if (result < 0) {
+ /* Don't clobber the OSError if the fork failed. */
+ PyErr_SetString(PyExc_RuntimeError,
+ "not holding the import lock");
+ return NULL;
+ }
+ return PyLong_FromPid(pid);
+}
+#endif
+
+
+#ifdef HAVE_FORK
+PyDoc_STRVAR(posix_fork__doc__,
+"fork() -> pid\n\n\
+Fork a child process.\n\
+Return 0 to child process and PID of child to parent process.");
+
+static PyObject *
+posix_fork(PyObject *self, PyObject *noargs)
+{
+ pid_t pid;
+ int result = 0;
+ _PyImport_AcquireLock();
+ pid = fork();
+ if (pid == 0) {
+ /* child: this clobbers and resets the import lock. */
+ PyOS_AfterFork();
+ } else {
+ /* parent: release the import lock. */
+ result = _PyImport_ReleaseLock();
+ }
+ if (pid == -1)
+ return posix_error();
+ if (result < 0) {
+ /* Don't clobber the OSError if the fork failed. */
+ PyErr_SetString(PyExc_RuntimeError,
+ "not holding the import lock");
+ return NULL;
+ }
+ return PyLong_FromPid(pid);
+}
+#endif
+
+/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
+/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
+#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
+#define DEV_PTY_FILE "/dev/ptc"
+#define HAVE_DEV_PTMX
+#else
+#define DEV_PTY_FILE "/dev/ptmx"
+#endif
+
+#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
+#ifdef HAVE_PTY_H
+#include <pty.h>
+#else
+#ifdef HAVE_LIBUTIL_H
+#include <libutil.h>
+#else
+#ifdef HAVE_UTIL_H
+#include <util.h>
+#endif /* HAVE_UTIL_H */
+#endif /* HAVE_LIBUTIL_H */
+#endif /* HAVE_PTY_H */
+#ifdef HAVE_STROPTS_H
+#include <stropts.h>
+#endif
+#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
+
+#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
+PyDoc_STRVAR(posix_openpty__doc__,
+"openpty() -> (master_fd, slave_fd)\n\n\
+Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
+
+static PyObject *
+posix_openpty(PyObject *self, PyObject *noargs)
+{
+ int master_fd, slave_fd;
+#ifndef HAVE_OPENPTY
+ char * slave_name;
+#endif
+#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
+ PyOS_sighandler_t sig_saved;
+#ifdef sun
+ extern char *ptsname(int fildes);
+#endif
+#endif
+
+#ifdef HAVE_OPENPTY
+ if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
+ return posix_error();
+#elif defined(HAVE__GETPTY)
+ slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
+ if (slave_name == NULL)
+ return posix_error();
+
+ slave_fd = open(slave_name, O_RDWR);
+ if (slave_fd < 0)
+ return posix_error();
+#else
+ master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
+ if (master_fd < 0)
+ return posix_error();
+ sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
+ /* change permission of slave */
+ if (grantpt(master_fd) < 0) {
+ PyOS_setsig(SIGCHLD, sig_saved);
+ return posix_error();
+ }
+ /* unlock slave */
+ if (unlockpt(master_fd) < 0) {
+ PyOS_setsig(SIGCHLD, sig_saved);
+ return posix_error();
+ }
+ PyOS_setsig(SIGCHLD, sig_saved);
+ slave_name = ptsname(master_fd); /* get name of slave */
+ if (slave_name == NULL)
+ return posix_error();
+ slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
+ if (slave_fd < 0)
+ return posix_error();
+#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
+ ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
+ ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
+#ifndef __hpux
+ ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
+#endif /* __hpux */
+#endif /* HAVE_CYGWIN */
+#endif /* HAVE_OPENPTY */
+
+ return Py_BuildValue("(ii)", master_fd, slave_fd);
+
+}
+#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
+
+#ifdef HAVE_FORKPTY
+PyDoc_STRVAR(posix_forkpty__doc__,
+"forkpty() -> (pid, master_fd)\n\n\
+Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
+Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
+To both, return fd of newly opened pseudo-terminal.\n");
+
+static PyObject *
+posix_forkpty(PyObject *self, PyObject *noargs)
+{
+ int master_fd = -1, result = 0;
+ pid_t pid;
+
+ _PyImport_AcquireLock();
+ pid = forkpty(&master_fd, NULL, NULL, NULL);
+ if (pid == 0) {
+ /* child: this clobbers and resets the import lock. */
+ PyOS_AfterFork();
+ } else {
+ /* parent: release the import lock. */
+ result = _PyImport_ReleaseLock();
+ }
+ if (pid == -1)
+ return posix_error();
+ if (result < 0) {
+ /* Don't clobber the OSError if the fork failed. */
+ PyErr_SetString(PyExc_RuntimeError,
+ "not holding the import lock");
+ return NULL;
+ }
+ return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
+}
+#endif
+
+#ifdef HAVE_GETEGID
+PyDoc_STRVAR(posix_getegid__doc__,
+"getegid() -> egid\n\n\
+Return the current process's effective group id.");
+
+static PyObject *
+posix_getegid(PyObject *self, PyObject *noargs)
+{
+ return PyInt_FromLong((long)getegid());
+}
+#endif
+
+
+#ifdef HAVE_GETEUID
+PyDoc_STRVAR(posix_geteuid__doc__,
+"geteuid() -> euid\n\n\
+Return the current process's effective user id.");
+
+static PyObject *
+posix_geteuid(PyObject *self, PyObject *noargs)
+{
+ return PyInt_FromLong((long)geteuid());
+}
+#endif
+
+
+#ifdef HAVE_GETGID
+PyDoc_STRVAR(posix_getgid__doc__,
+"getgid() -> gid\n\n\
+Return the current process's group id.");
+
+static PyObject *
+posix_getgid(PyObject *self, PyObject *noargs)
+{
+ return PyInt_FromLong((long)getgid());
+}
+#endif
+
+
+PyDoc_STRVAR(posix_getpid__doc__,
+"getpid() -> pid\n\n\
+Return the current process id");
+
+static PyObject *
+posix_getpid(PyObject *self, PyObject *noargs)
+{
+ return PyLong_FromPid(getpid());
+}
+
+
+#ifdef HAVE_GETGROUPS
+PyDoc_STRVAR(posix_getgroups__doc__,
+"getgroups() -> list of group IDs\n\n\
+Return list of supplemental group IDs for the process.");
+
+static PyObject *
+posix_getgroups(PyObject *self, PyObject *noargs)
+{
+ PyObject *result = NULL;
+
+#ifdef NGROUPS_MAX
+#define MAX_GROUPS NGROUPS_MAX
+#else
+ /* defined to be 16 on Solaris7, so this should be a small number */
+#define MAX_GROUPS 64
+#endif
+ gid_t grouplist[MAX_GROUPS];
+
+ /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
+ * This is a helper variable to store the intermediate result when
+ * that happens.
+ *
+ * To keep the code readable the OSX behaviour is unconditional,
+ * according to the POSIX spec this should be safe on all unix-y
+ * systems.
+ */
+ gid_t* alt_grouplist = grouplist;
+ int n;
+
+ n = getgroups(MAX_GROUPS, grouplist);
+ if (n < 0) {
+ if (errno == EINVAL) {
+ n = getgroups(0, NULL);
+ if (n == -1) {
+ return posix_error();
+ }
+ if (n == 0) {
+ /* Avoid malloc(0) */
+ alt_grouplist = grouplist;
+ } else {
+ alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));
+ if (alt_grouplist == NULL) {
+ errno = EINVAL;
+ return posix_error();
+ }
+ n = getgroups(n, alt_grouplist);
+ if (n == -1) {
+ PyMem_Free(alt_grouplist);
+ return posix_error();
+ }
+ }
+ } else {
+ return posix_error();
+ }
+ }
+ result = PyList_New(n);
+ if (result != NULL) {
+ int i;
+ for (i = 0; i < n; ++i) {
+ PyObject *o = PyInt_FromLong((long)alt_grouplist[i]);
+ if (o == NULL) {
+ Py_DECREF(result);
+ result = NULL;
+ break;
+ }
+ PyList_SET_ITEM(result, i, o);
+ }
+ }
+
+ if (alt_grouplist != grouplist) {
+ PyMem_Free(alt_grouplist);
+ }
+
+ return result;
+}
+#endif
+
+#ifdef HAVE_INITGROUPS
+PyDoc_STRVAR(posix_initgroups__doc__,
+"initgroups(username, gid) -> None\n\n\
+Call the system initgroups() to initialize the group access list with all of\n\
+the groups of which the specified username is a member, plus the specified\n\
+group id.");
+
+static PyObject *
+posix_initgroups(PyObject *self, PyObject *args)
+{
+ char *username;
+ long gid;
+
+ if (!PyArg_ParseTuple(args, "sl:initgroups", &username, &gid))
+ return NULL;
+
+ if (initgroups(username, (gid_t) gid) == -1)
+ return PyErr_SetFromErrno(PyExc_OSError);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif
+
+#ifdef HAVE_GETPGID
+PyDoc_STRVAR(posix_getpgid__doc__,
+"getpgid(pid) -> pgid\n\n\
+Call the system call getpgid().");
+
+static PyObject *
+posix_getpgid(PyObject *self, PyObject *args)
+{
+ pid_t pid, pgid;
+ if (!PyArg_ParseTuple(args, PARSE_PID ":getpgid", &pid))
+ return NULL;
+ pgid = getpgid(pid);
+ if (pgid < 0)
+ return posix_error();
+ return PyLong_FromPid(pgid);
+}
+#endif /* HAVE_GETPGID */
+
+
+#ifdef HAVE_GETPGRP
+PyDoc_STRVAR(posix_getpgrp__doc__,
+"getpgrp() -> pgrp\n\n\
+Return the current process group id.");
+
+static PyObject *
+posix_getpgrp(PyObject *self, PyObject *noargs)
+{
+#ifdef GETPGRP_HAVE_ARG
+ return PyLong_FromPid(getpgrp(0));
+#else /* GETPGRP_HAVE_ARG */
+ return PyLong_FromPid(getpgrp());
+#endif /* GETPGRP_HAVE_ARG */
+}
+#endif /* HAVE_GETPGRP */
+
+
+#ifdef HAVE_SETPGRP
+PyDoc_STRVAR(posix_setpgrp__doc__,
+"setpgrp()\n\n\
+Make this process the process group leader.");
+
+static PyObject *
+posix_setpgrp(PyObject *self, PyObject *noargs)
+{
+#ifdef SETPGRP_HAVE_ARG
+ if (setpgrp(0, 0) < 0)
+#else /* SETPGRP_HAVE_ARG */
+ if (setpgrp() < 0)
+#endif /* SETPGRP_HAVE_ARG */
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+#endif /* HAVE_SETPGRP */
+
+#ifdef HAVE_GETPPID
+PyDoc_STRVAR(posix_getppid__doc__,
+"getppid() -> ppid\n\n\
+Return the parent's process id.");
+
+static PyObject *
+posix_getppid(PyObject *self, PyObject *noargs)
+{
+ return PyLong_FromPid(getppid());
+}
+#endif
+
+
+#ifdef HAVE_GETLOGIN
+PyDoc_STRVAR(posix_getlogin__doc__,
+"getlogin() -> string\n\n\
+Return the actual login name.");
+
+static PyObject *
+posix_getlogin(PyObject *self, PyObject *noargs)
+{
+ PyObject *result = NULL;
+ char *name;
+ int old_errno = errno;
+
+ errno = 0;
+ name = getlogin();
+ if (name == NULL) {
+ if (errno)
+ posix_error();
+ else
+ PyErr_SetString(PyExc_OSError,
+ "unable to determine login name");
+ }
+ else
+ result = PyString_FromString(name);
+ errno = old_errno;
+
+ return result;
+}
+#endif
+
+#ifndef UEFI_C_SOURCE
+PyDoc_STRVAR(posix_getuid__doc__,
+"getuid() -> uid\n\n\
+Return the current process's user id.");
+
+static PyObject *
+posix_getuid(PyObject *self, PyObject *noargs)
+{
+ return PyInt_FromLong((long)getuid());
+}
+#endif /* UEFI_C_SOURCE */
+
+#ifdef HAVE_KILL
+PyDoc_STRVAR(posix_kill__doc__,
+"kill(pid, sig)\n\n\
+Kill a process with a signal.");
+
+static PyObject *
+posix_kill(PyObject *self, PyObject *args)
+{
+ pid_t pid;
+ int sig;
+ if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))
+ return NULL;
+#if defined(PYOS_OS2) && !defined(PYCC_GCC)
+ if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
+ APIRET rc;
+ if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
+ return os2_error(rc);
+
+ } else if (sig == XCPT_SIGNAL_KILLPROC) {
+ APIRET rc;
+ if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
+ return os2_error(rc);
+
+ } else
+ return NULL; /* Unrecognized Signal Requested */
+#else
+ if (kill(pid, sig) == -1)
+ return posix_error();
+#endif
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif
+
+#ifdef HAVE_KILLPG
+PyDoc_STRVAR(posix_killpg__doc__,
+"killpg(pgid, sig)\n\n\
+Kill a process group with a signal.");
+
+static PyObject *
+posix_killpg(PyObject *self, PyObject *args)
+{
+ int sig;
+ pid_t pgid;
+ /* XXX some man pages make the `pgid` parameter an int, others
+ a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
+ take the same type. Moreover, pid_t is always at least as wide as
+ int (else compilation of this module fails), which is safe. */
+ if (!PyArg_ParseTuple(args, PARSE_PID "i:killpg", &pgid, &sig))
+ return NULL;
+ if (killpg(pgid, sig) == -1)
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif
+
+#ifdef HAVE_PLOCK
+
+#ifdef HAVE_SYS_LOCK_H
+#include <sys/lock.h>
+#endif
+
+PyDoc_STRVAR(posix_plock__doc__,
+"plock(op)\n\n\
+Lock program segments into memory.");
+
+static PyObject *
+posix_plock(PyObject *self, PyObject *args)
+{
+ int op;
+ if (!PyArg_ParseTuple(args, "i:plock", &op))
+ return NULL;
+ if (plock(op) == -1)
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif
+
+
+#ifdef HAVE_POPEN
+PyDoc_STRVAR(posix_popen__doc__,
+"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
+Open a pipe to/from a command returning a file object.");
+
+#if defined(PYOS_OS2)
+#if defined(PYCC_VACPP)
+static int
+async_system(const char *command)
+{
+ char errormsg[256], args[1024];
+ RESULTCODES rcodes;
+ APIRET rc;
+
+ char *shell = getenv("COMSPEC");
+ if (!shell)
+ shell = "cmd";
+
+ /* avoid overflowing the argument buffer */
+ if (strlen(shell) + 3 + strlen(command) >= 1024)
+ return ERROR_NOT_ENOUGH_MEMORY
+
+ args[0] = '\0';
+ strcat(args, shell);
+ strcat(args, "/c ");
+ strcat(args, command);
+
+ /* execute asynchronously, inheriting the environment */
+ rc = DosExecPgm(errormsg,
+ sizeof(errormsg),
+ EXEC_ASYNC,
+ args,
+ NULL,
+ &rcodes,
+ shell);
+ return rc;
+}
+
+static FILE *
+popen(const char *command, const char *mode, int pipesize, int *err)
+{
+ int oldfd, tgtfd;
+ HFILE pipeh[2];
+ APIRET rc;
+
+ /* mode determines which of stdin or stdout is reconnected to
+ * the pipe to the child
+ */
+ if (strchr(mode, 'r') != NULL) {
+ tgt_fd = 1; /* stdout */
+ } else if (strchr(mode, 'w')) {
+ tgt_fd = 0; /* stdin */
+ } else {
+ *err = ERROR_INVALID_ACCESS;
+ return NULL;
+ }
+
+ /* setup the pipe */
+ if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
+ *err = rc;
+ return NULL;
+ }
+
+ /* prevent other threads accessing stdio */
+ DosEnterCritSec();
+
+ /* reconnect stdio and execute child */
+ oldfd = dup(tgtfd);
+ close(tgtfd);
+ if (dup2(pipeh[tgtfd], tgtfd) == 0) {
+ DosClose(pipeh[tgtfd]);
+ rc = async_system(command);
+ }
+
+ /* restore stdio */
+ dup2(oldfd, tgtfd);
+ close(oldfd);
+
+ /* allow other threads access to stdio */
+ DosExitCritSec();
+
+ /* if execution of child was successful return file stream */
+ if (rc == NO_ERROR)
+ return fdopen(pipeh[1 - tgtfd], mode);
+ else {
+ DosClose(pipeh[1 - tgtfd]);
+ *err = rc;
+ return NULL;
+ }
+}
+
+static PyObject *
+posix_popen(PyObject *self, PyObject *args)
+{
+ char *name;
+ char *mode = "r";
+ int err, bufsize = -1;
+ FILE *fp;
+ PyObject *f;
+ if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
+ Py_END_ALLOW_THREADS
+ if (fp == NULL)
+ return os2_error(err);
+
+ f = PyFile_FromFile(fp, name, mode, fclose);
+ if (f != NULL)
+ PyFile_SetBufSize(f, bufsize);
+ return f;
+}
+
+#elif defined(PYCC_GCC)
+
+/* standard posix version of popen() support */
+static PyObject *
+posix_popen(PyObject *self, PyObject *args)
+{
+ char *name;
+ char *mode = "r";
+ int bufsize = -1;
+ FILE *fp;
+ PyObject *f;
+ if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ fp = popen(name, mode);
+ Py_END_ALLOW_THREADS
+ if (fp == NULL)
+ return posix_error();
+ f = PyFile_FromFile(fp, name, mode, pclose);
+ if (f != NULL)
+ PyFile_SetBufSize(f, bufsize);
+ return f;
+}
+
+/* fork() under OS/2 has lots'o'warts
+ * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
+ * most of this code is a ripoff of the win32 code, but using the
+ * capabilities of EMX's C library routines
+ */
+
+/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
+#define POPEN_1 1
+#define POPEN_2 2
+#define POPEN_3 3
+#define POPEN_4 4
+
+static PyObject *_PyPopen(char *, int, int, int);
+static int _PyPclose(FILE *file);
+
+/*
+ * Internal dictionary mapping popen* file pointers to process handles,
+ * for use when retrieving the process exit code. See _PyPclose() below
+ * for more information on this dictionary's use.
+ */
+static PyObject *_PyPopenProcs = NULL;
+
+/* os2emx version of popen2()
+ *
+ * The result of this function is a pipe (file) connected to the
+ * process's stdin, and a pipe connected to the process's stdout.
+ */
+
+static PyObject *
+os2emx_popen2(PyObject *self, PyObject *args)
+{
+ PyObject *f;
+ int tm=0;
+
+ char *cmdstring;
+ char *mode = "t";
+ int bufsize = -1;
+ if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
+ return NULL;
+
+ if (*mode == 't')
+ tm = O_TEXT;
+ else if (*mode != 'b') {
+ PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
+ return NULL;
+ } else
+ tm = O_BINARY;
+
+ f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
+
+ return f;
+}
+
+/*
+ * Variation on os2emx.popen2
+ *
+ * The result of this function is 3 pipes - the process's stdin,
+ * stdout and stderr
+ */
+
+static PyObject *
+os2emx_popen3(PyObject *self, PyObject *args)
+{
+ PyObject *f;
+ int tm = 0;
+
+ char *cmdstring;
+ char *mode = "t";
+ int bufsize = -1;
+ if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
+ return NULL;
+
+ if (*mode == 't')
+ tm = O_TEXT;
+ else if (*mode != 'b') {
+ PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
+ return NULL;
+ } else
+ tm = O_BINARY;
+
+ f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
+
+ return f;
+}
+
+/*
+ * Variation on os2emx.popen2
+ *
+ * The result of this function is 2 pipes - the processes stdin,
+ * and stdout+stderr combined as a single pipe.
+ */
+
+static PyObject *
+os2emx_popen4(PyObject *self, PyObject *args)
+{
+ PyObject *f;
+ int tm = 0;
+
+ char *cmdstring;
+ char *mode = "t";
+ int bufsize = -1;
+ if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
+ return NULL;
+
+ if (*mode == 't')
+ tm = O_TEXT;
+ else if (*mode != 'b') {
+ PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
+ return NULL;
+ } else
+ tm = O_BINARY;
+
+ f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
+
+ return f;
+}
+
+/* a couple of structures for convenient handling of multiple
+ * file handles and pipes
+ */
+struct file_ref
+{
+ int handle;
+ int flags;
+};
+
+struct pipe_ref
+{
+ int rd;
+ int wr;
+};
+
+/* The following code is derived from the win32 code */
+
+static PyObject *
+_PyPopen(char *cmdstring, int mode, int n, int bufsize)
+{
+ struct file_ref stdio[3];
+ struct pipe_ref p_fd[3];
+ FILE *p_s[3];
+ int file_count, i, pipe_err;
+ pid_t pipe_pid;
+ char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
+ PyObject *f, *p_f[3];
+
+ /* file modes for subsequent fdopen's on pipe handles */
+ if (mode == O_TEXT)
+ {
+ rd_mode = "rt";
+ wr_mode = "wt";
+ }
+ else
+ {
+ rd_mode = "rb";
+ wr_mode = "wb";
+ }
+
+ /* prepare shell references */
+ if ((shell = getenv("EMXSHELL")) == NULL)
+ if ((shell = getenv("COMSPEC")) == NULL)
+ {
+ errno = ENOENT;
+ return posix_error();
+ }
+
+ sh_name = _getname(shell);
+ if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
+ opt = "/c";
+ else
+ opt = "-c";
+
+ /* save current stdio fds + their flags, and set not inheritable */
+ i = pipe_err = 0;
+ while (pipe_err >= 0 && i < 3)
+ {
+ pipe_err = stdio[i].handle = dup(i);
+ stdio[i].flags = fcntl(i, F_GETFD, 0);
+ fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
+ i++;
+ }
+ if (pipe_err < 0)
+ {
+ /* didn't get them all saved - clean up and bail out */
+ int saved_err = errno;
+ while (i-- > 0)
+ {
+ close(stdio[i].handle);
+ }
+ errno = saved_err;
+ return posix_error();
+ }
+
+ /* create pipe ends */
+ file_count = 2;
+ if (n == POPEN_3)
+ file_count = 3;
+ i = pipe_err = 0;
+ while ((pipe_err == 0) && (i < file_count))
+ pipe_err = pipe((int *)&p_fd[i++]);
+ if (pipe_err < 0)
+ {
+ /* didn't get them all made - clean up and bail out */
+ while (i-- > 0)
+ {
+ close(p_fd[i].wr);
+ close(p_fd[i].rd);
+ }
+ errno = EPIPE;
+ return posix_error();
+ }
+
+ /* change the actual standard IO streams over temporarily,
+ * making the retained pipe ends non-inheritable
+ */
+ pipe_err = 0;
+
+ /* - stdin */
+ if (dup2(p_fd[0].rd, 0) == 0)
+ {
+ close(p_fd[0].rd);
+ i = fcntl(p_fd[0].wr, F_GETFD, 0);
+ fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
+ if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
+ {
+ close(p_fd[0].wr);
+ pipe_err = -1;
+ }
+ }
+ else
+ {
+ pipe_err = -1;
+ }
+
+ /* - stdout */
+ if (pipe_err == 0)
+ {
+ if (dup2(p_fd[1].wr, 1) == 1)
+ {
+ close(p_fd[1].wr);
+ i = fcntl(p_fd[1].rd, F_GETFD, 0);
+ fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
+ if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
+ {
+ close(p_fd[1].rd);
+ pipe_err = -1;
+ }
+ }
+ else
+ {
+ pipe_err = -1;
+ }
+ }
+
+ /* - stderr, as required */
+ if (pipe_err == 0)
+ switch (n)
+ {
+ case POPEN_3:
+ {
+ if (dup2(p_fd[2].wr, 2) == 2)
+ {
+ close(p_fd[2].wr);
+ i = fcntl(p_fd[2].rd, F_GETFD, 0);
+ fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
+ if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
+ {
+ close(p_fd[2].rd);
+ pipe_err = -1;
+ }
+ }
+ else
+ {
+ pipe_err = -1;
+ }
+ break;
+ }
+
+ case POPEN_4:
+ {
+ if (dup2(1, 2) != 2)
+ {
+ pipe_err = -1;
+ }
+ break;
+ }
+ }
+
+ /* spawn the child process */
+ if (pipe_err == 0)
+ {
+ pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
+ if (pipe_pid == -1)
+ {
+ pipe_err = -1;
+ }
+ else
+ {
+ /* save the PID into the FILE structure
+ * NOTE: this implementation doesn't actually
+ * take advantage of this, but do it for
+ * completeness - AIM Apr01
+ */
+ for (i = 0; i < file_count; i++)
+ p_s[i]->_pid = pipe_pid;
+ }
+ }
+
+ /* reset standard IO to normal */
+ for (i = 0; i < 3; i++)
+ {
+ dup2(stdio[i].handle, i);
+ fcntl(i, F_SETFD, stdio[i].flags);
+ close(stdio[i].handle);
+ }
+
+ /* if any remnant problems, clean up and bail out */
+ if (pipe_err < 0)
+ {
+ for (i = 0; i < 3; i++)
+ {
+ close(p_fd[i].rd);
+ close(p_fd[i].wr);
+ }
+ errno = EPIPE;
+ return posix_error_with_filename(cmdstring);
+ }
+
+ /* build tuple of file objects to return */
+ if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
+ PyFile_SetBufSize(p_f[0], bufsize);
+ if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
+ PyFile_SetBufSize(p_f[1], bufsize);
+ if (n == POPEN_3)
+ {
+ if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
+ PyFile_SetBufSize(p_f[0], bufsize);
+ f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
+ }
+ else
+ f = PyTuple_Pack(2, p_f[0], p_f[1]);
+
+ /*
+ * Insert the files we've created into the process dictionary
+ * all referencing the list with the process handle and the
+ * initial number of files (see description below in _PyPclose).
+ * Since if _PyPclose later tried to wait on a process when all
+ * handles weren't closed, it could create a deadlock with the
+ * child, we spend some energy here to try to ensure that we
+ * either insert all file handles into the dictionary or none
+ * at all. It's a little clumsy with the various popen modes
+ * and variable number of files involved.
+ */
+ if (!_PyPopenProcs)
+ {
+ _PyPopenProcs = PyDict_New();
+ }
+
+ if (_PyPopenProcs)
+ {
+ PyObject *procObj, *pidObj, *intObj, *fileObj[3];
+ int ins_rc[3];
+
+ fileObj[0] = fileObj[1] = fileObj[2] = NULL;
+ ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
+
+ procObj = PyList_New(2);
+ pidObj = PyLong_FromPid(pipe_pid);
+ intObj = PyInt_FromLong((long) file_count);
+
+ if (procObj && pidObj && intObj)
+ {
+ PyList_SetItem(procObj, 0, pidObj);
+ PyList_SetItem(procObj, 1, intObj);
+
+ fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
+ if (fileObj[0])
+ {
+ ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
+ fileObj[0],
+ procObj);
+ }
+ fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
+ if (fileObj[1])
+ {
+ ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
+ fileObj[1],
+ procObj);
+ }
+ if (file_count >= 3)
+ {
+ fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
+ if (fileObj[2])
+ {
+ ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
+ fileObj[2],
+ procObj);
+ }
+ }
+
+ if (ins_rc[0] < 0 || !fileObj[0] ||
+ ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
+ ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
+ {
+ /* Something failed - remove any dictionary
+ * entries that did make it.
+ */
+ if (!ins_rc[0] && fileObj[0])
+ {
+ PyDict_DelItem(_PyPopenProcs,
+ fileObj[0]);
+ }
+ if (!ins_rc[1] && fileObj[1])
+ {
+ PyDict_DelItem(_PyPopenProcs,
+ fileObj[1]);
+ }
+ if (!ins_rc[2] && fileObj[2])
+ {
+ PyDict_DelItem(_PyPopenProcs,
+ fileObj[2]);
+ }
+ }
+ }
+
+ /*
+ * Clean up our localized references for the dictionary keys
+ * and value since PyDict_SetItem will Py_INCREF any copies
+ * that got placed in the dictionary.
+ */
+ Py_XDECREF(procObj);
+ Py_XDECREF(fileObj[0]);
+ Py_XDECREF(fileObj[1]);
+ Py_XDECREF(fileObj[2]);
+ }
+
+ /* Child is launched. */
+ return f;
+}
+
+/*
+ * Wrapper for fclose() to use for popen* files, so we can retrieve the
+ * exit code for the child process and return as a result of the close.
+ *
+ * This function uses the _PyPopenProcs dictionary in order to map the
+ * input file pointer to information about the process that was
+ * originally created by the popen* call that created the file pointer.
+ * The dictionary uses the file pointer as a key (with one entry
+ * inserted for each file returned by the original popen* call) and a
+ * single list object as the value for all files from a single call.
+ * The list object contains the Win32 process handle at [0], and a file
+ * count at [1], which is initialized to the total number of file
+ * handles using that list.
+ *
+ * This function closes whichever handle it is passed, and decrements
+ * the file count in the dictionary for the process handle pointed to
+ * by this file. On the last close (when the file count reaches zero),
+ * this function will wait for the child process and then return its
+ * exit code as the result of the close() operation. This permits the
+ * files to be closed in any order - it is always the close() of the
+ * final handle that will return the exit code.
+ *
+ * NOTE: This function is currently called with the GIL released.
+ * hence we use the GILState API to manage our state.
+ */
+
+static int _PyPclose(FILE *file)
+{
+ int result;
+ int exit_code;
+ pid_t pipe_pid;
+ PyObject *procObj, *pidObj, *intObj, *fileObj;
+ int file_count;
+#ifdef WITH_THREAD
+ PyGILState_STATE state;
+#endif
+
+ /* Close the file handle first, to ensure it can't block the
+ * child from exiting if it's the last handle.
+ */
+ result = fclose(file);
+
+#ifdef WITH_THREAD
+ state = PyGILState_Ensure();
+#endif
+ if (_PyPopenProcs)
+ {
+ if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
+ (procObj = PyDict_GetItem(_PyPopenProcs,
+ fileObj)) != NULL &&
+ (pidObj = PyList_GetItem(procObj,0)) != NULL &&
+ (intObj = PyList_GetItem(procObj,1)) != NULL)
+ {
+ pipe_pid = (pid_t) PyLong_AsPid(pidObj);
+ file_count = (int) PyInt_AsLong(intObj);
+
+ if (file_count > 1)
+ {
+ /* Still other files referencing process */
+ file_count--;
+ PyList_SetItem(procObj,1,
+ PyInt_FromLong((long) file_count));
+ }
+ else
+ {
+ /* Last file for this process */
+ if (result != EOF &&
+ waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
+ {
+ /* extract exit status */
+ if (WIFEXITED(exit_code))
+ {
+ result = WEXITSTATUS(exit_code);
+ }
+ else
+ {
+ errno = EPIPE;
+ result = -1;
+ }
+ }
+ else
+ {
+ /* Indicate failure - this will cause the file object
+ * to raise an I/O error and translate the last
+ * error code from errno. We do have a problem with
+ * last errors that overlap the normal errno table,
+ * but that's a consistent problem with the file object.
+ */
+ result = -1;
+ }
+ }
+
+ /* Remove this file pointer from dictionary */
+ PyDict_DelItem(_PyPopenProcs, fileObj);
+
+ if (PyDict_Size(_PyPopenProcs) == 0)
+ {
+ Py_DECREF(_PyPopenProcs);
+ _PyPopenProcs = NULL;
+ }
+
+ } /* if object retrieval ok */
+
+ Py_XDECREF(fileObj);
+ } /* if _PyPopenProcs */
+
+#ifdef WITH_THREAD
+ PyGILState_Release(state);
+#endif
+ return result;
+}
+
+#endif /* PYCC_??? */
+
+#elif defined(MS_WINDOWS)
+
+/*
+ * Portable 'popen' replacement for Win32.
+ *
+ * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
+ * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
+ * Return code handling by David Bolen <db3l@fitlinxx.com>.
+ */
+
+#include <malloc.h>
+#include <io.h>
+#include <fcntl.h>
+
+/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
+#define POPEN_1 1
+#define POPEN_2 2
+#define POPEN_3 3
+#define POPEN_4 4
+
+static PyObject *_PyPopen(char *, int, int);
+static int _PyPclose(FILE *file);
+
+/*
+ * Internal dictionary mapping popen* file pointers to process handles,
+ * for use when retrieving the process exit code. See _PyPclose() below
+ * for more information on this dictionary's use.
+ */
+static PyObject *_PyPopenProcs = NULL;
+
+
+/* popen that works from a GUI.
+ *
+ * The result of this function is a pipe (file) connected to the
+ * processes stdin or stdout, depending on the requested mode.
+ */
+
+static PyObject *
+posix_popen(PyObject *self, PyObject *args)
+{
+ PyObject *f;
+ int tm = 0;
+
+ char *cmdstring;
+ char *mode = "r";
+ int bufsize = -1;
+ if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
+ return NULL;
+
+ if (*mode == 'r')
+ tm = _O_RDONLY;
+ else if (*mode != 'w') {
+ PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
+ return NULL;
+ } else
+ tm = _O_WRONLY;
+
+ if (bufsize != -1) {
+ PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
+ return NULL;
+ }
+
+ if (*(mode+1) == 't')
+ f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
+ else if (*(mode+1) == 'b')
+ f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
+ else
+ f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
+
+ return f;
+}
+
+/* Variation on win32pipe.popen
+ *
+ * The result of this function is a pipe (file) connected to the
+ * process's stdin, and a pipe connected to the process's stdout.
+ */
+
+static PyObject *
+win32_popen2(PyObject *self, PyObject *args)
+{
+ PyObject *f;
+ int tm=0;
+
+ char *cmdstring;
+ char *mode = "t";
+ int bufsize = -1;
+ if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
+ return NULL;
+
+ if (*mode == 't')
+ tm = _O_TEXT;
+ else if (*mode != 'b') {
+ PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
+ return NULL;
+ } else
+ tm = _O_BINARY;
+
+ if (bufsize != -1) {
+ PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
+ return NULL;
+ }
+
+ f = _PyPopen(cmdstring, tm, POPEN_2);
+
+ return f;
+}
+
+/*
+ * Variation on <om win32pipe.popen>
+ *
+ * The result of this function is 3 pipes - the process's stdin,
+ * stdout and stderr
+ */
+
+static PyObject *
+win32_popen3(PyObject *self, PyObject *args)
+{
+ PyObject *f;
+ int tm = 0;
+
+ char *cmdstring;
+ char *mode = "t";
+ int bufsize = -1;
+ if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
+ return NULL;
+
+ if (*mode == 't')
+ tm = _O_TEXT;
+ else if (*mode != 'b') {
+ PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
+ return NULL;
+ } else
+ tm = _O_BINARY;
+
+ if (bufsize != -1) {
+ PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
+ return NULL;
+ }
+
+ f = _PyPopen(cmdstring, tm, POPEN_3);
+
+ return f;
+}
+
+/*
+ * Variation on win32pipe.popen
+ *
+ * The result of this function is 2 pipes - the processes stdin,
+ * and stdout+stderr combined as a single pipe.
+ */
+
+static PyObject *
+win32_popen4(PyObject *self, PyObject *args)
+{
+ PyObject *f;
+ int tm = 0;
+
+ char *cmdstring;
+ char *mode = "t";
+ int bufsize = -1;
+ if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
+ return NULL;
+
+ if (*mode == 't')
+ tm = _O_TEXT;
+ else if (*mode != 'b') {
+ PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
+ return NULL;
+ } else
+ tm = _O_BINARY;
+
+ if (bufsize != -1) {
+ PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
+ return NULL;
+ }
+
+ f = _PyPopen(cmdstring, tm, POPEN_4);
+
+ return f;
+}
+
+static BOOL
+_PyPopenCreateProcess(char *cmdstring,
+ HANDLE hStdin,
+ HANDLE hStdout,
+ HANDLE hStderr,
+ HANDLE *hProcess)
+{
+ PROCESS_INFORMATION piProcInfo;
+ STARTUPINFO siStartInfo;
+ DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
+ char *s1,*s2, *s3 = " /c ";
+ const char *szConsoleSpawn = "w9xpopen.exe";
+ int i;
+ Py_ssize_t x;
+
+ if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
+ char *comshell;
+
+ s1 = (char *)alloca(i);
+ if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
+ /* x < i, so x fits into an integer */
+ return (int)x;
+
+ /* Explicitly check if we are using COMMAND.COM. If we are
+ * then use the w9xpopen hack.
+ */
+ comshell = s1 + x;
+ while (comshell >= s1 && *comshell != '\\')
+ --comshell;
+ ++comshell;
+
+ if (GetVersion() < 0x80000000 &&
+ _stricmp(comshell, "command.com") != 0) {
+ /* NT/2000 and not using command.com. */
+ x = i + strlen(s3) + strlen(cmdstring) + 1;
+ s2 = (char *)alloca(x);
+ ZeroMemory(s2, x);
+ PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
+ }
+ else {
+ /*
+ * Oh gag, we're on Win9x or using COMMAND.COM. Use
+ * the workaround listed in KB: Q150956
+ */
+ char modulepath[_MAX_PATH];
+ struct stat statinfo;
+ GetModuleFileName(NULL, modulepath, sizeof(modulepath));
+ for (x = i = 0; modulepath[i]; i++)
+ if (modulepath[i] == SEP)
+ x = i+1;
+ modulepath[x] = '\0';
+ /* Create the full-name to w9xpopen, so we can test it exists */
+ strncat(modulepath,
+ szConsoleSpawn,
+ (sizeof(modulepath)/sizeof(modulepath[0]))
+ -strlen(modulepath));
+ if (stat(modulepath, &statinfo) != 0) {
+ size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
+ /* Eeek - file-not-found - possibly an embedding
+ situation - see if we can locate it in sys.prefix
+ */
+ strncpy(modulepath,
+ Py_GetExecPrefix(),
+ mplen);
+ modulepath[mplen-1] = '\0';
+ if (modulepath[strlen(modulepath)-1] != '\\')
+ strcat(modulepath, "\\");
+ strncat(modulepath,
+ szConsoleSpawn,
+ mplen-strlen(modulepath));
+ /* No where else to look - raise an easily identifiable
+ error, rather than leaving Windows to report
+ "file not found" - as the user is probably blissfully
+ unaware this shim EXE is used, and it will confuse them.
+ (well, it confused me for a while ;-)
+ */
+ if (stat(modulepath, &statinfo) != 0) {
+ PyErr_Format(PyExc_RuntimeError,
+ "Can not locate '%s' which is needed "
+ "for popen to work with your shell "
+ "or platform.",
+ szConsoleSpawn);
+ return FALSE;
+ }
+ }
+ x = i + strlen(s3) + strlen(cmdstring) + 1 +
+ strlen(modulepath) +
+ strlen(szConsoleSpawn) + 1;
+
+ s2 = (char *)alloca(x);
+ ZeroMemory(s2, x);
+ /* To maintain correct argument passing semantics,
+ we pass the command-line as it stands, and allow
+ quoting to be applied. w9xpopen.exe will then
+ use its argv vector, and re-quote the necessary
+ args for the ultimate child process.
+ */
+ PyOS_snprintf(
+ s2, x,
+ "\"%s\" %s%s%s",
+ modulepath,
+ s1,
+ s3,
+ cmdstring);
+ /* Not passing CREATE_NEW_CONSOLE has been known to
+ cause random failures on win9x. Specifically a
+ dialog:
+ "Your program accessed mem currently in use at xxx"
+ and a hopeful warning about the stability of your
+ system.
+ Cost is Ctrl+C won't kill children, but anyone
+ who cares can have a go!
+ */
+ dwProcessFlags |= CREATE_NEW_CONSOLE;
+ }
+ }
+
+ /* Could be an else here to try cmd.exe / command.com in the path
+ Now we'll just error out.. */
+ else {
+ PyErr_SetString(PyExc_RuntimeError,
+ "Cannot locate a COMSPEC environment variable to "
+ "use as the shell");
+ return FALSE;
+ }
+
+ ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
+ siStartInfo.cb = sizeof(STARTUPINFO);
+ siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
+ siStartInfo.hStdInput = hStdin;
+ siStartInfo.hStdOutput = hStdout;
+ siStartInfo.hStdError = hStderr;
+ siStartInfo.wShowWindow = SW_HIDE;
+
+ if (CreateProcess(NULL,
+ s2,
+ NULL,
+ NULL,
+ TRUE,
+ dwProcessFlags,
+ NULL,
+ NULL,
+ &siStartInfo,
+ &piProcInfo) ) {
+ /* Close the handles now so anyone waiting is woken. */
+ CloseHandle(piProcInfo.hThread);
+
+ /* Return process handle */
+ *hProcess = piProcInfo.hProcess;
+ return TRUE;
+ }
+ win32_error("CreateProcess", s2);
+ return FALSE;
+}
+
+/* The following code is based off of KB: Q190351 */
+
+static PyObject *
+_PyPopen(char *cmdstring, int mode, int n)
+{
+ HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
+ hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
+ hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
+
+ SECURITY_ATTRIBUTES saAttr;
+ BOOL fSuccess;
+ int fd1, fd2, fd3;
+ FILE *f1, *f2, *f3;
+ long file_count;
+ PyObject *f;
+
+ saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
+ saAttr.bInheritHandle = TRUE;
+ saAttr.lpSecurityDescriptor = NULL;
+
+ if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
+ return win32_error("CreatePipe", NULL);
+
+ /* Create new output read handle and the input write handle. Set
+ * the inheritance properties to FALSE. Otherwise, the child inherits
+ * these handles; resulting in non-closeable handles to the pipes
+ * being created. */
+ fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
+ GetCurrentProcess(), &hChildStdinWrDup, 0,
+ FALSE,
+ DUPLICATE_SAME_ACCESS);
+ if (!fSuccess)
+ return win32_error("DuplicateHandle", NULL);
+
+ /* Close the inheritable version of ChildStdin
+ that we're using. */
+ CloseHandle(hChildStdinWr);
+
+ if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
+ return win32_error("CreatePipe", NULL);
+
+ fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
+ GetCurrentProcess(), &hChildStdoutRdDup, 0,
+ FALSE, DUPLICATE_SAME_ACCESS);
+ if (!fSuccess)
+ return win32_error("DuplicateHandle", NULL);
+
+ /* Close the inheritable version of ChildStdout
+ that we're using. */
+ CloseHandle(hChildStdoutRd);
+
+ if (n != POPEN_4) {
+ if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
+ return win32_error("CreatePipe", NULL);
+ fSuccess = DuplicateHandle(GetCurrentProcess(),
+ hChildStderrRd,
+ GetCurrentProcess(),
+ &hChildStderrRdDup, 0,
+ FALSE, DUPLICATE_SAME_ACCESS);
+ if (!fSuccess)
+ return win32_error("DuplicateHandle", NULL);
+ /* Close the inheritable version of ChildStdErr that we're using. */
+ CloseHandle(hChildStderrRd);
+ }
+
+ switch (n) {
+ case POPEN_1:
+ switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
+ case _O_WRONLY | _O_TEXT:
+ /* Case for writing to child Stdin in text mode. */
+ fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
+ f1 = _fdopen(fd1, "w");
+ f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
+ PyFile_SetBufSize(f, 0);
+ /* We don't care about these pipes anymore, so close them. */
+ CloseHandle(hChildStdoutRdDup);
+ CloseHandle(hChildStderrRdDup);
+ break;
+
+ case _O_RDONLY | _O_TEXT:
+ /* Case for reading from child Stdout in text mode. */
+ fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
+ f1 = _fdopen(fd1, "r");
+ f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
+ PyFile_SetBufSize(f, 0);
+ /* We don't care about these pipes anymore, so close them. */
+ CloseHandle(hChildStdinWrDup);
+ CloseHandle(hChildStderrRdDup);
+ break;
+
+ case _O_RDONLY | _O_BINARY:
+ /* Case for readinig from child Stdout in binary mode. */
+ fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
+ f1 = _fdopen(fd1, "rb");
+ f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
+ PyFile_SetBufSize(f, 0);
+ /* We don't care about these pipes anymore, so close them. */
+ CloseHandle(hChildStdinWrDup);
+ CloseHandle(hChildStderrRdDup);
+ break;
+
+ case _O_WRONLY | _O_BINARY:
+ /* Case for writing to child Stdin in binary mode. */
+ fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
+ f1 = _fdopen(fd1, "wb");
+ f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
+ PyFile_SetBufSize(f, 0);
+ /* We don't care about these pipes anymore, so close them. */
+ CloseHandle(hChildStdoutRdDup);
+ CloseHandle(hChildStderrRdDup);
+ break;
+ }
+ file_count = 1;
+ break;
+
+ case POPEN_2:
+ case POPEN_4:
+ {
+ char *m1, *m2;
+ PyObject *p1, *p2;
+
+ if (mode & _O_TEXT) {
+ m1 = "r";
+ m2 = "w";
+ } else {
+ m1 = "rb";
+ m2 = "wb";
+ }
+
+ fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
+ f1 = _fdopen(fd1, m2);
+ fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
+ f2 = _fdopen(fd2, m1);
+ p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
+ PyFile_SetBufSize(p1, 0);
+ p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
+ PyFile_SetBufSize(p2, 0);
+
+ if (n != 4)
+ CloseHandle(hChildStderrRdDup);
+
+ f = PyTuple_Pack(2,p1,p2);
+ Py_XDECREF(p1);
+ Py_XDECREF(p2);
+ file_count = 2;
+ break;
+ }
+
+ case POPEN_3:
+ {
+ char *m1, *m2;
+ PyObject *p1, *p2, *p3;
+
+ if (mode & _O_TEXT) {
+ m1 = "r";
+ m2 = "w";
+ } else {
+ m1 = "rb";
+ m2 = "wb";
+ }
+
+ fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
+ f1 = _fdopen(fd1, m2);
+ fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
+ f2 = _fdopen(fd2, m1);
+ fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
+ f3 = _fdopen(fd3, m1);
+ p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
+ p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
+ p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
+ PyFile_SetBufSize(p1, 0);
+ PyFile_SetBufSize(p2, 0);
+ PyFile_SetBufSize(p3, 0);
+ f = PyTuple_Pack(3,p1,p2,p3);
+ Py_XDECREF(p1);
+ Py_XDECREF(p2);
+ Py_XDECREF(p3);
+ file_count = 3;
+ break;
+ }
+ }
+
+ if (n == POPEN_4) {
+ if (!_PyPopenCreateProcess(cmdstring,
+ hChildStdinRd,
+ hChildStdoutWr,
+ hChildStdoutWr,
+ &hProcess))
+ return NULL;
+ }
+ else {
+ if (!_PyPopenCreateProcess(cmdstring,
+ hChildStdinRd,
+ hChildStdoutWr,
+ hChildStderrWr,
+ &hProcess))
+ return NULL;
+ }
+
+ /*
+ * Insert the files we've created into the process dictionary
+ * all referencing the list with the process handle and the
+ * initial number of files (see description below in _PyPclose).
+ * Since if _PyPclose later tried to wait on a process when all
+ * handles weren't closed, it could create a deadlock with the
+ * child, we spend some energy here to try to ensure that we
+ * either insert all file handles into the dictionary or none
+ * at all. It's a little clumsy with the various popen modes
+ * and variable number of files involved.
+ */
+ if (!_PyPopenProcs) {
+ _PyPopenProcs = PyDict_New();
+ }
+
+ if (_PyPopenProcs) {
+ PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
+ int ins_rc[3];
+
+ fileObj[0] = fileObj[1] = fileObj[2] = NULL;
+ ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
+
+ procObj = PyList_New(2);
+ hProcessObj = PyLong_FromVoidPtr(hProcess);
+ intObj = PyInt_FromLong(file_count);
+
+ if (procObj && hProcessObj && intObj) {
+ PyList_SetItem(procObj,0,hProcessObj);
+ PyList_SetItem(procObj,1,intObj);
+
+ fileObj[0] = PyLong_FromVoidPtr(f1);
+ if (fileObj[0]) {
+ ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
+ fileObj[0],
+ procObj);
+ }
+ if (file_count >= 2) {
+ fileObj[1] = PyLong_FromVoidPtr(f2);
+ if (fileObj[1]) {
+ ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
+ fileObj[1],
+ procObj);
+ }
+ }
+ if (file_count >= 3) {
+ fileObj[2] = PyLong_FromVoidPtr(f3);
+ if (fileObj[2]) {
+ ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
+ fileObj[2],
+ procObj);
+ }
+ }
+
+ if (ins_rc[0] < 0 || !fileObj[0] ||
+ ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
+ ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
+ /* Something failed - remove any dictionary
+ * entries that did make it.
+ */
+ if (!ins_rc[0] && fileObj[0]) {
+ PyDict_DelItem(_PyPopenProcs,
+ fileObj[0]);
+ }
+ if (!ins_rc[1] && fileObj[1]) {
+ PyDict_DelItem(_PyPopenProcs,
+ fileObj[1]);
+ }
+ if (!ins_rc[2] && fileObj[2]) {
+ PyDict_DelItem(_PyPopenProcs,
+ fileObj[2]);
+ }
+ }
+ }
+
+ /*
+ * Clean up our localized references for the dictionary keys
+ * and value since PyDict_SetItem will Py_INCREF any copies
+ * that got placed in the dictionary.
+ */
+ Py_XDECREF(procObj);
+ Py_XDECREF(fileObj[0]);
+ Py_XDECREF(fileObj[1]);
+ Py_XDECREF(fileObj[2]);
+ }
+
+ /* Child is launched. Close the parents copy of those pipe
+ * handles that only the child should have open. You need to
+ * make sure that no handles to the write end of the output pipe
+ * are maintained in this process or else the pipe will not close
+ * when the child process exits and the ReadFile will hang. */
+
+ if (!CloseHandle(hChildStdinRd))
+ return win32_error("CloseHandle", NULL);
+
+ if (!CloseHandle(hChildStdoutWr))
+ return win32_error("CloseHandle", NULL);
+
+ if ((n != 4) && (!CloseHandle(hChildStderrWr)))
+ return win32_error("CloseHandle", NULL);
+
+ return f;
+}
+
+/*
+ * Wrapper for fclose() to use for popen* files, so we can retrieve the
+ * exit code for the child process and return as a result of the close.
+ *
+ * This function uses the _PyPopenProcs dictionary in order to map the
+ * input file pointer to information about the process that was
+ * originally created by the popen* call that created the file pointer.
+ * The dictionary uses the file pointer as a key (with one entry
+ * inserted for each file returned by the original popen* call) and a
+ * single list object as the value for all files from a single call.
+ * The list object contains the Win32 process handle at [0], and a file
+ * count at [1], which is initialized to the total number of file
+ * handles using that list.
+ *
+ * This function closes whichever handle it is passed, and decrements
+ * the file count in the dictionary for the process handle pointed to
+ * by this file. On the last close (when the file count reaches zero),
+ * this function will wait for the child process and then return its
+ * exit code as the result of the close() operation. This permits the
+ * files to be closed in any order - it is always the close() of the
+ * final handle that will return the exit code.
+ *
+ * NOTE: This function is currently called with the GIL released.
+ * hence we use the GILState API to manage our state.
+ */
+
+static int _PyPclose(FILE *file)
+{
+ int result;
+ DWORD exit_code;
+ HANDLE hProcess;
+ PyObject *procObj, *hProcessObj, *intObj, *fileObj;
+ long file_count;
+#ifdef WITH_THREAD
+ PyGILState_STATE state;
+#endif
+
+ /* Close the file handle first, to ensure it can't block the
+ * child from exiting if it's the last handle.
+ */
+ result = fclose(file);
+#ifdef WITH_THREAD
+ state = PyGILState_Ensure();
+#endif
+ if (_PyPopenProcs) {
+ if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
+ (procObj = PyDict_GetItem(_PyPopenProcs,
+ fileObj)) != NULL &&
+ (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
+ (intObj = PyList_GetItem(procObj,1)) != NULL) {
+
+ hProcess = PyLong_AsVoidPtr(hProcessObj);
+ file_count = PyInt_AsLong(intObj);
+
+ if (file_count > 1) {
+ /* Still other files referencing process */
+ file_count--;
+ PyList_SetItem(procObj,1,
+ PyInt_FromLong(file_count));
+ } else {
+ /* Last file for this process */
+ if (result != EOF &&
+ WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
+ GetExitCodeProcess(hProcess, &exit_code)) {
+ /* Possible truncation here in 16-bit environments, but
+ * real exit codes are just the lower byte in any event.
+ */
+ result = exit_code;
+ } else {
+ /* Indicate failure - this will cause the file object
+ * to raise an I/O error and translate the last Win32
+ * error code from errno. We do have a problem with
+ * last errors that overlap the normal errno table,
+ * but that's a consistent problem with the file object.
+ */
+ if (result != EOF) {
+ /* If the error wasn't from the fclose(), then
+ * set errno for the file object error handling.
+ */
+ errno = GetLastError();
+ }
+ result = -1;
+ }
+
+ /* Free up the native handle at this point */
+ CloseHandle(hProcess);
+ }
+
+ /* Remove this file pointer from dictionary */
+ PyDict_DelItem(_PyPopenProcs, fileObj);
+
+ if (PyDict_Size(_PyPopenProcs) == 0) {
+ Py_DECREF(_PyPopenProcs);
+ _PyPopenProcs = NULL;
+ }
+
+ } /* if object retrieval ok */
+
+ Py_XDECREF(fileObj);
+ } /* if _PyPopenProcs */
+
+#ifdef WITH_THREAD
+ PyGILState_Release(state);
+#endif
+ return result;
+}
+
+#else /* which OS? */
+static PyObject *
+posix_popen(PyObject *self, PyObject *args)
+{
+ char *name;
+ char *mode = "r";
+ int bufsize = -1;
+ FILE *fp;
+ PyObject *f;
+ if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
+ return NULL;
+ /* Strip mode of binary or text modifiers */
+ if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
+ mode = "r";
+ else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
+ mode = "w";
+ Py_BEGIN_ALLOW_THREADS
+ fp = popen(name, mode);
+ Py_END_ALLOW_THREADS
+ if (fp == NULL)
+ return posix_error();
+ f = PyFile_FromFile(fp, name, mode, pclose);
+ if (f != NULL)
+ PyFile_SetBufSize(f, bufsize);
+ return f;
+}
+
+#endif /* PYOS_??? */
+#endif /* HAVE_POPEN */
+
+
+#ifdef HAVE_SETUID
+PyDoc_STRVAR(posix_setuid__doc__,
+"setuid(uid)\n\n\
+Set the current process's user id.");
+
+static PyObject *
+posix_setuid(PyObject *self, PyObject *args)
+{
+ long uid_arg;
+ uid_t uid;
+ if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))
+ return NULL;
+ uid = uid_arg;
+ if (uid != uid_arg) {
+ PyErr_SetString(PyExc_OverflowError, "user id too big");
+ return NULL;
+ }
+ if (setuid(uid) < 0)
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif /* HAVE_SETUID */
+
+
+#ifdef HAVE_SETEUID
+PyDoc_STRVAR(posix_seteuid__doc__,
+"seteuid(uid)\n\n\
+Set the current process's effective user id.");
+
+static PyObject *
+posix_seteuid (PyObject *self, PyObject *args)
+{
+ long euid_arg;
+ uid_t euid;
+ if (!PyArg_ParseTuple(args, "l", &euid_arg))
+ return NULL;
+ euid = euid_arg;
+ if (euid != euid_arg) {
+ PyErr_SetString(PyExc_OverflowError, "user id too big");
+ return NULL;
+ }
+ if (seteuid(euid) < 0) {
+ return posix_error();
+ } else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+}
+#endif /* HAVE_SETEUID */
+
+#ifdef HAVE_SETEGID
+PyDoc_STRVAR(posix_setegid__doc__,
+"setegid(gid)\n\n\
+Set the current process's effective group id.");
+
+static PyObject *
+posix_setegid (PyObject *self, PyObject *args)
+{
+ long egid_arg;
+ gid_t egid;
+ if (!PyArg_ParseTuple(args, "l", &egid_arg))
+ return NULL;
+ egid = egid_arg;
+ if (egid != egid_arg) {
+ PyErr_SetString(PyExc_OverflowError, "group id too big");
+ return NULL;
+ }
+ if (setegid(egid) < 0) {
+ return posix_error();
+ } else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+}
+#endif /* HAVE_SETEGID */
+
+#ifdef HAVE_SETREUID
+PyDoc_STRVAR(posix_setreuid__doc__,
+"setreuid(ruid, euid)\n\n\
+Set the current process's real and effective user ids.");
+
+static PyObject *
+posix_setreuid (PyObject *self, PyObject *args)
+{
+ long ruid_arg, euid_arg;
+ uid_t ruid, euid;
+ if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))
+ return NULL;
+ if (ruid_arg == -1)
+ ruid = (uid_t)-1; /* let the compiler choose how -1 fits */
+ else
+ ruid = ruid_arg; /* otherwise, assign from our long */
+ if (euid_arg == -1)
+ euid = (uid_t)-1;
+ else
+ euid = euid_arg;
+ if ((euid_arg != -1 && euid != euid_arg) ||
+ (ruid_arg != -1 && ruid != ruid_arg)) {
+ PyErr_SetString(PyExc_OverflowError, "user id too big");
+ return NULL;
+ }
+ if (setreuid(ruid, euid) < 0) {
+ return posix_error();
+ } else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+}
+#endif /* HAVE_SETREUID */
+
+#ifdef HAVE_SETREGID
+PyDoc_STRVAR(posix_setregid__doc__,
+"setregid(rgid, egid)\n\n\
+Set the current process's real and effective group ids.");
+
+static PyObject *
+posix_setregid (PyObject *self, PyObject *args)
+{
+ long rgid_arg, egid_arg;
+ gid_t rgid, egid;
+ if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))
+ return NULL;
+ if (rgid_arg == -1)
+ rgid = (gid_t)-1; /* let the compiler choose how -1 fits */
+ else
+ rgid = rgid_arg; /* otherwise, assign from our long */
+ if (egid_arg == -1)
+ egid = (gid_t)-1;
+ else
+ egid = egid_arg;
+ if ((egid_arg != -1 && egid != egid_arg) ||
+ (rgid_arg != -1 && rgid != rgid_arg)) {
+ PyErr_SetString(PyExc_OverflowError, "group id too big");
+ return NULL;
+ }
+ if (setregid(rgid, egid) < 0) {
+ return posix_error();
+ } else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+}
+#endif /* HAVE_SETREGID */
+
+#ifdef HAVE_SETGID
+PyDoc_STRVAR(posix_setgid__doc__,
+"setgid(gid)\n\n\
+Set the current process's group id.");
+
+static PyObject *
+posix_setgid(PyObject *self, PyObject *args)
+{
+ long gid_arg;
+ gid_t gid;
+ if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))
+ return NULL;
+ gid = gid_arg;
+ if (gid != gid_arg) {
+ PyErr_SetString(PyExc_OverflowError, "group id too big");
+ return NULL;
+ }
+ if (setgid(gid) < 0)
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif /* HAVE_SETGID */
+
+#ifdef HAVE_SETGROUPS
+PyDoc_STRVAR(posix_setgroups__doc__,
+"setgroups(list)\n\n\
+Set the groups of the current process to list.");
+
+static PyObject *
+posix_setgroups(PyObject *self, PyObject *groups)
+{
+ int i, len;
+ gid_t grouplist[MAX_GROUPS];
+
+ if (!PySequence_Check(groups)) {
+ PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
+ return NULL;
+ }
+ len = PySequence_Size(groups);
+ if (len > MAX_GROUPS) {
+ PyErr_SetString(PyExc_ValueError, "too many groups");
+ return NULL;
+ }
+ for(i = 0; i < len; i++) {
+ PyObject *elem;
+ elem = PySequence_GetItem(groups, i);
+ if (!elem)
+ return NULL;
+ if (!PyInt_Check(elem)) {
+ if (!PyLong_Check(elem)) {
+ PyErr_SetString(PyExc_TypeError,
+ "groups must be integers");
+ Py_DECREF(elem);
+ return NULL;
+ } else {
+ unsigned long x = PyLong_AsUnsignedLong(elem);
+ if (PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError,
+ "group id too big");
+ Py_DECREF(elem);
+ return NULL;
+ }
+ grouplist[i] = x;
+ /* read back to see if it fits in gid_t */
+ if (grouplist[i] != x) {
+ PyErr_SetString(PyExc_TypeError,
+ "group id too big");
+ Py_DECREF(elem);
+ return NULL;
+ }
+ }
+ } else {
+ long x = PyInt_AsLong(elem);
+ grouplist[i] = x;
+ if (grouplist[i] != x) {
+ PyErr_SetString(PyExc_TypeError,
+ "group id too big");
+ Py_DECREF(elem);
+ return NULL;
+ }
+ }
+ Py_DECREF(elem);
+ }
+
+ if (setgroups(len, grouplist) < 0)
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif /* HAVE_SETGROUPS */
+
+#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
+static PyObject *
+wait_helper(pid_t pid, int status, struct rusage *ru)
+{
+ PyObject *result;
+ static PyObject *struct_rusage;
+
+ if (pid == -1)
+ return posix_error();
+
+ if (struct_rusage == NULL) {
+ PyObject *m = PyImport_ImportModuleNoBlock("resource");
+ if (m == NULL)
+ return NULL;
+ struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
+ Py_DECREF(m);
+ if (struct_rusage == NULL)
+ return NULL;
+ }
+
+ /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
+ result = PyStructSequence_New((PyTypeObject*) struct_rusage);
+ if (!result)
+ return NULL;
+
+#ifndef doubletime
+#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
+#endif
+
+ PyStructSequence_SET_ITEM(result, 0,
+ PyFloat_FromDouble(doubletime(ru->ru_utime)));
+ PyStructSequence_SET_ITEM(result, 1,
+ PyFloat_FromDouble(doubletime(ru->ru_stime)));
+#define SET_INT(result, index, value)\
+ PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
+ SET_INT(result, 2, ru->ru_maxrss);
+ SET_INT(result, 3, ru->ru_ixrss);
+ SET_INT(result, 4, ru->ru_idrss);
+ SET_INT(result, 5, ru->ru_isrss);
+ SET_INT(result, 6, ru->ru_minflt);
+ SET_INT(result, 7, ru->ru_majflt);
+ SET_INT(result, 8, ru->ru_nswap);
+ SET_INT(result, 9, ru->ru_inblock);
+ SET_INT(result, 10, ru->ru_oublock);
+ SET_INT(result, 11, ru->ru_msgsnd);
+ SET_INT(result, 12, ru->ru_msgrcv);
+ SET_INT(result, 13, ru->ru_nsignals);
+ SET_INT(result, 14, ru->ru_nvcsw);
+ SET_INT(result, 15, ru->ru_nivcsw);
+#undef SET_INT
+
+ if (PyErr_Occurred()) {
+ Py_DECREF(result);
+ return NULL;
+ }
+
+ return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
+}
+#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
+
+#ifdef HAVE_WAIT3
+PyDoc_STRVAR(posix_wait3__doc__,
+"wait3(options) -> (pid, status, rusage)\n\n\
+Wait for completion of a child process.");
+
+static PyObject *
+posix_wait3(PyObject *self, PyObject *args)
+{
+ pid_t pid;
+ int options;
+ struct rusage ru;
+ WAIT_TYPE status;
+ WAIT_STATUS_INT(status) = 0;
+
+ if (!PyArg_ParseTuple(args, "i:wait3", &options))
+ return NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+ pid = wait3(&status, options, &ru);
+ Py_END_ALLOW_THREADS
+
+ return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
+}
+#endif /* HAVE_WAIT3 */
+
+#ifdef HAVE_WAIT4
+PyDoc_STRVAR(posix_wait4__doc__,
+"wait4(pid, options) -> (pid, status, rusage)\n\n\
+Wait for completion of a given child process.");
+
+static PyObject *
+posix_wait4(PyObject *self, PyObject *args)
+{
+ pid_t pid;
+ int options;
+ struct rusage ru;
+ WAIT_TYPE status;
+ WAIT_STATUS_INT(status) = 0;
+
+ if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))
+ return NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+ pid = wait4(pid, &status, options, &ru);
+ Py_END_ALLOW_THREADS
+
+ return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
+}
+#endif /* HAVE_WAIT4 */
+
+#ifdef HAVE_WAITPID
+PyDoc_STRVAR(posix_waitpid__doc__,
+"waitpid(pid, options) -> (pid, status)\n\n\
+Wait for completion of a given child process.");
+
+static PyObject *
+posix_waitpid(PyObject *self, PyObject *args)
+{
+ pid_t pid;
+ int options;
+ WAIT_TYPE status;
+ WAIT_STATUS_INT(status) = 0;
+
+ if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ pid = waitpid(pid, &status, options);
+ Py_END_ALLOW_THREADS
+ if (pid == -1)
+ return posix_error();
+
+ return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
+}
+
+#elif defined(HAVE_CWAIT)
+
+/* MS C has a variant of waitpid() that's usable for most purposes. */
+PyDoc_STRVAR(posix_waitpid__doc__,
+"waitpid(pid, options) -> (pid, status << 8)\n\n"
+"Wait for completion of a given process. options is ignored on Windows.");
+
+static PyObject *
+posix_waitpid(PyObject *self, PyObject *args)
+{
+ Py_intptr_t pid;
+ int status, options;
+
+ if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ pid = _cwait(&status, pid, options);
+ Py_END_ALLOW_THREADS
+ if (pid == -1)
+ return posix_error();
+
+ /* shift the status left a byte so this is more like the POSIX waitpid */
+ return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
+}
+#endif /* HAVE_WAITPID || HAVE_CWAIT */
+
+#ifdef HAVE_WAIT
+PyDoc_STRVAR(posix_wait__doc__,
+"wait() -> (pid, status)\n\n\
+Wait for completion of a child process.");
+
+static PyObject *
+posix_wait(PyObject *self, PyObject *noargs)
+{
+ pid_t pid;
+ WAIT_TYPE status;
+ WAIT_STATUS_INT(status) = 0;
+
+ Py_BEGIN_ALLOW_THREADS
+ pid = wait(&status);
+ Py_END_ALLOW_THREADS
+ if (pid == -1)
+ return posix_error();
+
+ return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
+}
+#endif
+
+
+PyDoc_STRVAR(posix_lstat__doc__,
+"lstat(path) -> stat result\n\n\
+Like stat(path), but do not follow symbolic links.");
+
+static PyObject *
+posix_lstat(PyObject *self, PyObject *args)
+{
+#ifdef HAVE_LSTAT
+ return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
+#else /* !HAVE_LSTAT */
+ return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
+#endif /* !HAVE_LSTAT */
+}
+
+
+#ifdef HAVE_READLINK
+PyDoc_STRVAR(posix_readlink__doc__,
+"readlink(path) -> path\n\n\
+Return a string representing the path to which the symbolic link points.");
+
+static PyObject *
+posix_readlink(PyObject *self, PyObject *args)
+{
+ PyObject* v;
+ char buf[MAXPATHLEN];
+ char *path;
+ int n;
+#ifdef Py_USING_UNICODE
+ int arg_is_unicode = 0;
+#endif
+
+ if (!PyArg_ParseTuple(args, "et:readlink",
+ Py_FileSystemDefaultEncoding, &path))
+ return NULL;
+#ifdef Py_USING_UNICODE
+ v = PySequence_GetItem(args, 0);
+ if (v == NULL) {
+ PyMem_Free(path);
+ return NULL;
+ }
+
+ if (PyUnicode_Check(v)) {
+ arg_is_unicode = 1;
+ }
+ Py_DECREF(v);
+#endif
+
+ Py_BEGIN_ALLOW_THREADS
+ n = readlink(path, buf, (int) sizeof buf);
+ Py_END_ALLOW_THREADS
+ if (n < 0)
+ return posix_error_with_allocated_filename(path);
+
+ PyMem_Free(path);
+ v = PyString_FromStringAndSize(buf, n);
+#ifdef Py_USING_UNICODE
+ if (arg_is_unicode) {
+ PyObject *w;
+
+ w = PyUnicode_FromEncodedObject(v,
+ Py_FileSystemDefaultEncoding,
+ "strict");
+ if (w != NULL) {
+ Py_DECREF(v);
+ v = w;
+ }
+ else {
+ /* fall back to the original byte string, as
+ discussed in patch #683592 */
+ PyErr_Clear();
+ }
+ }
+#endif
+ return v;
+}
+#endif /* HAVE_READLINK */
+
+
+#ifdef HAVE_SYMLINK
+PyDoc_STRVAR(posix_symlink__doc__,
+"symlink(src, dst)\n\n\
+Create a symbolic link pointing to src named dst.");
+
+static PyObject *
+posix_symlink(PyObject *self, PyObject *args)
+{
+ return posix_2str(args, "etet:symlink", symlink);
+}
+#endif /* HAVE_SYMLINK */
+
+
+#ifdef HAVE_TIMES
+#if defined(PYCC_VACPP) && defined(PYOS_OS2)
+static long
+system_uptime(void)
+{
+ ULONG value = 0;
+
+ Py_BEGIN_ALLOW_THREADS
+ DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
+ Py_END_ALLOW_THREADS
+
+ return value;
+}
+
+static PyObject *
+posix_times(PyObject *self, PyObject *noargs)
+{
+ /* Currently Only Uptime is Provided -- Others Later */
+ return Py_BuildValue("ddddd",
+ (double)0 /* t.tms_utime / HZ */,
+ (double)0 /* t.tms_stime / HZ */,
+ (double)0 /* t.tms_cutime / HZ */,
+ (double)0 /* t.tms_cstime / HZ */,
+ (double)system_uptime() / 1000);
+}
+#else /* not OS2 */
+#define NEED_TICKS_PER_SECOND
+static long ticks_per_second = -1;
+static PyObject *
+posix_times(PyObject *self, PyObject *noargs)
+{
+ struct tms t;
+ clock_t c;
+ errno = 0;
+ c = times(&t);
+ if (c == (clock_t) -1)
+ return posix_error();
+ return Py_BuildValue("ddddd",
+ (double)t.tms_utime / ticks_per_second,
+ (double)t.tms_stime / ticks_per_second,
+ (double)t.tms_cutime / ticks_per_second,
+ (double)t.tms_cstime / ticks_per_second,
+ (double)c / ticks_per_second);
+}
+#endif /* not OS2 */
+#endif /* HAVE_TIMES */
+
+
+#ifdef HAVE_TIMES
+PyDoc_STRVAR(posix_times__doc__,
+"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
+Return a tuple of floating point numbers indicating process times.");
+#endif
+
+
+#ifdef HAVE_GETSID
+PyDoc_STRVAR(posix_getsid__doc__,
+"getsid(pid) -> sid\n\n\
+Call the system call getsid().");
+
+static PyObject *
+posix_getsid(PyObject *self, PyObject *args)
+{
+ pid_t pid;
+ int sid;
+ if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))
+ return NULL;
+ sid = getsid(pid);
+ if (sid < 0)
+ return posix_error();
+ return PyInt_FromLong((long)sid);
+}
+#endif /* HAVE_GETSID */
+
+
+#ifdef HAVE_SETSID
+PyDoc_STRVAR(posix_setsid__doc__,
+"setsid()\n\n\
+Call the system call setsid().");
+
+static PyObject *
+posix_setsid(PyObject *self, PyObject *noargs)
+{
+ if (setsid() < 0)
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif /* HAVE_SETSID */
+
+#ifdef HAVE_SETPGID
+PyDoc_STRVAR(posix_setpgid__doc__,
+"setpgid(pid, pgrp)\n\n\
+Call the system call setpgid().");
+
+static PyObject *
+posix_setpgid(PyObject *self, PyObject *args)
+{
+ pid_t pid;
+ int pgrp;
+ if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))
+ return NULL;
+ if (setpgid(pid, pgrp) < 0)
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif /* HAVE_SETPGID */
+
+
+#ifdef HAVE_TCGETPGRP
+PyDoc_STRVAR(posix_tcgetpgrp__doc__,
+"tcgetpgrp(fd) -> pgid\n\n\
+Return the process group associated with the terminal given by a fd.");
+
+static PyObject *
+posix_tcgetpgrp(PyObject *self, PyObject *args)
+{
+ int fd;
+ pid_t pgid;
+ if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
+ return NULL;
+ pgid = tcgetpgrp(fd);
+ if (pgid < 0)
+ return posix_error();
+ return PyLong_FromPid(pgid);
+}
+#endif /* HAVE_TCGETPGRP */
+
+
+#ifdef HAVE_TCSETPGRP
+PyDoc_STRVAR(posix_tcsetpgrp__doc__,
+"tcsetpgrp(fd, pgid)\n\n\
+Set the process group associated with the terminal given by a fd.");
+
+static PyObject *
+posix_tcsetpgrp(PyObject *self, PyObject *args)
+{
+ int fd;
+ pid_t pgid;
+ if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))
+ return NULL;
+ if (tcsetpgrp(fd, pgid) < 0)
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif /* HAVE_TCSETPGRP */
+
+/* Functions acting on file descriptors */
+
+PyDoc_STRVAR(posix_open__doc__,
+"open(filename, flag [, mode=0777]) -> fd\n\n\
+Open a file (for low level IO).");
+
+static PyObject *
+posix_open(PyObject *self, PyObject *args)
+{
+ char *file = NULL;
+ int flag;
+ int mode = 0777;
+ int fd;
+
+ if (!PyArg_ParseTuple(args, "eti|i",
+ Py_FileSystemDefaultEncoding, &file,
+ &flag, &mode))
+ return NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+ fd = open(file, flag, mode);
+ Py_END_ALLOW_THREADS
+ if (fd < 0)
+ return posix_error_with_allocated_filename(file);
+ PyMem_Free(file);
+ return PyInt_FromLong((long)fd);
+}
+
+
+PyDoc_STRVAR(posix_close__doc__,
+"close(fd)\n\n\
+Close a file descriptor (for low level IO).");
+
+static PyObject *
+posix_close(PyObject *self, PyObject *args)
+{
+ int fd, res;
+ if (!PyArg_ParseTuple(args, "i:close", &fd))
+ return NULL;
+ if (!_PyVerify_fd(fd))
+ return posix_error();
+ Py_BEGIN_ALLOW_THREADS
+ res = close(fd);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+PyDoc_STRVAR(posix_closerange__doc__,
+"closerange(fd_low, fd_high)\n\n\
+Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
+
+static PyObject *
+posix_closerange(PyObject *self, PyObject *args)
+{
+ int fd_from, fd_to, i;
+ if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ for (i = fd_from; i < fd_to; i++)
+ if (_PyVerify_fd(i))
+ close(i);
+ Py_END_ALLOW_THREADS
+ Py_RETURN_NONE;
+}
+
+
+PyDoc_STRVAR(posix_dup__doc__,
+"dup(fd) -> fd2\n\n\
+Return a duplicate of a file descriptor.");
+
+static PyObject *
+posix_dup(PyObject *self, PyObject *args)
+{
+ int fd;
+ if (!PyArg_ParseTuple(args, "i:dup", &fd))
+ return NULL;
+ if (!_PyVerify_fd(fd))
+ return posix_error();
+ Py_BEGIN_ALLOW_THREADS
+ fd = dup(fd);
+ Py_END_ALLOW_THREADS
+ if (fd < 0)
+ return posix_error();
+ return PyInt_FromLong((long)fd);
+}
+
+
+PyDoc_STRVAR(posix_dup2__doc__,
+"dup2(old_fd, new_fd)\n\n\
+Duplicate file descriptor.");
+
+static PyObject *
+posix_dup2(PyObject *self, PyObject *args)
+{
+ int fd, fd2, res;
+ if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
+ return NULL;
+ if (!_PyVerify_fd_dup2(fd, fd2))
+ return posix_error();
+ Py_BEGIN_ALLOW_THREADS
+ res = dup2(fd, fd2);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+PyDoc_STRVAR(posix_lseek__doc__,
+"lseek(fd, pos, how) -> newpos\n\n\
+Set the current position of a file descriptor.");
+
+static PyObject *
+posix_lseek(PyObject *self, PyObject *args)
+{
+ int fd, how;
+ off_t pos, res;
+ PyObject *posobj;
+ if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
+ return NULL;
+#ifdef SEEK_SET
+ /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
+ switch (how) {
+ case 0: how = SEEK_SET; break;
+ case 1: how = SEEK_CUR; break;
+ case 2: how = SEEK_END; break;
+ }
+#endif /* SEEK_END */
+
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+ pos = PyInt_AsLong(posobj);
+#else
+ pos = PyLong_Check(posobj) ?
+ PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
+#endif
+ if (PyErr_Occurred())
+ return NULL;
+
+ if (!_PyVerify_fd(fd))
+ return posix_error();
+ Py_BEGIN_ALLOW_THREADS
+ res = lseek(fd, pos, how);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return posix_error();
+
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+ return PyInt_FromLong(res);
+#else
+ return PyLong_FromLongLong(res);
+#endif
+}
+
+
+PyDoc_STRVAR(posix_read__doc__,
+"read(fd, buffersize) -> string\n\n\
+Read a file descriptor.");
+
+static PyObject *
+posix_read(PyObject *self, PyObject *args)
+{
+ int fd, size, n;
+ PyObject *buffer;
+ if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
+ return NULL;
+ if (size < 0) {
+ errno = EINVAL;
+ return posix_error();
+ }
+ buffer = PyString_FromStringAndSize((char *)NULL, size);
+ if (buffer == NULL)
+ return NULL;
+ if (!_PyVerify_fd(fd)) {
+ Py_DECREF(buffer);
+ return posix_error();
+ }
+ Py_BEGIN_ALLOW_THREADS
+ n = read(fd, PyString_AsString(buffer), size);
+ Py_END_ALLOW_THREADS
+ if (n < 0) {
+ Py_DECREF(buffer);
+ return posix_error();
+ }
+ if (n != size)
+ _PyString_Resize(&buffer, n);
+ return buffer;
+}
+
+
+PyDoc_STRVAR(posix_write__doc__,
+"write(fd, string) -> byteswritten\n\n\
+Write a string to a file descriptor.");
+
+static PyObject *
+posix_write(PyObject *self, PyObject *args)
+{
+ Py_buffer pbuf;
+ int fd;
+ Py_ssize_t size;
+
+ if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
+ return NULL;
+ if (!_PyVerify_fd(fd)) {
+ PyBuffer_Release(&pbuf);
+ return posix_error();
+ }
+ Py_BEGIN_ALLOW_THREADS
+ size = write(fd, pbuf.buf, (size_t)pbuf.len);
+ Py_END_ALLOW_THREADS
+ PyBuffer_Release(&pbuf);
+ if (size < 0)
+ return posix_error();
+ return PyInt_FromSsize_t(size);
+}
+
+
+PyDoc_STRVAR(posix_fstat__doc__,
+"fstat(fd) -> stat result\n\n\
+Like stat(), but for an open file descriptor.");
+
+static PyObject *
+posix_fstat(PyObject *self, PyObject *args)
+{
+ int fd;
+ STRUCT_STAT st;
+ int res;
+ if (!PyArg_ParseTuple(args, "i:fstat", &fd))
+ return NULL;
+ if (!_PyVerify_fd(fd))
+ return posix_error();
+ Py_BEGIN_ALLOW_THREADS
+ res = FSTAT(fd, &st);
+ Py_END_ALLOW_THREADS
+ if (res != 0) {
+ return posix_error();
+ }
+
+ return _pystat_fromstructstat(&st);
+}
+
+
+PyDoc_STRVAR(posix_fdopen__doc__,
+"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
+Return an open file object connected to a file descriptor.");
+
+static PyObject *
+posix_fdopen(PyObject *self, PyObject *args)
+{
+ int fd;
+ char *orgmode = "r";
+ int bufsize = -1;
+ FILE *fp;
+ PyObject *f;
+ char *mode;
+ if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
+ return NULL;
+
+ /* Sanitize mode. See fileobject.c */
+ mode = PyMem_MALLOC(strlen(orgmode)+3);
+ if (!mode) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ strcpy(mode, orgmode);
+ if (_PyFile_SanitizeMode(mode)) {
+ PyMem_FREE(mode);
+ return NULL;
+ }
+ if (!_PyVerify_fd(fd))
+ return posix_error();
+ Py_BEGIN_ALLOW_THREADS
+#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
+ if (mode[0] == 'a') {
+ /* try to make sure the O_APPEND flag is set */
+ int flags;
+ flags = fcntl(fd, F_GETFL);
+ if (flags != -1)
+ fcntl(fd, F_SETFL, flags | O_APPEND);
+ fp = fdopen(fd, mode);
+ if (fp == NULL && flags != -1)
+ /* restore old mode if fdopen failed */
+ fcntl(fd, F_SETFL, flags);
+ } else {
+ fp = fdopen(fd, mode);
+ }
+#else
+ fp = fdopen(fd, mode);
+#endif
+ Py_END_ALLOW_THREADS
+ PyMem_FREE(mode);
+ if (fp == NULL)
+ return posix_error();
+ f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
+ if (f != NULL)
+ PyFile_SetBufSize(f, bufsize);
+ return f;
+}
+
+PyDoc_STRVAR(posix_isatty__doc__,
+"isatty(fd) -> bool\n\n\
+Return True if the file descriptor 'fd' is an open file descriptor\n\
+connected to the slave end of a terminal.");
+
+static PyObject *
+posix_isatty(PyObject *self, PyObject *args)
+{
+ int fd;
+ if (!PyArg_ParseTuple(args, "i:isatty", &fd))
+ return NULL;
+ if (!_PyVerify_fd(fd))
+ return PyBool_FromLong(0);
+ return PyBool_FromLong(isatty(fd));
+}
+
+#ifdef HAVE_PIPE
+PyDoc_STRVAR(posix_pipe__doc__,
+"pipe() -> (read_end, write_end)\n\n\
+Create a pipe.");
+
+static PyObject *
+posix_pipe(PyObject *self, PyObject *noargs)
+{
+#if defined(PYOS_OS2)
+ HFILE read, write;
+ APIRET rc;
+
+ Py_BEGIN_ALLOW_THREADS
+ rc = DosCreatePipe( &read, &write, 4096);
+ Py_END_ALLOW_THREADS
+ if (rc != NO_ERROR)
+ return os2_error(rc);
+
+ return Py_BuildValue("(ii)", read, write);
+#else
+#if !defined(MS_WINDOWS)
+ int fds[2];
+ int res;
+ Py_BEGIN_ALLOW_THREADS
+ res = pipe(fds);
+ Py_END_ALLOW_THREADS
+ if (res != 0)
+ return posix_error();
+ return Py_BuildValue("(ii)", fds[0], fds[1]);
+#else /* MS_WINDOWS */
+ HANDLE read, write;
+ int read_fd, write_fd;
+ BOOL ok;
+ Py_BEGIN_ALLOW_THREADS
+ ok = CreatePipe(&read, &write, NULL, 0);
+ Py_END_ALLOW_THREADS
+ if (!ok)
+ return win32_error("CreatePipe", NULL);
+ read_fd = _open_osfhandle((Py_intptr_t)read, 0);
+ write_fd = _open_osfhandle((Py_intptr_t)write, 1);
+ return Py_BuildValue("(ii)", read_fd, write_fd);
+#endif /* MS_WINDOWS */
+#endif
+}
+#endif /* HAVE_PIPE */
+
+
+#ifdef HAVE_MKFIFO
+PyDoc_STRVAR(posix_mkfifo__doc__,
+"mkfifo(filename [, mode=0666])\n\n\
+Create a FIFO (a POSIX named pipe).");
+
+static PyObject *
+posix_mkfifo(PyObject *self, PyObject *args)
+{
+ char *filename;
+ int mode = 0666;
+ int res;
+ if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = mkfifo(filename, mode);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif
+
+
+#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
+PyDoc_STRVAR(posix_mknod__doc__,
+"mknod(filename [, mode=0600, device])\n\n\
+Create a filesystem node (file, device special file or named pipe)\n\
+named filename. mode specifies both the permissions to use and the\n\
+type of node to be created, being combined (bitwise OR) with one of\n\
+S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
+device defines the newly created device special file (probably using\n\
+os.makedev()), otherwise it is ignored.");
+
+
+static PyObject *
+posix_mknod(PyObject *self, PyObject *args)
+{
+ char *filename;
+ int mode = 0600;
+ int device = 0;
+ int res;
+ if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = mknod(filename, mode, device);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif
+
+#ifdef HAVE_DEVICE_MACROS
+PyDoc_STRVAR(posix_major__doc__,
+"major(device) -> major number\n\
+Extracts a device major number from a raw device number.");
+
+static PyObject *
+posix_major(PyObject *self, PyObject *args)
+{
+ int device;
+ if (!PyArg_ParseTuple(args, "i:major", &device))
+ return NULL;
+ return PyInt_FromLong((long)major(device));
+}
+
+PyDoc_STRVAR(posix_minor__doc__,
+"minor(device) -> minor number\n\
+Extracts a device minor number from a raw device number.");
+
+static PyObject *
+posix_minor(PyObject *self, PyObject *args)
+{
+ int device;
+ if (!PyArg_ParseTuple(args, "i:minor", &device))
+ return NULL;
+ return PyInt_FromLong((long)minor(device));
+}
+
+PyDoc_STRVAR(posix_makedev__doc__,
+"makedev(major, minor) -> device number\n\
+Composes a raw device number from the major and minor device numbers.");
+
+static PyObject *
+posix_makedev(PyObject *self, PyObject *args)
+{
+ int major, minor;
+ if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
+ return NULL;
+ return PyInt_FromLong((long)makedev(major, minor));
+}
+#endif /* device macros */
+
+
+#ifdef HAVE_FTRUNCATE
+PyDoc_STRVAR(posix_ftruncate__doc__,
+"ftruncate(fd, length)\n\n\
+Truncate a file to a specified length.");
+
+static PyObject *
+posix_ftruncate(PyObject *self, PyObject *args)
+{
+ int fd;
+ off_t length;
+ int res;
+ PyObject *lenobj;
+
+ if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
+ return NULL;
+
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+ length = PyInt_AsLong(lenobj);
+#else
+ length = PyLong_Check(lenobj) ?
+ PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
+#endif
+ if (PyErr_Occurred())
+ return NULL;
+
+ Py_BEGIN_ALLOW_THREADS
+ res = ftruncate(fd, length);
+ Py_END_ALLOW_THREADS
+ if (res < 0)
+ return posix_error();
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif
+
+#ifdef HAVE_PUTENV
+PyDoc_STRVAR(posix_putenv__doc__,
+"putenv(key, value)\n\n\
+Change or add an environment variable.");
+
+/* Save putenv() parameters as values here, so we can collect them when they
+ * get re-set with another call for the same key. */
+static PyObject *posix_putenv_garbage;
+
+static PyObject *
+posix_putenv(PyObject *self, PyObject *args)
+{
+ char *s1, *s2;
+ char *newenv;
+ PyObject *newstr;
+ size_t len;
+
+ if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
+ return NULL;
+
+#if defined(PYOS_OS2)
+ if (stricmp(s1, "BEGINLIBPATH") == 0) {
+ APIRET rc;
+
+ rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
+ if (rc != NO_ERROR)
+ return os2_error(rc);
+
+ } else if (stricmp(s1, "ENDLIBPATH") == 0) {
+ APIRET rc;
+
+ rc = DosSetExtLIBPATH(s2, END_LIBPATH);
+ if (rc != NO_ERROR)
+ return os2_error(rc);
+ } else {
+#endif
+
+ /* XXX This can leak memory -- not easy to fix :-( */
+ len = strlen(s1) + strlen(s2) + 2;
+ /* len includes space for a trailing \0; the size arg to
+ PyString_FromStringAndSize does not count that */
+ newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
+ if (newstr == NULL)
+ return PyErr_NoMemory();
+ newenv = PyString_AS_STRING(newstr);
+ PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
+ if (putenv(newenv)) {
+ Py_DECREF(newstr);
+ posix_error();
+ return NULL;
+ }
+ /* Install the first arg and newstr in posix_putenv_garbage;
+ * this will cause previous value to be collected. This has to
+ * happen after the real putenv() call because the old value
+ * was still accessible until then. */
+ if (PyDict_SetItem(posix_putenv_garbage,
+ PyTuple_GET_ITEM(args, 0), newstr)) {
+ /* really not much we can do; just leak */
+ PyErr_Clear();
+ }
+ else {
+ Py_DECREF(newstr);
+ }
+
+#if defined(PYOS_OS2)
+ }
+#endif
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif /* putenv */
+
+#ifdef HAVE_UNSETENV
+PyDoc_STRVAR(posix_unsetenv__doc__,
+"unsetenv(key)\n\n\
+Delete an environment variable.");
+
+static PyObject *
+posix_unsetenv(PyObject *self, PyObject *args)
+{
+ char *s1;
+
+ if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
+ return NULL;
+
+ unsetenv(s1);
+
+ /* Remove the key from posix_putenv_garbage;
+ * this will cause it to be collected. This has to
+ * happen after the real unsetenv() call because the
+ * old value was still accessible until then.
+ */
+ if (PyDict_DelItem(posix_putenv_garbage,
+ PyTuple_GET_ITEM(args, 0))) {
+ /* really not much we can do; just leak */
+ PyErr_Clear();
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif /* unsetenv */
+
+PyDoc_STRVAR(posix_strerror__doc__,
+"strerror(code) -> string\n\n\
+Translate an error code to a message string.");
+
+static PyObject *
+posix_strerror(PyObject *self, PyObject *args)
+{
+ int code;
+ char *message;
+ if (!PyArg_ParseTuple(args, "i:strerror", &code))
+ return NULL;
+ message = strerror(code);
+ if (message == NULL) {
+ PyErr_SetString(PyExc_ValueError,
+ "strerror() argument out of range");
+ return NULL;
+ }
+ return PyString_FromString(message);
+}
+
+
+#ifdef HAVE_SYS_WAIT_H
+
+#ifdef WCOREDUMP
+PyDoc_STRVAR(posix_WCOREDUMP__doc__,
+"WCOREDUMP(status) -> bool\n\n\
+Return True if the process returning 'status' was dumped to a core file.");
+
+static PyObject *
+posix_WCOREDUMP(PyObject *self, PyObject *args)
+{
+ WAIT_TYPE status;
+ WAIT_STATUS_INT(status) = 0;
+
+ if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
+ return NULL;
+
+ return PyBool_FromLong(WCOREDUMP(status));
+}
+#endif /* WCOREDUMP */
+
+#ifdef WIFCONTINUED
+PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
+"WIFCONTINUED(status) -> bool\n\n\
+Return True if the process returning 'status' was continued from a\n\
+job control stop.");
+
+static PyObject *
+posix_WIFCONTINUED(PyObject *self, PyObject *args)
+{
+ WAIT_TYPE status;
+ WAIT_STATUS_INT(status) = 0;
+
+ if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
+ return NULL;
+
+ return PyBool_FromLong(WIFCONTINUED(status));
+}
+#endif /* WIFCONTINUED */
+
+#ifdef WIFSTOPPED
+PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
+"WIFSTOPPED(status) -> bool\n\n\
+Return True if the process returning 'status' was stopped.");
+
+static PyObject *
+posix_WIFSTOPPED(PyObject *self, PyObject *args)
+{
+ WAIT_TYPE status;
+ WAIT_STATUS_INT(status) = 0;
+
+ if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
+ return NULL;
+
+ return PyBool_FromLong(WIFSTOPPED(status));
+}
+#endif /* WIFSTOPPED */
+
+#ifdef WIFSIGNALED
+PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
+"WIFSIGNALED(status) -> bool\n\n\
+Return True if the process returning 'status' was terminated by a signal.");
+
+static PyObject *
+posix_WIFSIGNALED(PyObject *self, PyObject *args)
+{
+ WAIT_TYPE status;
+ WAIT_STATUS_INT(status) = 0;
+
+ if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
+ return NULL;
+
+ return PyBool_FromLong(WIFSIGNALED(status));
+}
+#endif /* WIFSIGNALED */
+
+#ifdef WIFEXITED
+PyDoc_STRVAR(posix_WIFEXITED__doc__,
+"WIFEXITED(status) -> bool\n\n\
+Return true if the process returning 'status' exited using the exit()\n\
+system call.");
+
+static PyObject *
+posix_WIFEXITED(PyObject *self, PyObject *args)
+{
+ WAIT_TYPE status;
+ WAIT_STATUS_INT(status) = 0;
+
+ if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
+ return NULL;
+
+ return PyBool_FromLong(WIFEXITED(status));
+}
+#endif /* WIFEXITED */
+
+#ifdef WEXITSTATUS
+PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
+"WEXITSTATUS(status) -> integer\n\n\
+Return the process return code from 'status'.");
+
+static PyObject *
+posix_WEXITSTATUS(PyObject *self, PyObject *args)
+{
+ WAIT_TYPE status;
+ WAIT_STATUS_INT(status) = 0;
+
+ if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
+ return NULL;
+
+ return Py_BuildValue("i", WEXITSTATUS(status));
+}
+#endif /* WEXITSTATUS */
+
+#ifdef WTERMSIG
+PyDoc_STRVAR(posix_WTERMSIG__doc__,
+"WTERMSIG(status) -> integer\n\n\
+Return the signal that terminated the process that provided the 'status'\n\
+value.");
+
+static PyObject *
+posix_WTERMSIG(PyObject *self, PyObject *args)
+{
+ WAIT_TYPE status;
+ WAIT_STATUS_INT(status) = 0;
+
+ if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
+ return NULL;
+
+ return Py_BuildValue("i", WTERMSIG(status));
+}
+#endif /* WTERMSIG */
+
+#ifdef WSTOPSIG
+PyDoc_STRVAR(posix_WSTOPSIG__doc__,
+"WSTOPSIG(status) -> integer\n\n\
+Return the signal that stopped the process that provided\n\
+the 'status' value.");
+
+static PyObject *
+posix_WSTOPSIG(PyObject *self, PyObject *args)
+{
+ WAIT_TYPE status;
+ WAIT_STATUS_INT(status) = 0;
+
+ if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
+ return NULL;
+
+ return Py_BuildValue("i", WSTOPSIG(status));
+}
+#endif /* WSTOPSIG */
+
+#endif /* HAVE_SYS_WAIT_H */
+
+
+#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
+#ifdef _SCO_DS
+/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
+ needed definitions in sys/statvfs.h */
+#define _SVID3
+#endif
+#include <sys/statvfs.h>
+
+static PyObject*
+_pystatvfs_fromstructstatvfs(struct statvfs st) {
+ PyObject *v = PyStructSequence_New(&StatVFSResultType);
+ if (v == NULL)
+ return NULL;
+
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+ PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
+ PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
+ PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
+ PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
+ PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
+ PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
+ PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
+ PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
+ PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
+ PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
+#else
+ PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
+ PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
+ PyStructSequence_SET_ITEM(v, 2,
+ PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
+ PyStructSequence_SET_ITEM(v, 3,
+ PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
+ PyStructSequence_SET_ITEM(v, 4,
+ PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
+ PyStructSequence_SET_ITEM(v, 5,
+ PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
+ PyStructSequence_SET_ITEM(v, 6,
+ PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
+ PyStructSequence_SET_ITEM(v, 7,
+ PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
+ PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
+ PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
+#endif
+
+ return v;
+}
+
+PyDoc_STRVAR(posix_fstatvfs__doc__,
+"fstatvfs(fd) -> statvfs result\n\n\
+Perform an fstatvfs system call on the given fd.");
+
+static PyObject *
+posix_fstatvfs(PyObject *self, PyObject *args)
+{
+ int fd, res;
+ struct statvfs st;
+
+ if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = fstatvfs(fd, &st);
+ Py_END_ALLOW_THREADS
+ if (res != 0)
+ return posix_error();
+
+ return _pystatvfs_fromstructstatvfs(st);
+}
+#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
+
+
+#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
+#include <sys/statvfs.h>
+
+PyDoc_STRVAR(posix_statvfs__doc__,
+"statvfs(path) -> statvfs result\n\n\
+Perform a statvfs system call on the given path.");
+
+static PyObject *
+posix_statvfs(PyObject *self, PyObject *args)
+{
+ char *path;
+ int res;
+ struct statvfs st;
+ if (!PyArg_ParseTuple(args, "s:statvfs", &path))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ res = statvfs(path, &st);
+ Py_END_ALLOW_THREADS
+ if (res != 0)
+ return posix_error_with_filename(path);
+
+ return _pystatvfs_fromstructstatvfs(st);
+}
+#endif /* HAVE_STATVFS */
+
+
+#ifdef HAVE_TEMPNAM
+PyDoc_STRVAR(posix_tempnam__doc__,
+"tempnam([dir[, prefix]]) -> string\n\n\
+Return a unique name for a temporary file.\n\
+The directory and a prefix may be specified as strings; they may be omitted\n\
+or None if not needed.");
+
+static PyObject *
+posix_tempnam(PyObject *self, PyObject *args)
+{
+ PyObject *result = NULL;
+ char *dir = NULL;
+ char *pfx = NULL;
+ char *name;
+
+ if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
+ return NULL;
+
+ if (PyErr_Warn(PyExc_RuntimeWarning,
+ "tempnam is a potential security risk to your program") < 0)
+ return NULL;
+
+ if (PyErr_WarnPy3k("tempnam has been removed in 3.x; "
+ "use the tempfile module", 1) < 0)
+ return NULL;
+
+ name = tempnam(dir, pfx);
+ if (name == NULL)
+ return PyErr_NoMemory();
+ result = PyString_FromString(name);
+ free(name);
+ return result;
+}
+#endif
+
+
+#ifdef HAVE_TMPFILE
+PyDoc_STRVAR(posix_tmpfile__doc__,
+"tmpfile() -> file object\n\n\
+Create a temporary file with no directory entries.");
+
+static PyObject *
+posix_tmpfile(PyObject *self, PyObject *noargs)
+{
+ FILE *fp;
+
+ if (PyErr_WarnPy3k("tmpfile has been removed in 3.x; "
+ "use the tempfile module", 1) < 0)
+ return NULL;
+
+ fp = tmpfile();
+ if (fp == NULL)
+ return posix_error();
+ return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
+}
+#endif
+
+
+#ifdef HAVE_TMPNAM
+PyDoc_STRVAR(posix_tmpnam__doc__,
+"tmpnam() -> string\n\n\
+Return a unique name for a temporary file.");
+
+static PyObject *
+posix_tmpnam(PyObject *self, PyObject *noargs)
+{
+ char buffer[L_tmpnam];
+ char *name;
+
+ if (PyErr_Warn(PyExc_RuntimeWarning,
+ "tmpnam is a potential security risk to your program") < 0)
+ return NULL;
+
+ if (PyErr_WarnPy3k("tmpnam has been removed in 3.x; "
+ "use the tempfile module", 1) < 0)
+ return NULL;
+
+#ifdef USE_TMPNAM_R
+ name = tmpnam_r(buffer);
+#else
+ name = tmpnam(buffer);
+#endif
+ if (name == NULL) {
+ PyObject *err = Py_BuildValue("is", 0,
+#ifdef USE_TMPNAM_R
+ "unexpected NULL from tmpnam_r"
+#else
+ "unexpected NULL from tmpnam"
+#endif
+ );
+ PyErr_SetObject(PyExc_OSError, err);
+ Py_XDECREF(err);
+ return NULL;
+ }
+ return PyString_FromString(buffer);
+}
+#endif
+
+
+/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
+ * It maps strings representing configuration variable names to
+ * integer values, allowing those functions to be called with the
+ * magic names instead of polluting the module's namespace with tons of
+ * rarely-used constants. There are three separate tables that use
+ * these definitions.
+ *
+ * This code is always included, even if none of the interfaces that
+ * need it are included. The #if hackery needed to avoid it would be
+ * sufficiently pervasive that it's not worth the loss of readability.
+ */
+struct constdef {
+ char *name;
+ long value;
+};
+
+#ifndef UEFI_C_SOURCE
+static int
+conv_confname(PyObject *arg, int *valuep, struct constdef *table,
+ size_t tablesize)
+{
+ if (PyInt_Check(arg)) {
+ *valuep = PyInt_AS_LONG(arg);
+ return 1;
+ }
+ if (PyString_Check(arg)) {
+ /* look up the value in the table using a binary search */
+ size_t lo = 0;
+ size_t mid;
+ size_t hi = tablesize;
+ int cmp;
+ char *confname = PyString_AS_STRING(arg);
+ while (lo < hi) {
+ mid = (lo + hi) / 2;
+ cmp = strcmp(confname, table[mid].name);
+ if (cmp < 0)
+ hi = mid;
+ else if (cmp > 0)
+ lo = mid + 1;
+ else {
+ *valuep = table[mid].value;
+ return 1;
+ }
+ }
+ PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
+ }
+ else
+ PyErr_SetString(PyExc_TypeError,
+ "configuration names must be strings or integers");
+ return 0;
+}
+#endif /* UEFI_C_SOURCE */
+
+#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
+static struct constdef posix_constants_pathconf[] = {
+#ifdef _PC_ABI_AIO_XFER_MAX
+ {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
+#endif
+#ifdef _PC_ABI_ASYNC_IO
+ {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
+#endif
+#ifdef _PC_ASYNC_IO
+ {"PC_ASYNC_IO", _PC_ASYNC_IO},
+#endif
+#ifdef _PC_CHOWN_RESTRICTED
+ {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
+#endif
+#ifdef _PC_FILESIZEBITS
+ {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
+#endif
+#ifdef _PC_LAST
+ {"PC_LAST", _PC_LAST},
+#endif
+#ifdef _PC_LINK_MAX
+ {"PC_LINK_MAX", _PC_LINK_MAX},
+#endif
+#ifdef _PC_MAX_CANON
+ {"PC_MAX_CANON", _PC_MAX_CANON},
+#endif
+#ifdef _PC_MAX_INPUT
+ {"PC_MAX_INPUT", _PC_MAX_INPUT},
+#endif
+#ifdef _PC_NAME_MAX
+ {"PC_NAME_MAX", _PC_NAME_MAX},
+#endif
+#ifdef _PC_NO_TRUNC
+ {"PC_NO_TRUNC", _PC_NO_TRUNC},
+#endif
+#ifdef _PC_PATH_MAX
+ {"PC_PATH_MAX", _PC_PATH_MAX},
+#endif
+#ifdef _PC_PIPE_BUF
+ {"PC_PIPE_BUF", _PC_PIPE_BUF},
+#endif
+#ifdef _PC_PRIO_IO
+ {"PC_PRIO_IO", _PC_PRIO_IO},
+#endif
+#ifdef _PC_SOCK_MAXBUF
+ {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
+#endif
+#ifdef _PC_SYNC_IO
+ {"PC_SYNC_IO", _PC_SYNC_IO},
+#endif
+#ifdef _PC_VDISABLE
+ {"PC_VDISABLE", _PC_VDISABLE},
+#endif
+};
+
+static int
+conv_path_confname(PyObject *arg, int *valuep)
+{
+ return conv_confname(arg, valuep, posix_constants_pathconf,
+ sizeof(posix_constants_pathconf)
+ / sizeof(struct constdef));
+}
+#endif
+
+#ifdef HAVE_FPATHCONF
+PyDoc_STRVAR(posix_fpathconf__doc__,
+"fpathconf(fd, name) -> integer\n\n\
+Return the configuration limit name for the file descriptor fd.\n\
+If there is no limit, return -1.");
+
+static PyObject *
+posix_fpathconf(PyObject *self, PyObject *args)
+{
+ PyObject *result = NULL;
+ int name, fd;
+
+ if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
+ conv_path_confname, &name)) {
+ long limit;
+
+ errno = 0;
+ limit = fpathconf(fd, name);
+ if (limit == -1 && errno != 0)
+ posix_error();
+ else
+ result = PyInt_FromLong(limit);
+ }
+ return result;
+}
+#endif
+
+
+#ifdef HAVE_PATHCONF
+PyDoc_STRVAR(posix_pathconf__doc__,
+"pathconf(path, name) -> integer\n\n\
+Return the configuration limit name for the file or directory path.\n\
+If there is no limit, return -1.");
+
+static PyObject *
+posix_pathconf(PyObject *self, PyObject *args)
+{
+ PyObject *result = NULL;
+ int name;
+ char *path;
+
+ if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
+ conv_path_confname, &name)) {
+ long limit;
+
+ errno = 0;
+ limit = pathconf(path, name);
+ if (limit == -1 && errno != 0) {
+ if (errno == EINVAL)
+ /* could be a path or name problem */
+ posix_error();
+ else
+ posix_error_with_filename(path);
+ }
+ else
+ result = PyInt_FromLong(limit);
+ }
+ return result;
+}
+#endif
+
+#ifdef HAVE_CONFSTR
+static struct constdef posix_constants_confstr[] = {
+#ifdef _CS_ARCHITECTURE
+ {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
+#endif
+#ifdef _CS_HOSTNAME
+ {"CS_HOSTNAME", _CS_HOSTNAME},
+#endif
+#ifdef _CS_HW_PROVIDER
+ {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
+#endif
+#ifdef _CS_HW_SERIAL
+ {"CS_HW_SERIAL", _CS_HW_SERIAL},
+#endif
+#ifdef _CS_INITTAB_NAME
+ {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
+#endif
+#ifdef _CS_LFS64_CFLAGS
+ {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
+#endif
+#ifdef _CS_LFS64_LDFLAGS
+ {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
+#endif
+#ifdef _CS_LFS64_LIBS
+ {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
+#endif
+#ifdef _CS_LFS64_LINTFLAGS
+ {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
+#endif
+#ifdef _CS_LFS_CFLAGS
+ {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
+#endif
+#ifdef _CS_LFS_LDFLAGS
+ {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
+#endif
+#ifdef _CS_LFS_LIBS
+ {"CS_LFS_LIBS", _CS_LFS_LIBS},
+#endif
+#ifdef _CS_LFS_LINTFLAGS
+ {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
+#endif
+#ifdef _CS_MACHINE
+ {"CS_MACHINE", _CS_MACHINE},
+#endif
+#ifdef _CS_PATH
+ {"CS_PATH", _CS_PATH},
+#endif
+#ifdef _CS_RELEASE
+ {"CS_RELEASE", _CS_RELEASE},
+#endif
+#ifdef _CS_SRPC_DOMAIN
+ {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
+#endif
+#ifdef _CS_SYSNAME
+ {"CS_SYSNAME", _CS_SYSNAME},
+#endif
+#ifdef _CS_VERSION
+ {"CS_VERSION", _CS_VERSION},
+#endif
+#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
+ {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
+#endif
+#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
+ {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
+#endif
+#ifdef _CS_XBS5_ILP32_OFF32_LIBS
+ {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
+#endif
+#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
+ {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
+#endif
+#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
+ {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
+#endif
+#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
+ {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
+#endif
+#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
+ {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
+#endif
+#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
+ {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
+#endif
+#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
+ {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
+#endif
+#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
+ {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
+#endif
+#ifdef _CS_XBS5_LP64_OFF64_LIBS
+ {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
+#endif
+#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
+ {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
+#endif
+#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
+ {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
+#endif
+#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
+ {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
+#endif
+#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
+ {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
+#endif
+#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
+ {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
+#endif
+#ifdef _MIPS_CS_AVAIL_PROCESSORS
+ {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
+#endif
+#ifdef _MIPS_CS_BASE
+ {"MIPS_CS_BASE", _MIPS_CS_BASE},
+#endif
+#ifdef _MIPS_CS_HOSTID
+ {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
+#endif
+#ifdef _MIPS_CS_HW_NAME
+ {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
+#endif
+#ifdef _MIPS_CS_NUM_PROCESSORS
+ {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
+#endif
+#ifdef _MIPS_CS_OSREL_MAJ
+ {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
+#endif
+#ifdef _MIPS_CS_OSREL_MIN
+ {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
+#endif
+#ifdef _MIPS_CS_OSREL_PATCH
+ {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
+#endif
+#ifdef _MIPS_CS_OS_NAME
+ {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
+#endif
+#ifdef _MIPS_CS_OS_PROVIDER
+ {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
+#endif
+#ifdef _MIPS_CS_PROCESSORS
+ {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
+#endif
+#ifdef _MIPS_CS_SERIAL
+ {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
+#endif
+#ifdef _MIPS_CS_VENDOR
+ {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
+#endif
+};
+
+static int
+conv_confstr_confname(PyObject *arg, int *valuep)
+{
+ return conv_confname(arg, valuep, posix_constants_confstr,
+ sizeof(posix_constants_confstr)
+ / sizeof(struct constdef));
+}
+
+PyDoc_STRVAR(posix_confstr__doc__,
+"confstr(name) -> string\n\n\
+Return a string-valued system configuration variable.");
+
+static PyObject *
+posix_confstr(PyObject *self, PyObject *args)
+{
+ PyObject *result = NULL;
+ int name;
+ char buffer[256];
+
+ if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
+ int len;
+
+ errno = 0;
+ len = confstr(name, buffer, sizeof(buffer));
+ if (len == 0) {
+ if (errno) {
+ posix_error();
+ }
+ else {
+ result = Py_None;
+ Py_INCREF(Py_None);
+ }
+ }
+ else {
+ if ((unsigned int)len >= sizeof(buffer)) {
+ result = PyString_FromStringAndSize(NULL, len-1);
+ if (result != NULL)
+ confstr(name, PyString_AS_STRING(result), len);
+ }
+ else
+ result = PyString_FromStringAndSize(buffer, len-1);
+ }
+ }
+ return result;
+}
+#endif
+
+
+#ifdef HAVE_SYSCONF
+static struct constdef posix_constants_sysconf[] = {
+#ifdef _SC_2_CHAR_TERM
+ {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
+#endif
+#ifdef _SC_2_C_BIND
+ {"SC_2_C_BIND", _SC_2_C_BIND},
+#endif
+#ifdef _SC_2_C_DEV
+ {"SC_2_C_DEV", _SC_2_C_DEV},
+#endif
+#ifdef _SC_2_C_VERSION
+ {"SC_2_C_VERSION", _SC_2_C_VERSION},
+#endif
+#ifdef _SC_2_FORT_DEV
+ {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
+#endif
+#ifdef _SC_2_FORT_RUN
+ {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
+#endif
+#ifdef _SC_2_LOCALEDEF
+ {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
+#endif
+#ifdef _SC_2_SW_DEV
+ {"SC_2_SW_DEV", _SC_2_SW_DEV},
+#endif
+#ifdef _SC_2_UPE
+ {"SC_2_UPE", _SC_2_UPE},
+#endif
+#ifdef _SC_2_VERSION
+ {"SC_2_VERSION", _SC_2_VERSION},
+#endif
+#ifdef _SC_ABI_ASYNCHRONOUS_IO
+ {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
+#endif
+#ifdef _SC_ACL
+ {"SC_ACL", _SC_ACL},
+#endif
+#ifdef _SC_AIO_LISTIO_MAX
+ {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
+#endif
+#ifdef _SC_AIO_MAX
+ {"SC_AIO_MAX", _SC_AIO_MAX},
+#endif
+#ifdef _SC_AIO_PRIO_DELTA_MAX
+ {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
+#endif
+#ifdef _SC_ARG_MAX
+ {"SC_ARG_MAX", _SC_ARG_MAX},
+#endif
+#ifdef _SC_ASYNCHRONOUS_IO
+ {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
+#endif
+#ifdef _SC_ATEXIT_MAX
+ {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
+#endif
+#ifdef _SC_AUDIT
+ {"SC_AUDIT", _SC_AUDIT},
+#endif
+#ifdef _SC_AVPHYS_PAGES
+ {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
+#endif
+#ifdef _SC_BC_BASE_MAX
+ {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
+#endif
+#ifdef _SC_BC_DIM_MAX
+ {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
+#endif
+#ifdef _SC_BC_SCALE_MAX
+ {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
+#endif
+#ifdef _SC_BC_STRING_MAX
+ {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
+#endif
+#ifdef _SC_CAP
+ {"SC_CAP", _SC_CAP},
+#endif
+#ifdef _SC_CHARCLASS_NAME_MAX
+ {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
+#endif
+#ifdef _SC_CHAR_BIT
+ {"SC_CHAR_BIT", _SC_CHAR_BIT},
+#endif
+#ifdef _SC_CHAR_MAX
+ {"SC_CHAR_MAX", _SC_CHAR_MAX},
+#endif
+#ifdef _SC_CHAR_MIN
+ {"SC_CHAR_MIN", _SC_CHAR_MIN},
+#endif
+#ifdef _SC_CHILD_MAX
+ {"SC_CHILD_MAX", _SC_CHILD_MAX},
+#endif
+#ifdef _SC_CLK_TCK
+ {"SC_CLK_TCK", _SC_CLK_TCK},
+#endif
+#ifdef _SC_COHER_BLKSZ
+ {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
+#endif
+#ifdef _SC_COLL_WEIGHTS_MAX
+ {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
+#endif
+#ifdef _SC_DCACHE_ASSOC
+ {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
+#endif
+#ifdef _SC_DCACHE_BLKSZ
+ {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
+#endif
+#ifdef _SC_DCACHE_LINESZ
+ {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
+#endif
+#ifdef _SC_DCACHE_SZ
+ {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
+#endif
+#ifdef _SC_DCACHE_TBLKSZ
+ {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
+#endif
+#ifdef _SC_DELAYTIMER_MAX
+ {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
+#endif
+#ifdef _SC_EQUIV_CLASS_MAX
+ {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
+#endif
+#ifdef _SC_EXPR_NEST_MAX
+ {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
+#endif
+#ifdef _SC_FSYNC
+ {"SC_FSYNC", _SC_FSYNC},
+#endif
+#ifdef _SC_GETGR_R_SIZE_MAX
+ {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
+#endif
+#ifdef _SC_GETPW_R_SIZE_MAX
+ {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
+#endif
+#ifdef _SC_ICACHE_ASSOC
+ {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
+#endif
+#ifdef _SC_ICACHE_BLKSZ
+ {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
+#endif
+#ifdef _SC_ICACHE_LINESZ
+ {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
+#endif
+#ifdef _SC_ICACHE_SZ
+ {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
+#endif
+#ifdef _SC_INF
+ {"SC_INF", _SC_INF},
+#endif
+#ifdef _SC_INT_MAX
+ {"SC_INT_MAX", _SC_INT_MAX},
+#endif
+#ifdef _SC_INT_MIN
+ {"SC_INT_MIN", _SC_INT_MIN},
+#endif
+#ifdef _SC_IOV_MAX
+ {"SC_IOV_MAX", _SC_IOV_MAX},
+#endif
+#ifdef _SC_IP_SECOPTS
+ {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
+#endif
+#ifdef _SC_JOB_CONTROL
+ {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
+#endif
+#ifdef _SC_KERN_POINTERS
+ {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
+#endif
+#ifdef _SC_KERN_SIM
+ {"SC_KERN_SIM", _SC_KERN_SIM},
+#endif
+#ifdef _SC_LINE_MAX
+ {"SC_LINE_MAX", _SC_LINE_MAX},
+#endif
+#ifdef _SC_LOGIN_NAME_MAX
+ {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
+#endif
+#ifdef _SC_LOGNAME_MAX
+ {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
+#endif
+#ifdef _SC_LONG_BIT
+ {"SC_LONG_BIT", _SC_LONG_BIT},
+#endif
+#ifdef _SC_MAC
+ {"SC_MAC", _SC_MAC},
+#endif
+#ifdef _SC_MAPPED_FILES
+ {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
+#endif
+#ifdef _SC_MAXPID
+ {"SC_MAXPID", _SC_MAXPID},
+#endif
+#ifdef _SC_MB_LEN_MAX
+ {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
+#endif
+#ifdef _SC_MEMLOCK
+ {"SC_MEMLOCK", _SC_MEMLOCK},
+#endif
+#ifdef _SC_MEMLOCK_RANGE
+ {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
+#endif
+#ifdef _SC_MEMORY_PROTECTION
+ {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
+#endif
+#ifdef _SC_MESSAGE_PASSING
+ {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
+#endif
+#ifdef _SC_MMAP_FIXED_ALIGNMENT
+ {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
+#endif
+#ifdef _SC_MQ_OPEN_MAX
+ {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
+#endif
+#ifdef _SC_MQ_PRIO_MAX
+ {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
+#endif
+#ifdef _SC_NACLS_MAX
+ {"SC_NACLS_MAX", _SC_NACLS_MAX},
+#endif
+#ifdef _SC_NGROUPS_MAX
+ {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
+#endif
+#ifdef _SC_NL_ARGMAX
+ {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
+#endif
+#ifdef _SC_NL_LANGMAX
+ {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
+#endif
+#ifdef _SC_NL_MSGMAX
+ {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
+#endif
+#ifdef _SC_NL_NMAX
+ {"SC_NL_NMAX", _SC_NL_NMAX},
+#endif
+#ifdef _SC_NL_SETMAX
+ {"SC_NL_SETMAX", _SC_NL_SETMAX},
+#endif
+#ifdef _SC_NL_TEXTMAX
+ {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
+#endif
+#ifdef _SC_NPROCESSORS_CONF
+ {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
+#endif
+#ifdef _SC_NPROCESSORS_ONLN
+ {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
+#endif
+#ifdef _SC_NPROC_CONF
+ {"SC_NPROC_CONF", _SC_NPROC_CONF},
+#endif
+#ifdef _SC_NPROC_ONLN
+ {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
+#endif
+#ifdef _SC_NZERO
+ {"SC_NZERO", _SC_NZERO},
+#endif
+#ifdef _SC_OPEN_MAX
+ {"SC_OPEN_MAX", _SC_OPEN_MAX},
+#endif
+#ifdef _SC_PAGESIZE
+ {"SC_PAGESIZE", _SC_PAGESIZE},
+#endif
+#ifdef _SC_PAGE_SIZE
+ {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
+#endif
+#ifdef _SC_PASS_MAX
+ {"SC_PASS_MAX", _SC_PASS_MAX},
+#endif
+#ifdef _SC_PHYS_PAGES
+ {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
+#endif
+#ifdef _SC_PII
+ {"SC_PII", _SC_PII},
+#endif
+#ifdef _SC_PII_INTERNET
+ {"SC_PII_INTERNET", _SC_PII_INTERNET},
+#endif
+#ifdef _SC_PII_INTERNET_DGRAM
+ {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
+#endif
+#ifdef _SC_PII_INTERNET_STREAM
+ {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
+#endif
+#ifdef _SC_PII_OSI
+ {"SC_PII_OSI", _SC_PII_OSI},
+#endif
+#ifdef _SC_PII_OSI_CLTS
+ {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
+#endif
+#ifdef _SC_PII_OSI_COTS
+ {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
+#endif
+#ifdef _SC_PII_OSI_M
+ {"SC_PII_OSI_M", _SC_PII_OSI_M},
+#endif
+#ifdef _SC_PII_SOCKET
+ {"SC_PII_SOCKET", _SC_PII_SOCKET},
+#endif
+#ifdef _SC_PII_XTI
+ {"SC_PII_XTI", _SC_PII_XTI},
+#endif
+#ifdef _SC_POLL
+ {"SC_POLL", _SC_POLL},
+#endif
+#ifdef _SC_PRIORITIZED_IO
+ {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
+#endif
+#ifdef _SC_PRIORITY_SCHEDULING
+ {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
+#endif
+#ifdef _SC_REALTIME_SIGNALS
+ {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
+#endif
+#ifdef _SC_RE_DUP_MAX
+ {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
+#endif
+#ifdef _SC_RTSIG_MAX
+ {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
+#endif
+#ifdef _SC_SAVED_IDS
+ {"SC_SAVED_IDS", _SC_SAVED_IDS},
+#endif
+#ifdef _SC_SCHAR_MAX
+ {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
+#endif
+#ifdef _SC_SCHAR_MIN
+ {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
+#endif
+#ifdef _SC_SELECT
+ {"SC_SELECT", _SC_SELECT},
+#endif
+#ifdef _SC_SEMAPHORES
+ {"SC_SEMAPHORES", _SC_SEMAPHORES},
+#endif
+#ifdef _SC_SEM_NSEMS_MAX
+ {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
+#endif
+#ifdef _SC_SEM_VALUE_MAX
+ {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
+#endif
+#ifdef _SC_SHARED_MEMORY_OBJECTS
+ {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
+#endif
+#ifdef _SC_SHRT_MAX
+ {"SC_SHRT_MAX", _SC_SHRT_MAX},
+#endif
+#ifdef _SC_SHRT_MIN
+ {"SC_SHRT_MIN", _SC_SHRT_MIN},
+#endif
+#ifdef _SC_SIGQUEUE_MAX
+ {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
+#endif
+#ifdef _SC_SIGRT_MAX
+ {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
+#endif
+#ifdef _SC_SIGRT_MIN
+ {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
+#endif
+#ifdef _SC_SOFTPOWER
+ {"SC_SOFTPOWER", _SC_SOFTPOWER},
+#endif
+#ifdef _SC_SPLIT_CACHE
+ {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
+#endif
+#ifdef _SC_SSIZE_MAX
+ {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
+#endif
+#ifdef _SC_STACK_PROT
+ {"SC_STACK_PROT", _SC_STACK_PROT},
+#endif
+#ifdef _SC_STREAM_MAX
+ {"SC_STREAM_MAX", _SC_STREAM_MAX},
+#endif
+#ifdef _SC_SYNCHRONIZED_IO
+ {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
+#endif
+#ifdef _SC_THREADS
+ {"SC_THREADS", _SC_THREADS},
+#endif
+#ifdef _SC_THREAD_ATTR_STACKADDR
+ {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
+#endif
+#ifdef _SC_THREAD_ATTR_STACKSIZE
+ {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
+#endif
+#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
+ {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
+#endif
+#ifdef _SC_THREAD_KEYS_MAX
+ {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
+#endif
+#ifdef _SC_THREAD_PRIORITY_SCHEDULING
+ {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
+#endif
+#ifdef _SC_THREAD_PRIO_INHERIT
+ {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
+#endif
+#ifdef _SC_THREAD_PRIO_PROTECT
+ {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
+#endif
+#ifdef _SC_THREAD_PROCESS_SHARED
+ {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
+#endif
+#ifdef _SC_THREAD_SAFE_FUNCTIONS
+ {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
+#endif
+#ifdef _SC_THREAD_STACK_MIN
+ {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
+#endif
+#ifdef _SC_THREAD_THREADS_MAX
+ {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
+#endif
+#ifdef _SC_TIMERS
+ {"SC_TIMERS", _SC_TIMERS},
+#endif
+#ifdef _SC_TIMER_MAX
+ {"SC_TIMER_MAX", _SC_TIMER_MAX},
+#endif
+#ifdef _SC_TTY_NAME_MAX
+ {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
+#endif
+#ifdef _SC_TZNAME_MAX
+ {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
+#endif
+#ifdef _SC_T_IOV_MAX
+ {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
+#endif
+#ifdef _SC_UCHAR_MAX
+ {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
+#endif
+#ifdef _SC_UINT_MAX
+ {"SC_UINT_MAX", _SC_UINT_MAX},
+#endif
+#ifdef _SC_UIO_MAXIOV
+ {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
+#endif
+#ifdef _SC_ULONG_MAX
+ {"SC_ULONG_MAX", _SC_ULONG_MAX},
+#endif
+#ifdef _SC_USHRT_MAX
+ {"SC_USHRT_MAX", _SC_USHRT_MAX},
+#endif
+#ifdef _SC_VERSION
+ {"SC_VERSION", _SC_VERSION},
+#endif
+#ifdef _SC_WORD_BIT
+ {"SC_WORD_BIT", _SC_WORD_BIT},
+#endif
+#ifdef _SC_XBS5_ILP32_OFF32
+ {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
+#endif
+#ifdef _SC_XBS5_ILP32_OFFBIG
+ {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
+#endif
+#ifdef _SC_XBS5_LP64_OFF64
+ {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
+#endif
+#ifdef _SC_XBS5_LPBIG_OFFBIG
+ {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
+#endif
+#ifdef _SC_XOPEN_CRYPT
+ {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
+#endif
+#ifdef _SC_XOPEN_ENH_I18N
+ {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
+#endif
+#ifdef _SC_XOPEN_LEGACY
+ {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
+#endif
+#ifdef _SC_XOPEN_REALTIME
+ {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
+#endif
+#ifdef _SC_XOPEN_REALTIME_THREADS
+ {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
+#endif
+#ifdef _SC_XOPEN_SHM
+ {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
+#endif
+#ifdef _SC_XOPEN_UNIX
+ {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
+#endif
+#ifdef _SC_XOPEN_VERSION
+ {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
+#endif
+#ifdef _SC_XOPEN_XCU_VERSION
+ {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
+#endif
+#ifdef _SC_XOPEN_XPG2
+ {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
+#endif
+#ifdef _SC_XOPEN_XPG3
+ {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
+#endif
+#ifdef _SC_XOPEN_XPG4
+ {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
+#endif
+};
+
+static int
+conv_sysconf_confname(PyObject *arg, int *valuep)
+{
+ return conv_confname(arg, valuep, posix_constants_sysconf,
+ sizeof(posix_constants_sysconf)
+ / sizeof(struct constdef));
+}
+
+PyDoc_STRVAR(posix_sysconf__doc__,
+"sysconf(name) -> integer\n\n\
+Return an integer-valued system configuration variable.");
+
+static PyObject *
+posix_sysconf(PyObject *self, PyObject *args)
+{
+ PyObject *result = NULL;
+ int name;
+
+ if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
+ int value;
+
+ errno = 0;
+ value = sysconf(name);
+ if (value == -1 && errno != 0)
+ posix_error();
+ else
+ result = PyInt_FromLong(value);
+ }
+ return result;
+}
+#endif
+
+
+#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF) || defined(HAVE_CONFSTR) || defined(HAVE_SYSCONF)
+/* This code is used to ensure that the tables of configuration value names
+ * are in sorted order as required by conv_confname(), and also to build the
+ * the exported dictionaries that are used to publish information about the
+ * names available on the host platform.
+ *
+ * Sorting the table at runtime ensures that the table is properly ordered
+ * when used, even for platforms we're not able to test on. It also makes
+ * it easier to add additional entries to the tables.
+ */
+
+static int
+cmp_constdefs(const void *v1, const void *v2)
+{
+ const struct constdef *c1 =
+ (const struct constdef *) v1;
+ const struct constdef *c2 =
+ (const struct constdef *) v2;
+
+ return strcmp(c1->name, c2->name);
+}
+
+static int
+setup_confname_table(struct constdef *table, size_t tablesize,
+ char *tablename, PyObject *module)
+{
+ PyObject *d = NULL;
+ size_t i;
+
+ qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
+ d = PyDict_New();
+ if (d == NULL)
+ return -1;
+
+ for (i=0; i < tablesize; ++i) {
+ PyObject *o = PyInt_FromLong(table[i].value);
+ if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
+ Py_XDECREF(o);
+ Py_DECREF(d);
+ return -1;
+ }
+ Py_DECREF(o);
+ }
+ return PyModule_AddObject(module, tablename, d);
+}
+#endif /* HAVE_FPATHCONF || HAVE_PATHCONF || HAVE_CONFSTR || HAVE_SYSCONF */
+
+/* Return -1 on failure, 0 on success. */
+static int
+setup_confname_tables(PyObject *module)
+{
+#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
+ if (setup_confname_table(posix_constants_pathconf,
+ sizeof(posix_constants_pathconf)
+ / sizeof(struct constdef),
+ "pathconf_names", module))
+ return -1;
+#endif
+#ifdef HAVE_CONFSTR
+ if (setup_confname_table(posix_constants_confstr,
+ sizeof(posix_constants_confstr)
+ / sizeof(struct constdef),
+ "confstr_names", module))
+ return -1;
+#endif
+#ifdef HAVE_SYSCONF
+ if (setup_confname_table(posix_constants_sysconf,
+ sizeof(posix_constants_sysconf)
+ / sizeof(struct constdef),
+ "sysconf_names", module))
+ return -1;
+#endif
+ return 0;
+}
+
+
+PyDoc_STRVAR(posix_abort__doc__,
+"abort() -> does not return!\n\n\
+Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
+in the hardest way possible on the hosting operating system.");
+
+static PyObject *
+posix_abort(PyObject *self, PyObject *noargs)
+{
+ abort();
+ /*NOTREACHED*/
+ Py_FatalError("abort() called from Python code didn't abort!");
+ return NULL;
+}
+
+#ifdef HAVE_SETRESUID
+PyDoc_STRVAR(posix_setresuid__doc__,
+"setresuid(ruid, euid, suid)\n\n\
+Set the current process's real, effective, and saved user ids.");
+
+static PyObject*
+posix_setresuid (PyObject *self, PyObject *args)
+{
+ /* We assume uid_t is no larger than a long. */
+ long ruid, euid, suid;
+ if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))
+ return NULL;
+ if (setresuid(ruid, euid, suid) < 0)
+ return posix_error();
+ Py_RETURN_NONE;
+}
+#endif
+
+#ifdef HAVE_SETRESGID
+PyDoc_STRVAR(posix_setresgid__doc__,
+"setresgid(rgid, egid, sgid)\n\n\
+Set the current process's real, effective, and saved group ids.");
+
+static PyObject*
+posix_setresgid (PyObject *self, PyObject *args)
+{
+ /* We assume uid_t is no larger than a long. */
+ long rgid, egid, sgid;
+ if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))
+ return NULL;
+ if (setresgid(rgid, egid, sgid) < 0)
+ return posix_error();
+ Py_RETURN_NONE;
+}
+#endif
+
+#ifdef HAVE_GETRESUID
+PyDoc_STRVAR(posix_getresuid__doc__,
+"getresuid() -> (ruid, euid, suid)\n\n\
+Get tuple of the current process's real, effective, and saved user ids.");
+
+static PyObject*
+posix_getresuid (PyObject *self, PyObject *noargs)
+{
+ uid_t ruid, euid, suid;
+ long l_ruid, l_euid, l_suid;
+ if (getresuid(&ruid, &euid, &suid) < 0)
+ return posix_error();
+ /* Force the values into long's as we don't know the size of uid_t. */
+ l_ruid = ruid;
+ l_euid = euid;
+ l_suid = suid;
+ return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);
+}
+#endif
+
+#ifdef HAVE_GETRESGID
+PyDoc_STRVAR(posix_getresgid__doc__,
+"getresgid() -> (rgid, egid, sgid)\n\n\
+Get tuple of the current process's real, effective, and saved group ids.");
+
+static PyObject*
+posix_getresgid (PyObject *self, PyObject *noargs)
+{
+ uid_t rgid, egid, sgid;
+ long l_rgid, l_egid, l_sgid;
+ if (getresgid(&rgid, &egid, &sgid) < 0)
+ return posix_error();
+ /* Force the values into long's as we don't know the size of uid_t. */
+ l_rgid = rgid;
+ l_egid = egid;
+ l_sgid = sgid;
+ return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);
+}
+#endif
+
+static PyMethodDef posix_methods[] = {
+ {"access", posix_access, METH_VARARGS, posix_access__doc__},
+#ifdef HAVE_TTYNAME
+ {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
+#endif
+ {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
+#ifdef HAVE_CHFLAGS
+ {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
+#endif /* HAVE_CHFLAGS */
+ {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
+#ifdef HAVE_FCHMOD
+ {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
+#endif /* HAVE_FCHMOD */
+#ifdef HAVE_CHOWN
+ {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
+#endif /* HAVE_CHOWN */
+#ifdef HAVE_LCHMOD
+ {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
+#endif /* HAVE_LCHMOD */
+#ifdef HAVE_FCHOWN
+ {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
+#endif /* HAVE_FCHOWN */
+#ifdef HAVE_LCHFLAGS
+ {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
+#endif /* HAVE_LCHFLAGS */
+#ifdef HAVE_LCHOWN
+ {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
+#endif /* HAVE_LCHOWN */
+#ifdef HAVE_CHROOT
+ {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
+#endif
+#ifdef HAVE_CTERMID
+ {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
+#endif
+#ifdef HAVE_GETCWD
+ {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
+#ifdef Py_USING_UNICODE
+ {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
+#endif
+#endif
+#ifdef HAVE_LINK
+ {"link", posix_link, METH_VARARGS, posix_link__doc__},
+#endif /* HAVE_LINK */
+ {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
+ {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
+ {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
+#ifdef HAVE_NICE
+ {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
+#endif /* HAVE_NICE */
+#ifdef HAVE_READLINK
+ {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
+#endif /* HAVE_READLINK */
+ {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
+ {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
+ {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
+ //{"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
+#ifdef HAVE_SYMLINK
+ {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
+#endif /* HAVE_SYMLINK */
+#ifdef HAVE_SYSTEM
+ {"system", posix_system, METH_VARARGS, posix_system__doc__},
+#endif
+ {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
+#ifdef HAVE_UNAME
+ {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
+#endif /* HAVE_UNAME */
+ {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
+ {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
+ {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
+#ifdef HAVE_TIMES
+ {"times", posix_times, METH_NOARGS, posix_times__doc__},
+#endif /* HAVE_TIMES */
+ {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
+#ifdef HAVE_EXECV
+ {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
+ {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
+#endif /* HAVE_EXECV */
+#ifdef HAVE_SPAWNV
+ {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
+ {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
+#if defined(PYOS_OS2)
+ {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
+ {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
+#endif /* PYOS_OS2 */
+#endif /* HAVE_SPAWNV */
+#ifdef HAVE_FORK1
+ {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
+#endif /* HAVE_FORK1 */
+#ifdef HAVE_FORK
+ {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
+#endif /* HAVE_FORK */
+#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
+ {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
+#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
+#ifdef HAVE_FORKPTY
+ {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
+#endif /* HAVE_FORKPTY */
+#ifdef HAVE_GETEGID
+ {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
+#endif /* HAVE_GETEGID */
+#ifdef HAVE_GETEUID
+ {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
+#endif /* HAVE_GETEUID */
+#ifdef HAVE_GETGID
+ {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
+#endif /* HAVE_GETGID */
+#ifdef HAVE_GETGROUPS
+ {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
+#endif
+ {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
+#ifdef HAVE_GETPGRP
+ {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
+#endif /* HAVE_GETPGRP */
+#ifdef HAVE_GETPPID
+ {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
+#endif /* HAVE_GETPPID */
+#ifdef HAVE_GETUID
+ {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
+#endif /* HAVE_GETUID */
+#ifdef HAVE_GETLOGIN
+ {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
+#endif
+#ifdef HAVE_KILL
+ {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
+#endif /* HAVE_KILL */
+#ifdef HAVE_KILLPG
+ {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
+#endif /* HAVE_KILLPG */
+#ifdef HAVE_PLOCK
+ {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
+#endif /* HAVE_PLOCK */
+#ifdef HAVE_POPEN
+ {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
+#ifdef MS_WINDOWS
+ {"popen2", win32_popen2, METH_VARARGS},
+ {"popen3", win32_popen3, METH_VARARGS},
+ {"popen4", win32_popen4, METH_VARARGS},
+ {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
+ {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},
+#else
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+ {"popen2", os2emx_popen2, METH_VARARGS},
+ {"popen3", os2emx_popen3, METH_VARARGS},
+ {"popen4", os2emx_popen4, METH_VARARGS},
+#endif
+#endif
+#endif /* HAVE_POPEN */
+#ifdef HAVE_SETUID
+ {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
+#endif /* HAVE_SETUID */
+#ifdef HAVE_SETEUID
+ {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
+#endif /* HAVE_SETEUID */
+#ifdef HAVE_SETEGID
+ {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
+#endif /* HAVE_SETEGID */
+#ifdef HAVE_SETREUID
+ {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
+#endif /* HAVE_SETREUID */
+#ifdef HAVE_SETREGID
+ {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
+#endif /* HAVE_SETREGID */
+#ifdef HAVE_SETGID
+ {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
+#endif /* HAVE_SETGID */
+#ifdef HAVE_SETGROUPS
+ {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
+#endif /* HAVE_SETGROUPS */
+#ifdef HAVE_INITGROUPS
+ {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
+#endif /* HAVE_INITGROUPS */
+#ifdef HAVE_GETPGID
+ {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
+#endif /* HAVE_GETPGID */
+#ifdef HAVE_SETPGRP
+ {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
+#endif /* HAVE_SETPGRP */
+#ifdef HAVE_WAIT
+ {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
+#endif /* HAVE_WAIT */
+#ifdef HAVE_WAIT3
+ {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
+#endif /* HAVE_WAIT3 */
+#ifdef HAVE_WAIT4
+ {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
+#endif /* HAVE_WAIT4 */
+#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
+ {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
+#endif /* HAVE_WAITPID */
+#ifdef HAVE_GETSID
+ {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
+#endif /* HAVE_GETSID */
+#ifdef HAVE_SETSID
+ {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
+#endif /* HAVE_SETSID */
+#ifdef HAVE_SETPGID
+ {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
+#endif /* HAVE_SETPGID */
+#ifdef HAVE_TCGETPGRP
+ {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
+#endif /* HAVE_TCGETPGRP */
+#ifdef HAVE_TCSETPGRP
+ {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
+#endif /* HAVE_TCSETPGRP */
+ {"open", posix_open, METH_VARARGS, posix_open__doc__},
+ {"close", posix_close, METH_VARARGS, posix_close__doc__},
+ {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
+ {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
+ {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
+ {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
+ {"read", posix_read, METH_VARARGS, posix_read__doc__},
+ {"write", posix_write, METH_VARARGS, posix_write__doc__},
+ {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
+ {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
+ {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
+#ifdef HAVE_PIPE
+ {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
+#endif
+#ifdef HAVE_MKFIFO
+ {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
+#endif
+#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
+ {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
+#endif
+#ifdef HAVE_DEVICE_MACROS
+ {"major", posix_major, METH_VARARGS, posix_major__doc__},
+ {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
+ {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
+#endif
+#ifdef HAVE_FTRUNCATE
+ {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
+#endif
+#ifdef HAVE_PUTENV
+ {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
+#endif
+#ifdef HAVE_UNSETENV
+ {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
+#endif
+ {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
+#ifdef HAVE_FCHDIR
+ {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
+#endif
+#ifdef HAVE_FSYNC
+ {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
+#endif
+#ifdef HAVE_FDATASYNC
+ {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#ifdef WCOREDUMP
+ {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
+#endif /* WCOREDUMP */
+#ifdef WIFCONTINUED
+ {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
+#endif /* WIFCONTINUED */
+#ifdef WIFSTOPPED
+ {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
+#endif /* WIFSTOPPED */
+#ifdef WIFSIGNALED
+ {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
+#endif /* WIFSIGNALED */
+#ifdef WIFEXITED
+ {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
+#endif /* WIFEXITED */
+#ifdef WEXITSTATUS
+ {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
+#endif /* WEXITSTATUS */
+#ifdef WTERMSIG
+ {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
+#endif /* WTERMSIG */
+#ifdef WSTOPSIG
+ {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
+#endif /* WSTOPSIG */
+#endif /* HAVE_SYS_WAIT_H */
+#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
+ {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
+#endif
+#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
+ {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
+#endif
+#ifdef HAVE_TMPFILE
+ {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
+#endif
+#ifdef HAVE_TEMPNAM
+ {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
+#endif
+#ifdef HAVE_TMPNAM
+ {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
+#endif
+#ifdef HAVE_CONFSTR
+ {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
+#endif
+#ifdef HAVE_SYSCONF
+ {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
+#endif
+#ifdef HAVE_FPATHCONF
+ {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
+#endif
+#ifdef HAVE_PATHCONF
+ {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
+#endif
+ {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
+#ifdef HAVE_SETRESUID
+ {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},
+#endif
+#ifdef HAVE_SETRESGID
+ {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},
+#endif
+#ifdef HAVE_GETRESUID
+ {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},
+#endif
+#ifdef HAVE_GETRESGID
+ {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},
+#endif
+
+ {NULL, NULL} /* Sentinel */
+};
+
+
+static int
+ins(PyObject *module, char *symbol, long value)
+{
+ return PyModule_AddIntConstant(module, symbol, value);
+}
+
+static int
+all_ins(PyObject *d)
+{
+#ifdef F_OK
+ if (ins(d, "F_OK", (long)F_OK)) return -1;
+#endif
+#ifdef R_OK
+ if (ins(d, "R_OK", (long)R_OK)) return -1;
+#endif
+#ifdef W_OK
+ if (ins(d, "W_OK", (long)W_OK)) return -1;
+#endif
+#ifdef X_OK
+ if (ins(d, "X_OK", (long)X_OK)) return -1;
+#endif
+#ifdef NGROUPS_MAX
+ if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
+#endif
+#ifdef TMP_MAX
+ if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
+#endif
+#ifdef WCONTINUED
+ if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
+#endif
+#ifdef WNOHANG
+ if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
+#endif
+#ifdef WUNTRACED
+ if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
+#endif
+#ifdef O_RDONLY
+ if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
+#endif
+#ifdef O_WRONLY
+ if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
+#endif
+#ifdef O_RDWR
+ if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
+#endif
+#ifdef O_NDELAY
+ if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
+#endif
+#ifdef O_NONBLOCK
+ if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
+#endif
+#ifdef O_APPEND
+ if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
+#endif
+#ifdef O_DSYNC
+ if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
+#endif
+#ifdef O_RSYNC
+ if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
+#endif
+#ifdef O_SYNC
+ if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
+#endif
+#ifdef O_NOCTTY
+ if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
+#endif
+#ifdef O_CREAT
+ if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
+#endif
+#ifdef O_EXCL
+ if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
+#endif
+#ifdef O_TRUNC
+ if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
+#endif
+#ifdef O_BINARY
+ if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
+#endif
+#ifdef O_TEXT
+ if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
+#endif
+#ifdef O_LARGEFILE
+ if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
+#endif
+#ifdef O_SHLOCK
+ if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
+#endif
+#ifdef O_EXLOCK
+ if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
+#endif
+
+/* MS Windows */
+#ifdef O_NOINHERIT
+ /* Don't inherit in child processes. */
+ if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
+#endif
+#ifdef _O_SHORT_LIVED
+ /* Optimize for short life (keep in memory). */
+ /* MS forgot to define this one with a non-underscore form too. */
+ if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
+#endif
+#ifdef O_TEMPORARY
+ /* Automatically delete when last handle is closed. */
+ if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
+#endif
+#ifdef O_RANDOM
+ /* Optimize for random access. */
+ if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
+#endif
+#ifdef O_SEQUENTIAL
+ /* Optimize for sequential access. */
+ if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
+#endif
+
+/* GNU extensions. */
+#ifdef O_ASYNC
+ /* Send a SIGIO signal whenever input or output
+ becomes available on file descriptor */
+ if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
+#endif
+#ifdef O_DIRECT
+ /* Direct disk access. */
+ if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
+#endif
+#ifdef O_DIRECTORY
+ /* Must be a directory. */
+ if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
+#endif
+#ifdef O_NOFOLLOW
+ /* Do not follow links. */
+ if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
+#endif
+#ifdef O_NOATIME
+ /* Do not update the access time. */
+ if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
+#endif
+
+ /* These come from sysexits.h */
+#ifdef EX_OK
+ if (ins(d, "EX_OK", (long)EX_OK)) return -1;
+#endif /* EX_OK */
+#ifdef EX_USAGE
+ if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
+#endif /* EX_USAGE */
+#ifdef EX_DATAERR
+ if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
+#endif /* EX_DATAERR */
+#ifdef EX_NOINPUT
+ if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
+#endif /* EX_NOINPUT */
+#ifdef EX_NOUSER
+ if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
+#endif /* EX_NOUSER */
+#ifdef EX_NOHOST
+ if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
+#endif /* EX_NOHOST */
+#ifdef EX_UNAVAILABLE
+ if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
+#endif /* EX_UNAVAILABLE */
+#ifdef EX_SOFTWARE
+ if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
+#endif /* EX_SOFTWARE */
+#ifdef EX_OSERR
+ if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
+#endif /* EX_OSERR */
+#ifdef EX_OSFILE
+ if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
+#endif /* EX_OSFILE */
+#ifdef EX_CANTCREAT
+ if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
+#endif /* EX_CANTCREAT */
+#ifdef EX_IOERR
+ if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
+#endif /* EX_IOERR */
+#ifdef EX_TEMPFAIL
+ if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
+#endif /* EX_TEMPFAIL */
+#ifdef EX_PROTOCOL
+ if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
+#endif /* EX_PROTOCOL */
+#ifdef EX_NOPERM
+ if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
+#endif /* EX_NOPERM */
+#ifdef EX_CONFIG
+ if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
+#endif /* EX_CONFIG */
+#ifdef EX_NOTFOUND
+ if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
+#endif /* EX_NOTFOUND */
+
+#ifdef HAVE_SPAWNV
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+ if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
+ if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
+ if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
+ if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
+ if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
+ if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
+ if (ins(d, "P_PM", (long)P_PM)) return -1;
+ if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
+ if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
+ if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
+ if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
+ if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
+ if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
+ if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
+ if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
+ if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
+ if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
+ if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
+ if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
+ if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
+#else
+ if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
+ if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
+ if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
+ if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
+ if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
+#endif
+#endif
+ return 0;
+}
+
+#define INITFUNC initedk2
+#define MODNAME "edk2"
+
+PyMODINIT_FUNC
+INITFUNC(void)
+{
+ PyObject *m;
+
+#ifndef UEFI_C_SOURCE
+ PyObject *v;
+#endif
+
+ m = Py_InitModule3(MODNAME,
+ posix_methods,
+ edk2__doc__);
+ if (m == NULL)
+ return;
+
+#ifndef UEFI_C_SOURCE
+ /* Initialize environ dictionary */
+ v = convertenviron();
+ Py_XINCREF(v);
+ if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
+ return;
+ Py_DECREF(v);
+#endif /* UEFI_C_SOURCE */
+
+ if (all_ins(m))
+ return;
+
+ if (setup_confname_tables(m))
+ return;
+
+ Py_INCREF(PyExc_OSError);
+ PyModule_AddObject(m, "error", PyExc_OSError);
+
+#ifdef HAVE_PUTENV
+ if (posix_putenv_garbage == NULL)
+ posix_putenv_garbage = PyDict_New();
+#endif
+
+ if (!initialized) {
+ stat_result_desc.name = MODNAME ".stat_result";
+ stat_result_desc.fields[2].name = PyStructSequence_UnnamedField;
+ stat_result_desc.fields[3].name = PyStructSequence_UnnamedField;
+ stat_result_desc.fields[4].name = PyStructSequence_UnnamedField;
+ PyStructSequence_InitType(&StatResultType, &stat_result_desc);
+ structseq_new = StatResultType.tp_new;
+ StatResultType.tp_new = statresult_new;
+
+ //statvfs_result_desc.name = MODNAME ".statvfs_result";
+ //PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
+#ifdef NEED_TICKS_PER_SECOND
+# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
+ ticks_per_second = sysconf(_SC_CLK_TCK);
+# elif defined(HZ)
+ ticks_per_second = HZ;
+# else
+ ticks_per_second = 60; /* magic fallback value; may be bogus */
+# endif
+#endif
+ }
+ Py_INCREF((PyObject*) &StatResultType);
+ PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
+ //Py_INCREF((PyObject*) &StatVFSResultType);
+ //PyModule_AddObject(m, "statvfs_result",
+ // (PyObject*) &StatVFSResultType);
+ initialized = 1;
+
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+
diff --git a/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/errnomodule.c b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/errnomodule.c new file mode 100644 index 0000000000..349aaa8d6d --- /dev/null +++ b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/errnomodule.c @@ -0,0 +1,791 @@ +
+/* Errno module */
+
+#include "Python.h"
+
+/* Windows socket errors (WSA*) */
+#ifdef MS_WINDOWS
+#include <windows.h>
+#endif
+
+/*
+ * Pull in the system error definitions
+ */
+
+static PyMethodDef errno_methods[] = {
+ {NULL, NULL}
+};
+
+/* Helper function doing the dictionary inserting */
+
+static void
+_inscode(PyObject *d, PyObject *de, char *name, int code)
+{
+ PyObject *u = PyString_FromString(name);
+ PyObject *v = PyInt_FromLong((long) code);
+
+ /* Don't bother checking for errors; they'll be caught at the end
+ * of the module initialization function by the caller of
+ * initerrno().
+ */
+ if (u && v) {
+ /* insert in modules dict */
+ PyDict_SetItem(d, u, v);
+ /* insert in errorcode dict */
+ PyDict_SetItem(de, v, u);
+ }
+ Py_XDECREF(u);
+ Py_XDECREF(v);
+}
+
+PyDoc_STRVAR(errno__doc__,
+"This module makes available standard errno system symbols.\n\
+\n\
+The value of each symbol is the corresponding integer value,\n\
+e.g., on most systems, errno.ENOENT equals the integer 2.\n\
+\n\
+The dictionary errno.errorcode maps numeric codes to symbol names,\n\
+e.g., errno.errorcode[2] could be the string 'ENOENT'.\n\
+\n\
+Symbols that are not relevant to the underlying system are not defined.\n\
+\n\
+To map error codes to error messages, use the function os.strerror(),\n\
+e.g. os.strerror(2) could return 'No such file or directory'.");
+
+PyMODINIT_FUNC
+initerrno(void)
+{
+ PyObject *m, *d, *de;
+ m = Py_InitModule3("errno", errno_methods, errno__doc__);
+ if (m == NULL)
+ return;
+ d = PyModule_GetDict(m);
+ de = PyDict_New();
+ if (!d || !de || PyDict_SetItemString(d, "errorcode", de) < 0)
+ return;
+
+/* Macro so I don't have to edit each and every line below... */
+#define inscode(d, ds, de, name, code, comment) _inscode(d, de, name, code)
+
+ /*
+ * The names and comments are borrowed from linux/include/errno.h,
+ * which should be pretty all-inclusive
+ */
+
+#ifdef ENODEV
+ inscode(d, ds, de, "ENODEV", ENODEV, "No such device");
+#endif
+#ifdef ENOCSI
+ inscode(d, ds, de, "ENOCSI", ENOCSI, "No CSI structure available");
+#endif
+#ifdef EHOSTUNREACH
+ inscode(d, ds, de, "EHOSTUNREACH", EHOSTUNREACH, "No route to host");
+#else
+#ifdef WSAEHOSTUNREACH
+ inscode(d, ds, de, "EHOSTUNREACH", WSAEHOSTUNREACH, "No route to host");
+#endif
+#endif
+#ifdef ENOMSG
+ inscode(d, ds, de, "ENOMSG", ENOMSG, "No message of desired type");
+#endif
+#ifdef EUCLEAN
+ inscode(d, ds, de, "EUCLEAN", EUCLEAN, "Structure needs cleaning");
+#endif
+#ifdef EL2NSYNC
+ inscode(d, ds, de, "EL2NSYNC", EL2NSYNC, "Level 2 not synchronized");
+#endif
+#ifdef EL2HLT
+ inscode(d, ds, de, "EL2HLT", EL2HLT, "Level 2 halted");
+#endif
+#ifdef ENODATA
+ inscode(d, ds, de, "ENODATA", ENODATA, "No data available");
+#endif
+#ifdef ENOTBLK
+ inscode(d, ds, de, "ENOTBLK", ENOTBLK, "Block device required");
+#endif
+#ifdef ENOSYS
+ inscode(d, ds, de, "ENOSYS", ENOSYS, "Function not implemented");
+#endif
+#ifdef EPIPE
+ inscode(d, ds, de, "EPIPE", EPIPE, "Broken pipe");
+#endif
+#ifdef EINVAL
+ inscode(d, ds, de, "EINVAL", EINVAL, "Invalid argument");
+#else
+#ifdef WSAEINVAL
+ inscode(d, ds, de, "EINVAL", WSAEINVAL, "Invalid argument");
+#endif
+#endif
+#ifdef EOVERFLOW
+ inscode(d, ds, de, "EOVERFLOW", EOVERFLOW, "Value too large for defined data type");
+#endif
+#ifdef EADV
+ inscode(d, ds, de, "EADV", EADV, "Advertise error");
+#endif
+#ifdef EINTR
+ inscode(d, ds, de, "EINTR", EINTR, "Interrupted system call");
+#else
+#ifdef WSAEINTR
+ inscode(d, ds, de, "EINTR", WSAEINTR, "Interrupted system call");
+#endif
+#endif
+#ifdef EUSERS
+ inscode(d, ds, de, "EUSERS", EUSERS, "Too many users");
+#else
+#ifdef WSAEUSERS
+ inscode(d, ds, de, "EUSERS", WSAEUSERS, "Too many users");
+#endif
+#endif
+#ifdef ENOTEMPTY
+ inscode(d, ds, de, "ENOTEMPTY", ENOTEMPTY, "Directory not empty");
+#else
+#ifdef WSAENOTEMPTY
+ inscode(d, ds, de, "ENOTEMPTY", WSAENOTEMPTY, "Directory not empty");
+#endif
+#endif
+#ifdef ENOBUFS
+ inscode(d, ds, de, "ENOBUFS", ENOBUFS, "No buffer space available");
+#else
+#ifdef WSAENOBUFS
+ inscode(d, ds, de, "ENOBUFS", WSAENOBUFS, "No buffer space available");
+#endif
+#endif
+#ifdef EPROTO
+ inscode(d, ds, de, "EPROTO", EPROTO, "Protocol error");
+#endif
+#ifdef EREMOTE
+ inscode(d, ds, de, "EREMOTE", EREMOTE, "Object is remote");
+#else
+#ifdef WSAEREMOTE
+ inscode(d, ds, de, "EREMOTE", WSAEREMOTE, "Object is remote");
+#endif
+#endif
+#ifdef ENAVAIL
+ inscode(d, ds, de, "ENAVAIL", ENAVAIL, "No XENIX semaphores available");
+#endif
+#ifdef ECHILD
+ inscode(d, ds, de, "ECHILD", ECHILD, "No child processes");
+#endif
+#ifdef ELOOP
+ inscode(d, ds, de, "ELOOP", ELOOP, "Too many symbolic links encountered");
+#else
+#ifdef WSAELOOP
+ inscode(d, ds, de, "ELOOP", WSAELOOP, "Too many symbolic links encountered");
+#endif
+#endif
+#ifdef EXDEV
+ inscode(d, ds, de, "EXDEV", EXDEV, "Cross-device link");
+#endif
+#ifdef E2BIG
+ inscode(d, ds, de, "E2BIG", E2BIG, "Arg list too long");
+#endif
+#ifdef ESRCH
+ inscode(d, ds, de, "ESRCH", ESRCH, "No such process");
+#endif
+#ifdef EMSGSIZE
+ inscode(d, ds, de, "EMSGSIZE", EMSGSIZE, "Message too long");
+#else
+#ifdef WSAEMSGSIZE
+ inscode(d, ds, de, "EMSGSIZE", WSAEMSGSIZE, "Message too long");
+#endif
+#endif
+#ifdef EAFNOSUPPORT
+ inscode(d, ds, de, "EAFNOSUPPORT", EAFNOSUPPORT, "Address family not supported by protocol");
+#else
+#ifdef WSAEAFNOSUPPORT
+ inscode(d, ds, de, "EAFNOSUPPORT", WSAEAFNOSUPPORT, "Address family not supported by protocol");
+#endif
+#endif
+#ifdef EBADR
+ inscode(d, ds, de, "EBADR", EBADR, "Invalid request descriptor");
+#endif
+#ifdef EHOSTDOWN
+ inscode(d, ds, de, "EHOSTDOWN", EHOSTDOWN, "Host is down");
+#else
+#ifdef WSAEHOSTDOWN
+ inscode(d, ds, de, "EHOSTDOWN", WSAEHOSTDOWN, "Host is down");
+#endif
+#endif
+#ifdef EPFNOSUPPORT
+ inscode(d, ds, de, "EPFNOSUPPORT", EPFNOSUPPORT, "Protocol family not supported");
+#else
+#ifdef WSAEPFNOSUPPORT
+ inscode(d, ds, de, "EPFNOSUPPORT", WSAEPFNOSUPPORT, "Protocol family not supported");
+#endif
+#endif
+#ifdef ENOPROTOOPT
+ inscode(d, ds, de, "ENOPROTOOPT", ENOPROTOOPT, "Protocol not available");
+#else
+#ifdef WSAENOPROTOOPT
+ inscode(d, ds, de, "ENOPROTOOPT", WSAENOPROTOOPT, "Protocol not available");
+#endif
+#endif
+#ifdef EBUSY
+ inscode(d, ds, de, "EBUSY", EBUSY, "Device or resource busy");
+#endif
+#ifdef EWOULDBLOCK
+ inscode(d, ds, de, "EWOULDBLOCK", EWOULDBLOCK, "Operation would block");
+#else
+#ifdef WSAEWOULDBLOCK
+ inscode(d, ds, de, "EWOULDBLOCK", WSAEWOULDBLOCK, "Operation would block");
+#endif
+#endif
+#ifdef EBADFD
+ inscode(d, ds, de, "EBADFD", EBADFD, "File descriptor in bad state");
+#endif
+#ifdef EDOTDOT
+ inscode(d, ds, de, "EDOTDOT", EDOTDOT, "RFS specific error");
+#endif
+#ifdef EISCONN
+ inscode(d, ds, de, "EISCONN", EISCONN, "Transport endpoint is already connected");
+#else
+#ifdef WSAEISCONN
+ inscode(d, ds, de, "EISCONN", WSAEISCONN, "Transport endpoint is already connected");
+#endif
+#endif
+#ifdef ENOANO
+ inscode(d, ds, de, "ENOANO", ENOANO, "No anode");
+#endif
+#ifdef ESHUTDOWN
+ inscode(d, ds, de, "ESHUTDOWN", ESHUTDOWN, "Cannot send after transport endpoint shutdown");
+#else
+#ifdef WSAESHUTDOWN
+ inscode(d, ds, de, "ESHUTDOWN", WSAESHUTDOWN, "Cannot send after transport endpoint shutdown");
+#endif
+#endif
+#ifdef ECHRNG
+ inscode(d, ds, de, "ECHRNG", ECHRNG, "Channel number out of range");
+#endif
+#ifdef ELIBBAD
+ inscode(d, ds, de, "ELIBBAD", ELIBBAD, "Accessing a corrupted shared library");
+#endif
+#ifdef ENONET
+ inscode(d, ds, de, "ENONET", ENONET, "Machine is not on the network");
+#endif
+#ifdef EBADE
+ inscode(d, ds, de, "EBADE", EBADE, "Invalid exchange");
+#endif
+#ifdef EBADF
+ inscode(d, ds, de, "EBADF", EBADF, "Bad file number");
+#else
+#ifdef WSAEBADF
+ inscode(d, ds, de, "EBADF", WSAEBADF, "Bad file number");
+#endif
+#endif
+#ifdef EMULTIHOP
+ inscode(d, ds, de, "EMULTIHOP", EMULTIHOP, "Multihop attempted");
+#endif
+#ifdef EIO
+ inscode(d, ds, de, "EIO", EIO, "I/O error");
+#endif
+#ifdef EUNATCH
+ inscode(d, ds, de, "EUNATCH", EUNATCH, "Protocol driver not attached");
+#endif
+#ifdef EPROTOTYPE
+ inscode(d, ds, de, "EPROTOTYPE", EPROTOTYPE, "Protocol wrong type for socket");
+#else
+#ifdef WSAEPROTOTYPE
+ inscode(d, ds, de, "EPROTOTYPE", WSAEPROTOTYPE, "Protocol wrong type for socket");
+#endif
+#endif
+#ifdef ENOSPC
+ inscode(d, ds, de, "ENOSPC", ENOSPC, "No space left on device");
+#endif
+#ifdef ENOEXEC
+ inscode(d, ds, de, "ENOEXEC", ENOEXEC, "Exec format error");
+#endif
+#ifdef EALREADY
+ inscode(d, ds, de, "EALREADY", EALREADY, "Operation already in progress");
+#else
+#ifdef WSAEALREADY
+ inscode(d, ds, de, "EALREADY", WSAEALREADY, "Operation already in progress");
+#endif
+#endif
+#ifdef ENETDOWN
+ inscode(d, ds, de, "ENETDOWN", ENETDOWN, "Network is down");
+#else
+#ifdef WSAENETDOWN
+ inscode(d, ds, de, "ENETDOWN", WSAENETDOWN, "Network is down");
+#endif
+#endif
+#ifdef ENOTNAM
+ inscode(d, ds, de, "ENOTNAM", ENOTNAM, "Not a XENIX named type file");
+#endif
+#ifdef EACCES
+ inscode(d, ds, de, "EACCES", EACCES, "Permission denied");
+#else
+#ifdef WSAEACCES
+ inscode(d, ds, de, "EACCES", WSAEACCES, "Permission denied");
+#endif
+#endif
+#ifdef ELNRNG
+ inscode(d, ds, de, "ELNRNG", ELNRNG, "Link number out of range");
+#endif
+#ifdef EILSEQ
+ inscode(d, ds, de, "EILSEQ", EILSEQ, "Illegal byte sequence");
+#endif
+#ifdef ENOTDIR
+ inscode(d, ds, de, "ENOTDIR", ENOTDIR, "Not a directory");
+#endif
+#ifdef ENOTUNIQ
+ inscode(d, ds, de, "ENOTUNIQ", ENOTUNIQ, "Name not unique on network");
+#endif
+#ifdef EPERM
+ inscode(d, ds, de, "EPERM", EPERM, "Operation not permitted");
+#endif
+#ifdef EDOM
+ inscode(d, ds, de, "EDOM", EDOM, "Math argument out of domain of func");
+#endif
+#ifdef EXFULL
+ inscode(d, ds, de, "EXFULL", EXFULL, "Exchange full");
+#endif
+#ifdef ECONNREFUSED
+ inscode(d, ds, de, "ECONNREFUSED", ECONNREFUSED, "Connection refused");
+#else
+#ifdef WSAECONNREFUSED
+ inscode(d, ds, de, "ECONNREFUSED", WSAECONNREFUSED, "Connection refused");
+#endif
+#endif
+#ifdef EISDIR
+ inscode(d, ds, de, "EISDIR", EISDIR, "Is a directory");
+#endif
+#ifdef EPROTONOSUPPORT
+ inscode(d, ds, de, "EPROTONOSUPPORT", EPROTONOSUPPORT, "Protocol not supported");
+#else
+#ifdef WSAEPROTONOSUPPORT
+ inscode(d, ds, de, "EPROTONOSUPPORT", WSAEPROTONOSUPPORT, "Protocol not supported");
+#endif
+#endif
+#ifdef EROFS
+ inscode(d, ds, de, "EROFS", EROFS, "Read-only file system");
+#endif
+#ifdef EADDRNOTAVAIL
+ inscode(d, ds, de, "EADDRNOTAVAIL", EADDRNOTAVAIL, "Cannot assign requested address");
+#else
+#ifdef WSAEADDRNOTAVAIL
+ inscode(d, ds, de, "EADDRNOTAVAIL", WSAEADDRNOTAVAIL, "Cannot assign requested address");
+#endif
+#endif
+#ifdef EIDRM
+ inscode(d, ds, de, "EIDRM", EIDRM, "Identifier removed");
+#endif
+#ifdef ECOMM
+ inscode(d, ds, de, "ECOMM", ECOMM, "Communication error on send");
+#endif
+#ifdef ESRMNT
+ inscode(d, ds, de, "ESRMNT", ESRMNT, "Srmount error");
+#endif
+#ifdef EREMOTEIO
+ inscode(d, ds, de, "EREMOTEIO", EREMOTEIO, "Remote I/O error");
+#endif
+#ifdef EL3RST
+ inscode(d, ds, de, "EL3RST", EL3RST, "Level 3 reset");
+#endif
+#ifdef EBADMSG
+ inscode(d, ds, de, "EBADMSG", EBADMSG, "Not a data message");
+#endif
+#ifdef ENFILE
+ inscode(d, ds, de, "ENFILE", ENFILE, "File table overflow");
+#endif
+#ifdef ELIBMAX
+ inscode(d, ds, de, "ELIBMAX", ELIBMAX, "Attempting to link in too many shared libraries");
+#endif
+#ifdef ESPIPE
+ inscode(d, ds, de, "ESPIPE", ESPIPE, "Illegal seek");
+#endif
+#ifdef ENOLINK
+ inscode(d, ds, de, "ENOLINK", ENOLINK, "Link has been severed");
+#endif
+#ifdef ENETRESET
+ inscode(d, ds, de, "ENETRESET", ENETRESET, "Network dropped connection because of reset");
+#else
+#ifdef WSAENETRESET
+ inscode(d, ds, de, "ENETRESET", WSAENETRESET, "Network dropped connection because of reset");
+#endif
+#endif
+#ifdef ETIMEDOUT
+ inscode(d, ds, de, "ETIMEDOUT", ETIMEDOUT, "Connection timed out");
+#else
+#ifdef WSAETIMEDOUT
+ inscode(d, ds, de, "ETIMEDOUT", WSAETIMEDOUT, "Connection timed out");
+#endif
+#endif
+#ifdef ENOENT
+ inscode(d, ds, de, "ENOENT", ENOENT, "No such file or directory");
+#endif
+#ifdef EEXIST
+ inscode(d, ds, de, "EEXIST", EEXIST, "File exists");
+#endif
+#ifdef EDQUOT
+ inscode(d, ds, de, "EDQUOT", EDQUOT, "Quota exceeded");
+#else
+#ifdef WSAEDQUOT
+ inscode(d, ds, de, "EDQUOT", WSAEDQUOT, "Quota exceeded");
+#endif
+#endif
+#ifdef ENOSTR
+ inscode(d, ds, de, "ENOSTR", ENOSTR, "Device not a stream");
+#endif
+#ifdef EBADSLT
+ inscode(d, ds, de, "EBADSLT", EBADSLT, "Invalid slot");
+#endif
+#ifdef EBADRQC
+ inscode(d, ds, de, "EBADRQC", EBADRQC, "Invalid request code");
+#endif
+#ifdef ELIBACC
+ inscode(d, ds, de, "ELIBACC", ELIBACC, "Can not access a needed shared library");
+#endif
+#ifdef EFAULT
+ inscode(d, ds, de, "EFAULT", EFAULT, "Bad address");
+#else
+#ifdef WSAEFAULT
+ inscode(d, ds, de, "EFAULT", WSAEFAULT, "Bad address");
+#endif
+#endif
+#ifdef EFBIG
+ inscode(d, ds, de, "EFBIG", EFBIG, "File too large");
+#endif
+#ifdef EDEADLK
+ inscode(d, ds, de, "EDEADLK", EDEADLK, "Resource deadlock would occur");
+#endif
+#ifdef ENOTCONN
+ inscode(d, ds, de, "ENOTCONN", ENOTCONN, "Transport endpoint is not connected");
+#else
+#ifdef WSAENOTCONN
+ inscode(d, ds, de, "ENOTCONN", WSAENOTCONN, "Transport endpoint is not connected");
+#endif
+#endif
+#ifdef EDESTADDRREQ
+ inscode(d, ds, de, "EDESTADDRREQ", EDESTADDRREQ, "Destination address required");
+#else
+#ifdef WSAEDESTADDRREQ
+ inscode(d, ds, de, "EDESTADDRREQ", WSAEDESTADDRREQ, "Destination address required");
+#endif
+#endif
+#ifdef ELIBSCN
+ inscode(d, ds, de, "ELIBSCN", ELIBSCN, ".lib section in a.out corrupted");
+#endif
+#ifdef ENOLCK
+ inscode(d, ds, de, "ENOLCK", ENOLCK, "No record locks available");
+#endif
+#ifdef EISNAM
+ inscode(d, ds, de, "EISNAM", EISNAM, "Is a named type file");
+#endif
+#ifdef ECONNABORTED
+ inscode(d, ds, de, "ECONNABORTED", ECONNABORTED, "Software caused connection abort");
+#else
+#ifdef WSAECONNABORTED
+ inscode(d, ds, de, "ECONNABORTED", WSAECONNABORTED, "Software caused connection abort");
+#endif
+#endif
+#ifdef ENETUNREACH
+ inscode(d, ds, de, "ENETUNREACH", ENETUNREACH, "Network is unreachable");
+#else
+#ifdef WSAENETUNREACH
+ inscode(d, ds, de, "ENETUNREACH", WSAENETUNREACH, "Network is unreachable");
+#endif
+#endif
+#ifdef ESTALE
+ inscode(d, ds, de, "ESTALE", ESTALE, "Stale NFS file handle");
+#else
+#ifdef WSAESTALE
+ inscode(d, ds, de, "ESTALE", WSAESTALE, "Stale NFS file handle");
+#endif
+#endif
+#ifdef ENOSR
+ inscode(d, ds, de, "ENOSR", ENOSR, "Out of streams resources");
+#endif
+#ifdef ENOMEM
+ inscode(d, ds, de, "ENOMEM", ENOMEM, "Out of memory");
+#endif
+#ifdef ENOTSOCK
+ inscode(d, ds, de, "ENOTSOCK", ENOTSOCK, "Socket operation on non-socket");
+#else
+#ifdef WSAENOTSOCK
+ inscode(d, ds, de, "ENOTSOCK", WSAENOTSOCK, "Socket operation on non-socket");
+#endif
+#endif
+#ifdef ESTRPIPE
+ inscode(d, ds, de, "ESTRPIPE", ESTRPIPE, "Streams pipe error");
+#endif
+#ifdef EMLINK
+ inscode(d, ds, de, "EMLINK", EMLINK, "Too many links");
+#endif
+#ifdef ERANGE
+ inscode(d, ds, de, "ERANGE", ERANGE, "Math result not representable");
+#endif
+#ifdef ELIBEXEC
+ inscode(d, ds, de, "ELIBEXEC", ELIBEXEC, "Cannot exec a shared library directly");
+#endif
+#ifdef EL3HLT
+ inscode(d, ds, de, "EL3HLT", EL3HLT, "Level 3 halted");
+#endif
+#ifdef ECONNRESET
+ inscode(d, ds, de, "ECONNRESET", ECONNRESET, "Connection reset by peer");
+#else
+#ifdef WSAECONNRESET
+ inscode(d, ds, de, "ECONNRESET", WSAECONNRESET, "Connection reset by peer");
+#endif
+#endif
+#ifdef EADDRINUSE
+ inscode(d, ds, de, "EADDRINUSE", EADDRINUSE, "Address already in use");
+#else
+#ifdef WSAEADDRINUSE
+ inscode(d, ds, de, "EADDRINUSE", WSAEADDRINUSE, "Address already in use");
+#endif
+#endif
+#ifdef EOPNOTSUPP
+ inscode(d, ds, de, "EOPNOTSUPP", EOPNOTSUPP, "Operation not supported on transport endpoint");
+#else
+#ifdef WSAEOPNOTSUPP
+ inscode(d, ds, de, "EOPNOTSUPP", WSAEOPNOTSUPP, "Operation not supported on transport endpoint");
+#endif
+#endif
+#ifdef EREMCHG
+ inscode(d, ds, de, "EREMCHG", EREMCHG, "Remote address changed");
+#endif
+#ifdef EAGAIN
+ inscode(d, ds, de, "EAGAIN", EAGAIN, "Try again");
+#endif
+#ifdef ENAMETOOLONG
+ inscode(d, ds, de, "ENAMETOOLONG", ENAMETOOLONG, "File name too long");
+#else
+#ifdef WSAENAMETOOLONG
+ inscode(d, ds, de, "ENAMETOOLONG", WSAENAMETOOLONG, "File name too long");
+#endif
+#endif
+#ifdef ENOTTY
+ inscode(d, ds, de, "ENOTTY", ENOTTY, "Not a typewriter");
+#endif
+#ifdef ERESTART
+ inscode(d, ds, de, "ERESTART", ERESTART, "Interrupted system call should be restarted");
+#endif
+#ifdef ESOCKTNOSUPPORT
+ inscode(d, ds, de, "ESOCKTNOSUPPORT", ESOCKTNOSUPPORT, "Socket type not supported");
+#else
+#ifdef WSAESOCKTNOSUPPORT
+ inscode(d, ds, de, "ESOCKTNOSUPPORT", WSAESOCKTNOSUPPORT, "Socket type not supported");
+#endif
+#endif
+#ifdef ETIME
+ inscode(d, ds, de, "ETIME", ETIME, "Timer expired");
+#endif
+#ifdef EBFONT
+ inscode(d, ds, de, "EBFONT", EBFONT, "Bad font file format");
+#endif
+#ifdef EDEADLOCK
+ inscode(d, ds, de, "EDEADLOCK", EDEADLOCK, "Error EDEADLOCK");
+#endif
+#ifdef ETOOMANYREFS
+ inscode(d, ds, de, "ETOOMANYREFS", ETOOMANYREFS, "Too many references: cannot splice");
+#else
+#ifdef WSAETOOMANYREFS
+ inscode(d, ds, de, "ETOOMANYREFS", WSAETOOMANYREFS, "Too many references: cannot splice");
+#endif
+#endif
+#ifdef EMFILE
+ inscode(d, ds, de, "EMFILE", EMFILE, "Too many open files");
+#else
+#ifdef WSAEMFILE
+ inscode(d, ds, de, "EMFILE", WSAEMFILE, "Too many open files");
+#endif
+#endif
+#ifdef ETXTBSY
+ inscode(d, ds, de, "ETXTBSY", ETXTBSY, "Text file busy");
+#endif
+#ifdef EINPROGRESS
+ inscode(d, ds, de, "EINPROGRESS", EINPROGRESS, "Operation now in progress");
+#else
+#ifdef WSAEINPROGRESS
+ inscode(d, ds, de, "EINPROGRESS", WSAEINPROGRESS, "Operation now in progress");
+#endif
+#endif
+#ifdef ENXIO
+ inscode(d, ds, de, "ENXIO", ENXIO, "No such device or address");
+#endif
+#ifdef ENOPKG
+ inscode(d, ds, de, "ENOPKG", ENOPKG, "Package not installed");
+#endif
+#ifdef WSASY
+ inscode(d, ds, de, "WSASY", WSASY, "Error WSASY");
+#endif
+#ifdef WSAEHOSTDOWN
+ inscode(d, ds, de, "WSAEHOSTDOWN", WSAEHOSTDOWN, "Host is down");
+#endif
+#ifdef WSAENETDOWN
+ inscode(d, ds, de, "WSAENETDOWN", WSAENETDOWN, "Network is down");
+#endif
+#ifdef WSAENOTSOCK
+ inscode(d, ds, de, "WSAENOTSOCK", WSAENOTSOCK, "Socket operation on non-socket");
+#endif
+#ifdef WSAEHOSTUNREACH
+ inscode(d, ds, de, "WSAEHOSTUNREACH", WSAEHOSTUNREACH, "No route to host");
+#endif
+#ifdef WSAELOOP
+ inscode(d, ds, de, "WSAELOOP", WSAELOOP, "Too many symbolic links encountered");
+#endif
+#ifdef WSAEMFILE
+ inscode(d, ds, de, "WSAEMFILE", WSAEMFILE, "Too many open files");
+#endif
+#ifdef WSAESTALE
+ inscode(d, ds, de, "WSAESTALE", WSAESTALE, "Stale NFS file handle");
+#endif
+#ifdef WSAVERNOTSUPPORTED
+ inscode(d, ds, de, "WSAVERNOTSUPPORTED", WSAVERNOTSUPPORTED, "Error WSAVERNOTSUPPORTED");
+#endif
+#ifdef WSAENETUNREACH
+ inscode(d, ds, de, "WSAENETUNREACH", WSAENETUNREACH, "Network is unreachable");
+#endif
+#ifdef WSAEPROCLIM
+ inscode(d, ds, de, "WSAEPROCLIM", WSAEPROCLIM, "Error WSAEPROCLIM");
+#endif
+#ifdef WSAEFAULT
+ inscode(d, ds, de, "WSAEFAULT", WSAEFAULT, "Bad address");
+#endif
+#ifdef WSANOTINITIALISED
+ inscode(d, ds, de, "WSANOTINITIALISED", WSANOTINITIALISED, "Error WSANOTINITIALISED");
+#endif
+#ifdef WSAEUSERS
+ inscode(d, ds, de, "WSAEUSERS", WSAEUSERS, "Too many users");
+#endif
+#ifdef WSAMAKEASYNCREPL
+ inscode(d, ds, de, "WSAMAKEASYNCREPL", WSAMAKEASYNCREPL, "Error WSAMAKEASYNCREPL");
+#endif
+#ifdef WSAENOPROTOOPT
+ inscode(d, ds, de, "WSAENOPROTOOPT", WSAENOPROTOOPT, "Protocol not available");
+#endif
+#ifdef WSAECONNABORTED
+ inscode(d, ds, de, "WSAECONNABORTED", WSAECONNABORTED, "Software caused connection abort");
+#endif
+#ifdef WSAENAMETOOLONG
+ inscode(d, ds, de, "WSAENAMETOOLONG", WSAENAMETOOLONG, "File name too long");
+#endif
+#ifdef WSAENOTEMPTY
+ inscode(d, ds, de, "WSAENOTEMPTY", WSAENOTEMPTY, "Directory not empty");
+#endif
+#ifdef WSAESHUTDOWN
+ inscode(d, ds, de, "WSAESHUTDOWN", WSAESHUTDOWN, "Cannot send after transport endpoint shutdown");
+#endif
+#ifdef WSAEAFNOSUPPORT
+ inscode(d, ds, de, "WSAEAFNOSUPPORT", WSAEAFNOSUPPORT, "Address family not supported by protocol");
+#endif
+#ifdef WSAETOOMANYREFS
+ inscode(d, ds, de, "WSAETOOMANYREFS", WSAETOOMANYREFS, "Too many references: cannot splice");
+#endif
+#ifdef WSAEACCES
+ inscode(d, ds, de, "WSAEACCES", WSAEACCES, "Permission denied");
+#endif
+#ifdef WSATR
+ inscode(d, ds, de, "WSATR", WSATR, "Error WSATR");
+#endif
+#ifdef WSABASEERR
+ inscode(d, ds, de, "WSABASEERR", WSABASEERR, "Error WSABASEERR");
+#endif
+#ifdef WSADESCRIPTIO
+ inscode(d, ds, de, "WSADESCRIPTIO", WSADESCRIPTIO, "Error WSADESCRIPTIO");
+#endif
+#ifdef WSAEMSGSIZE
+ inscode(d, ds, de, "WSAEMSGSIZE", WSAEMSGSIZE, "Message too long");
+#endif
+#ifdef WSAEBADF
+ inscode(d, ds, de, "WSAEBADF", WSAEBADF, "Bad file number");
+#endif
+#ifdef WSAECONNRESET
+ inscode(d, ds, de, "WSAECONNRESET", WSAECONNRESET, "Connection reset by peer");
+#endif
+#ifdef WSAGETSELECTERRO
+ inscode(d, ds, de, "WSAGETSELECTERRO", WSAGETSELECTERRO, "Error WSAGETSELECTERRO");
+#endif
+#ifdef WSAETIMEDOUT
+ inscode(d, ds, de, "WSAETIMEDOUT", WSAETIMEDOUT, "Connection timed out");
+#endif
+#ifdef WSAENOBUFS
+ inscode(d, ds, de, "WSAENOBUFS", WSAENOBUFS, "No buffer space available");
+#endif
+#ifdef WSAEDISCON
+ inscode(d, ds, de, "WSAEDISCON", WSAEDISCON, "Error WSAEDISCON");
+#endif
+#ifdef WSAEINTR
+ inscode(d, ds, de, "WSAEINTR", WSAEINTR, "Interrupted system call");
+#endif
+#ifdef WSAEPROTOTYPE
+ inscode(d, ds, de, "WSAEPROTOTYPE", WSAEPROTOTYPE, "Protocol wrong type for socket");
+#endif
+#ifdef WSAHOS
+ inscode(d, ds, de, "WSAHOS", WSAHOS, "Error WSAHOS");
+#endif
+#ifdef WSAEADDRINUSE
+ inscode(d, ds, de, "WSAEADDRINUSE", WSAEADDRINUSE, "Address already in use");
+#endif
+#ifdef WSAEADDRNOTAVAIL
+ inscode(d, ds, de, "WSAEADDRNOTAVAIL", WSAEADDRNOTAVAIL, "Cannot assign requested address");
+#endif
+#ifdef WSAEALREADY
+ inscode(d, ds, de, "WSAEALREADY", WSAEALREADY, "Operation already in progress");
+#endif
+#ifdef WSAEPROTONOSUPPORT
+ inscode(d, ds, de, "WSAEPROTONOSUPPORT", WSAEPROTONOSUPPORT, "Protocol not supported");
+#endif
+#ifdef WSASYSNOTREADY
+ inscode(d, ds, de, "WSASYSNOTREADY", WSASYSNOTREADY, "Error WSASYSNOTREADY");
+#endif
+#ifdef WSAEWOULDBLOCK
+ inscode(d, ds, de, "WSAEWOULDBLOCK", WSAEWOULDBLOCK, "Operation would block");
+#endif
+#ifdef WSAEPFNOSUPPORT
+ inscode(d, ds, de, "WSAEPFNOSUPPORT", WSAEPFNOSUPPORT, "Protocol family not supported");
+#endif
+#ifdef WSAEOPNOTSUPP
+ inscode(d, ds, de, "WSAEOPNOTSUPP", WSAEOPNOTSUPP, "Operation not supported on transport endpoint");
+#endif
+#ifdef WSAEISCONN
+ inscode(d, ds, de, "WSAEISCONN", WSAEISCONN, "Transport endpoint is already connected");
+#endif
+#ifdef WSAEDQUOT
+ inscode(d, ds, de, "WSAEDQUOT", WSAEDQUOT, "Quota exceeded");
+#endif
+#ifdef WSAENOTCONN
+ inscode(d, ds, de, "WSAENOTCONN", WSAENOTCONN, "Transport endpoint is not connected");
+#endif
+#ifdef WSAEREMOTE
+ inscode(d, ds, de, "WSAEREMOTE", WSAEREMOTE, "Object is remote");
+#endif
+#ifdef WSAEINVAL
+ inscode(d, ds, de, "WSAEINVAL", WSAEINVAL, "Invalid argument");
+#endif
+#ifdef WSAEINPROGRESS
+ inscode(d, ds, de, "WSAEINPROGRESS", WSAEINPROGRESS, "Operation now in progress");
+#endif
+#ifdef WSAGETSELECTEVEN
+ inscode(d, ds, de, "WSAGETSELECTEVEN", WSAGETSELECTEVEN, "Error WSAGETSELECTEVEN");
+#endif
+#ifdef WSAESOCKTNOSUPPORT
+ inscode(d, ds, de, "WSAESOCKTNOSUPPORT", WSAESOCKTNOSUPPORT, "Socket type not supported");
+#endif
+#ifdef WSAGETASYNCERRO
+ inscode(d, ds, de, "WSAGETASYNCERRO", WSAGETASYNCERRO, "Error WSAGETASYNCERRO");
+#endif
+#ifdef WSAMAKESELECTREPL
+ inscode(d, ds, de, "WSAMAKESELECTREPL", WSAMAKESELECTREPL, "Error WSAMAKESELECTREPL");
+#endif
+#ifdef WSAGETASYNCBUFLE
+ inscode(d, ds, de, "WSAGETASYNCBUFLE", WSAGETASYNCBUFLE, "Error WSAGETASYNCBUFLE");
+#endif
+#ifdef WSAEDESTADDRREQ
+ inscode(d, ds, de, "WSAEDESTADDRREQ", WSAEDESTADDRREQ, "Destination address required");
+#endif
+#ifdef WSAECONNREFUSED
+ inscode(d, ds, de, "WSAECONNREFUSED", WSAECONNREFUSED, "Connection refused");
+#endif
+#ifdef WSAENETRESET
+ inscode(d, ds, de, "WSAENETRESET", WSAENETRESET, "Network dropped connection because of reset");
+#endif
+#ifdef WSAN
+ inscode(d, ds, de, "WSAN", WSAN, "Error WSAN");
+#endif
+#ifdef ENOTSUP
+ inscode(d, ds, de, "ENOTSUP", ENOTSUP, "Operation not supported");
+#endif
+
+ Py_DECREF(de);
+}
diff --git a/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/expat/expat_external.h b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/expat/expat_external.h new file mode 100644 index 0000000000..8210f416c5 --- /dev/null +++ b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/expat/expat_external.h @@ -0,0 +1,119 @@ +/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+ See the file COPYING for copying permission.
+*/
+
+#ifndef Expat_External_INCLUDED
+#define Expat_External_INCLUDED 1
+
+/* External API definitions */
+
+/* Namespace external symbols to allow multiple libexpat version to
+ co-exist. */
+#include "pyexpatns.h"
+
+#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__)
+#define XML_USE_MSC_EXTENSIONS 1
+#endif
+
+/* Expat tries very hard to make the API boundary very specifically
+ defined. There are two macros defined to control this boundary;
+ each of these can be defined before including this header to
+ achieve some different behavior, but doing so it not recommended or
+ tested frequently.
+
+ XMLCALL - The calling convention to use for all calls across the
+ "library boundary." This will default to cdecl, and
+ try really hard to tell the compiler that's what we
+ want.
+
+ XMLIMPORT - Whatever magic is needed to note that a function is
+ to be imported from a dynamically loaded library
+ (.dll, .so, or .sl, depending on your platform).
+
+ The XMLCALL macro was added in Expat 1.95.7. The only one which is
+ expected to be directly useful in client code is XMLCALL.
+
+ Note that on at least some Unix versions, the Expat library must be
+ compiled with the cdecl calling convention as the default since
+ system headers may assume the cdecl convention.
+*/
+#ifndef XMLCALL
+#if defined(_MSC_VER)
+#define XMLCALL __cdecl
+#elif defined(__GNUC__) && defined(__i386) && !defined(__INTEL_COMPILER)
+#define XMLCALL __attribute__((cdecl))
+#else
+/* For any platform which uses this definition and supports more than
+ one calling convention, we need to extend this definition to
+ declare the convention used on that platform, if it's possible to
+ do so.
+
+ If this is the case for your platform, please file a bug report
+ with information on how to identify your platform via the C
+ pre-processor and how to specify the same calling convention as the
+ platform's malloc() implementation.
+*/
+#define XMLCALL
+#endif
+#endif /* not defined XMLCALL */
+
+
+#if !defined(XML_STATIC) && !defined(XMLIMPORT)
+#ifndef XML_BUILDING_EXPAT
+/* using Expat from an application */
+
+#ifdef XML_USE_MSC_EXTENSIONS
+#define XMLIMPORT __declspec(dllimport)
+#endif
+
+#endif
+#endif /* not defined XML_STATIC */
+
+
+/* If we didn't define it above, define it away: */
+#ifndef XMLIMPORT
+#define XMLIMPORT
+#endif
+
+
+#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef XML_UNICODE_WCHAR_T
+#define XML_UNICODE
+#endif
+
+#ifdef XML_UNICODE /* Information is UTF-16 encoded. */
+#ifdef XML_UNICODE_WCHAR_T
+typedef wchar_t XML_Char;
+typedef wchar_t XML_LChar;
+#else
+typedef unsigned short XML_Char;
+typedef char XML_LChar;
+#endif /* XML_UNICODE_WCHAR_T */
+#else /* Information is UTF-8 encoded. */
+typedef char XML_Char;
+typedef char XML_LChar;
+#endif /* XML_UNICODE */
+
+#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */
+#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400
+typedef __int64 XML_Index;
+typedef unsigned __int64 XML_Size;
+#else
+typedef long long XML_Index;
+typedef unsigned long long XML_Size;
+#endif
+#else
+typedef long XML_Index;
+typedef unsigned long XML_Size;
+#endif /* XML_LARGE_SIZE */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not Expat_External_INCLUDED */
diff --git a/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/getpath.c b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/getpath.c new file mode 100644 index 0000000000..9492864379 --- /dev/null +++ b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/getpath.c @@ -0,0 +1,725 @@ +/** @file
+ Return the initial module search path.
+
+ Search in specified locations for the associated Python libraries.
+
+ Py_GetPath returns module_search_path.
+ Py_GetPrefix returns PREFIX
+ Py_GetExec_Prefix returns PREFIX
+ Py_GetProgramFullPath returns the full path to the python executable.
+
+ These are built dynamically so that the proper volume name can be prefixed
+ to the paths.
+
+ For the EDK II, UEFI, implementation of Python, PREFIX and EXEC_PREFIX
+ are set as follows:
+ PREFIX = /Efi/StdLib
+ EXEC_PREFIX = PREFIX
+
+ The following final paths are assumed:
+ /Efi/Tools/Python.efi The Python executable.
+ /Efi/StdLib/lib/python.VERSION The platform independent Python modules.
+ /Efi/StdLib/lib/python.VERSION/dynalib Dynamically loadable Python extension modules.
+
+ Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include <Python.h>
+#include <osdefs.h>
+#include <ctype.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* VERSION must be at least two characters long. */
+#ifndef VERSION
+ #define VERSION "27"
+#endif
+
+#ifndef VPATH
+ #define VPATH "."
+#endif
+
+/* Search path entry delimiter */
+#ifdef DELIM
+ #define sDELIM ";"
+#endif
+
+#ifndef PREFIX
+ #define PREFIX "/Efi/StdLib"
+#endif
+
+#ifndef EXEC_PREFIX
+ #define EXEC_PREFIX PREFIX
+#endif
+
+#ifndef LIBPYTHON
+ #define LIBPYTHON "lib/python." VERSION
+#endif
+
+#ifndef PYTHONPATH
+ #ifdef HAVE_ENVIRONMENT_OPS
+ #define PYTHONPATH PREFIX LIBPYTHON sDELIM \
+ EXEC_PREFIX LIBPYTHON "/lib-dynload"
+ #else
+ #define PYTHONPATH LIBPYTHON
+ #endif
+#endif
+
+#ifndef LANDMARK
+#define LANDMARK "os.py"
+#endif
+
+static char prefix[MAXPATHLEN+1];
+static char exec_prefix[MAXPATHLEN+1];
+static char progpath[MAXPATHLEN+1];
+static char *module_search_path = NULL;
+static char lib_python[] = LIBPYTHON;
+static char volume_name[32] = { 0 };
+
+/** Determine if "ch" is a separator character.
+
+ @param[in] ch The character to test.
+
+ @retval TRUE ch is a separator character.
+ @retval FALSE ch is NOT a separator character.
+**/
+static int
+is_sep(char ch)
+{
+#ifdef ALTSEP
+ return ch == SEP || ch == ALTSEP;
+#else
+ return ch == SEP;
+#endif
+}
+
+/** Reduce a path by its last element.
+
+ The last element (everything to the right of the last separator character)
+ in the path, dir, is removed from the path. Parameter dir is modified in place.
+
+ @param[in,out] dir Pointer to the path to modify.
+**/
+static void
+reduce(char *dir)
+{
+ size_t i = strlen(dir);
+ while (i > 0 && !is_sep(dir[i]))
+ --i;
+ dir[i] = '\0';
+}
+
+#ifndef UEFI_C_SOURCE
+/** Does filename point to a file and not directory?
+
+ @param[in] filename The fully qualified path to the object to test.
+
+ @retval 0 Filename was not found, or is a directory.
+ @retval 1 Filename refers to a regular file.
+**/
+static int
+isfile(char *filename)
+{
+ struct stat buf;
+ if (stat(filename, &buf) != 0) {
+ return 0;
+ }
+ //if (!S_ISREG(buf.st_mode))
+ if (S_ISDIR(buf.st_mode)) {
+ return 0;
+ }
+ return 1;
+}
+
+/** Determine if filename refers to a Python module.
+
+ A Python module is indicated if the file exists, or if the file with
+ 'o' or 'c' appended exists.
+
+ @param[in] filename The fully qualified path to the object to test.
+
+ @retval 0
+**/
+static int
+ismodule(char *filename)
+{
+ if (isfile(filename)) {
+ //if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: file = \"%s\"\n", __func__, __LINE__, filename);
+ return 1;
+ }
+
+ /* Check for the compiled version of prefix. */
+ if (strlen(filename) < MAXPATHLEN) {
+ strcat(filename, Py_OptimizeFlag ? "o" : "c");
+ if (isfile(filename)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/** Does filename point to a directory?
+
+ @param[in] filename The fully qualified path to the object to test.
+
+ @retval 0 Filename was not found, or is not a regular file.
+ @retval 1 Filename refers to a directory.
+**/
+static int
+isdir(char *filename)
+{
+ struct stat buf;
+
+ if (stat(filename, &buf) != 0)
+ return 0;
+
+ if (!S_ISDIR(buf.st_mode))
+ return 0;
+
+ return 1;
+}
+#endif /* UEFI_C_SOURCE */
+
+/** Determine if a path is absolute, or not.
+ An absolute path consists of a volume name, "VOL:", followed by a rooted path,
+ "/path/elements". If both of these components are present, the path is absolute.
+
+ Let P be a pointer to the path to test.
+ Let A be a pointer to the first ':' in P.
+ Let B be a pointer to the first '/' or '\\' in P.
+
+ If A and B are not NULL
+ If (A-P+1) == (B-P) then the path is absolute.
+ Otherwise, the path is NOT absolute.
+
+ @param[in] path The path to test.
+
+ @retval -1 Path is absolute but lacking volume name.
+ @retval 0 Path is NOT absolute.
+ @retval 1 Path is absolute.
+*/
+static int
+is_absolute(char *path)
+{
+ char *A;
+ char *B;
+
+ A = strchr(path, ':');
+ B = strpbrk(path, "/\\");
+
+ if(B != NULL) {
+ if(A == NULL) {
+ if(B == path) {
+ return -1;
+ }
+ }
+ else {
+ if(((A - path) + 1) == (B - path)) {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+
+/** Add a path component, by appending stuff to buffer.
+ buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a
+ NUL-terminated string with no more than MAXPATHLEN characters (not counting
+ the trailing NUL). It's a fatal error if it contains a string longer than
+ that (callers must be careful!). If these requirements are met, it's
+ guaranteed that buffer will still be a NUL-terminated string with no more
+ than MAXPATHLEN characters at exit. If stuff is too long, only as much of
+ stuff as fits will be appended.
+
+ @param[in,out] buffer The path to be extended.
+ @param[in] stuff The stuff to join onto the path.
+*/
+static void
+joinpath(char *buffer, char *stuff)
+{
+ size_t n, k;
+
+ k = 0;
+ if (is_absolute(stuff) == 1) {
+ n = 0;
+ }
+ else {
+ n = strlen(buffer);
+ if(n == 0) {
+ strncpy(buffer, volume_name, MAXPATHLEN);
+ n = strlen(buffer);
+ }
+ /* We must not use an else clause here because we want to test n again.
+ volume_name may have been empty.
+ */
+ if (n > 0 && n < MAXPATHLEN) {
+ if(!is_sep(buffer[n-1])) {
+ buffer[n++] = SEP;
+ }
+ if(is_sep(stuff[0])) ++stuff;
+ }
+ }
+ if (n > MAXPATHLEN)
+ Py_FatalError("buffer overflow in getpath.c's joinpath()");
+ k = strlen(stuff);
+ if (n + k > MAXPATHLEN)
+ k = MAXPATHLEN - n;
+ strncpy(buffer+n, stuff, k);
+ buffer[n+k] = '\0';
+}
+
+/** Is filename an executable file?
+
+ An executable file:
+ 1) exists
+ 2) is a file, not a directory
+ 3) has a name ending with ".efi"
+ 4) Only has a single '.' in the name.
+
+ If basename(filename) does not contain a '.', append ".efi" to filename
+ If filename ends in ".efi", it is executable, else it isn't.
+
+ This routine is used to when searching for the file named by argv[0].
+ As such, there is no need to search for extensions other than ".efi".
+
+ @param[in] filename The name of the file to test. It may, or may not, have an extension.
+
+ @retval 0 filename already has a path other than ".efi", or it doesn't exist, or is a directory.
+ @retval 1 filename refers to an executable file.
+**/
+static int
+isxfile(char *filename)
+{
+ struct stat buf;
+ char *bn;
+ char *newbn;
+ int bnlen;
+
+ bn = basename(filename); // Separate off the file name component
+ reduce(filename); // and isolate the path component
+ bnlen = strlen(bn);
+ newbn = strrchr(bn, '.'); // Does basename contain a period?
+ if(newbn == NULL) { // Does NOT contain a period.
+ newbn = &bn[bnlen];
+ strncpyX(newbn, ".efi", MAXPATHLEN - bnlen); // append ".efi" to basename
+ bnlen += 4;
+ }
+ else if(strcmp(newbn, ".efi") != 0) {
+ return 0; // File can not be executable.
+ }
+ joinpath(filename, bn); // Stitch path and file name back together
+
+ if (stat(filename, &buf) != 0) { // Now, verify that file exists
+ return 0;
+ }
+ if(S_ISDIR(buf.st_mode)) { // And it is not a directory.
+ return 0;
+ }
+
+ return 1;
+}
+
+/** Copy p into path, ensuring that the result is an absolute path.
+
+ copy_absolute requires that path be allocated at least
+ MAXPATHLEN + 1 bytes and that p be no more than MAXPATHLEN bytes.
+
+ @param[out] path Destination to receive the absolute path.
+ @param[in] p Path to be tested and possibly converted.
+**/
+static void
+copy_absolute(char *path, char *p)
+{
+ if (is_absolute(p) == 1)
+ strcpy(path, p);
+ else {
+ if (!getcwd(path, MAXPATHLEN)) {
+ /* unable to get the current directory */
+ if(volume_name[0] != 0) {
+ strcpy(path, volume_name);
+ joinpath(path, p);
+ }
+ else
+ strcpy(path, p);
+ return;
+ }
+ if (p[0] == '.' && is_sep(p[1]))
+ p += 2;
+ joinpath(path, p);
+ }
+}
+
+/** Modify path so that the result is an absolute path.
+ absolutize() requires that path be allocated at least MAXPATHLEN+1 bytes.
+
+ @param[in,out] path The path to be made absolute.
+*/
+static void
+absolutize(char *path)
+{
+ char buffer[MAXPATHLEN + 1];
+
+ if (is_absolute(path) == 1)
+ return;
+ copy_absolute(buffer, path);
+ strcpy(path, buffer);
+}
+
+/** Extract the volume name from a path.
+
+ @param[out] Dest Pointer to location in which to store the extracted volume name.
+ @param[in] path Pointer to the path to extract the volume name from.
+**/
+static void
+set_volume(char *Dest, char *path)
+{
+ size_t VolLen;
+
+ if(is_absolute(path)) {
+ VolLen = strcspn(path, "/\\:");
+ if((VolLen != 0) && (path[VolLen] == ':')) {
+ (void) strncpyX(Dest, path, VolLen + 1);
+ }
+ }
+}
+
+
+/** Determine paths.
+
+ Two directories must be found, the platform independent directory
+ (prefix), containing the common .py and .pyc files, and the platform
+ dependent directory (exec_prefix), containing the shared library
+ modules. Note that prefix and exec_prefix are the same directory
+ for UEFI installations.
+
+ Separate searches are carried out for prefix and exec_prefix.
+ Each search tries a number of different locations until a ``landmark''
+ file or directory is found. If no prefix or exec_prefix is found, a
+ warning message is issued and the preprocessor defined PREFIX and
+ EXEC_PREFIX are used (even though they may not work); python carries on
+ as best as is possible, but some imports may fail.
+
+ Before any searches are done, the location of the executable is
+ determined. If argv[0] has one or more slashes in it, it is used
+ unchanged. Otherwise, it must have been invoked from the shell's path,
+ so we search %PATH% for the named executable and use that. If the
+ executable was not found on %PATH% (or there was no %PATH% environment
+ variable), the original argv[0] string is used.
+
+ Finally, argv0_path is set to the directory containing the executable
+ (i.e. the last component is stripped).
+
+ With argv0_path in hand, we perform a number of steps. The same steps
+ are performed for prefix and for exec_prefix, but with a different
+ landmark.
+
+ The prefix landmark will always be lib/python.VERSION/os.py and the
+ exec_prefix will always be lib/python.VERSION/dynaload, where VERSION
+ is Python's version number as defined at the beginning of this file.
+
+ First. See if the %PYTHONHOME% environment variable points to the
+ installed location of the Python libraries. If %PYTHONHOME% is set, then
+ it points to prefix and exec_prefix. %PYTHONHOME% can be a single
+ directory, which is used for both, or the prefix and exec_prefix
+ directories separated by the DELIM character.
+
+ Next. Search the directories pointed to by the preprocessor variables
+ PREFIX and EXEC_PREFIX. These paths are prefixed with the volume name
+ extracted from argv0_path. The volume names correspond to the UEFI
+ shell "map" names.
+
+ That's it!
+
+ Well, almost. Once we have determined prefix and exec_prefix, the
+ preprocessor variable PYTHONPATH is used to construct a path. Each
+ relative path on PYTHONPATH is prefixed with prefix. Then the directory
+ containing the shared library modules is appended. The environment
+ variable $PYTHONPATH is inserted in front of it all. Finally, the
+ prefix and exec_prefix globals are tweaked so they reflect the values
+ expected by other code, by stripping the "lib/python$VERSION/..." stuff
+ off. This seems to make more sense given that currently the only
+ known use of sys.prefix and sys.exec_prefix is for the ILU installation
+ process to find the installed Python tree.
+
+ The final, fully resolved, paths should look something like:
+ fs0:/Efi/Tools/python.efi
+ fs0:/Efi/StdLib/lib/python27
+ fs0:/Efi/StdLib/lib/python27/dynaload
+
+**/
+static void
+calculate_path(void)
+{
+ extern char *Py_GetProgramName(void);
+
+ static char delimiter[2] = {DELIM, '\0'};
+ static char separator[2] = {SEP, '\0'};
+ char *pythonpath = PYTHONPATH;
+ char *rtpypath = Py_GETENV("PYTHONPATH");
+ //char *home = Py_GetPythonHome();
+ char *path = getenv("PATH");
+ char *prog = Py_GetProgramName();
+ char argv0_path[MAXPATHLEN+1];
+ char zip_path[MAXPATHLEN+1];
+ char *buf;
+ size_t bufsz;
+ size_t prefixsz;
+ char *defpath;
+
+
+/* ###########################################################################
+ Determine path to the Python.efi binary.
+ Produces progpath, argv0_path, and volume_name.
+########################################################################### */
+
+ /* If there is no slash in the argv0 path, then we have to
+ * assume python is on the user's $PATH, since there's no
+ * other way to find a directory to start the search from. If
+ * $PATH isn't exported, you lose.
+ */
+ if (strchr(prog, SEP))
+ strncpy(progpath, prog, MAXPATHLEN);
+ else if (path) {
+ while (1) {
+ char *delim = strchr(path, DELIM);
+
+ if (delim) {
+ size_t len = delim - path;
+ if (len > MAXPATHLEN)
+ len = MAXPATHLEN;
+ strncpy(progpath, path, len);
+ *(progpath + len) = '\0';
+ }
+ else
+ strncpy(progpath, path, MAXPATHLEN);
+
+ joinpath(progpath, prog);
+ if (isxfile(progpath))
+ break;
+
+ if (!delim) {
+ progpath[0] = '\0';
+ break;
+ }
+ path = delim + 1;
+ }
+ }
+ else
+ progpath[0] = '\0';
+ if ( (!is_absolute(progpath)) && (progpath[0] != '\0') )
+ absolutize(progpath);
+ strncpy(argv0_path, progpath, MAXPATHLEN);
+ argv0_path[MAXPATHLEN] = '\0';
+ set_volume(volume_name, argv0_path);
+
+ reduce(argv0_path);
+ /* At this point, argv0_path is guaranteed to be less than
+ MAXPATHLEN bytes long.
+ */
+
+/* ###########################################################################
+ Build the FULL prefix string, including volume name.
+ This is the full path to the platform independent libraries.
+########################################################################### */
+
+ strncpy(prefix, volume_name, MAXPATHLEN);
+ joinpath(prefix, PREFIX);
+ joinpath(prefix, lib_python);
+
+/* ###########################################################################
+ Build the FULL path to the zipped-up Python library.
+########################################################################### */
+
+ strncpy(zip_path, prefix, MAXPATHLEN);
+ zip_path[MAXPATHLEN] = '\0';
+ reduce(zip_path);
+ joinpath(zip_path, "python00.zip");
+ bufsz = strlen(zip_path); /* Replace "00" with version */
+ zip_path[bufsz - 6] = VERSION[0];
+ zip_path[bufsz - 5] = VERSION[1];
+
+/* ###########################################################################
+ Build the FULL path to dynamically loadable libraries.
+########################################################################### */
+
+ strncpy(exec_prefix, volume_name, MAXPATHLEN);
+ joinpath(exec_prefix, EXEC_PREFIX);
+ joinpath(exec_prefix, lib_python);
+ joinpath(exec_prefix, "lib-dynload");
+
+/* ###########################################################################
+ Build the module search path.
+########################################################################### */
+
+ /* Reduce prefix and exec_prefix to their essence,
+ * e.g. /usr/local/lib/python1.5 is reduced to /usr/local.
+ * If we're loading relative to the build directory,
+ * return the compiled-in defaults instead.
+ */
+ reduce(prefix);
+ reduce(prefix);
+ /* The prefix is the root directory, but reduce() chopped
+ * off the "/". */
+ if (!prefix[0]) {
+ strcpy(prefix, volume_name);
+ }
+ bufsz = strlen(prefix);
+ if(prefix[bufsz-1] == ':') {
+ prefix[bufsz] = SEP;
+ prefix[bufsz+1] = 0;
+ }
+
+ /* Calculate size of return buffer.
+ */
+ defpath = pythonpath;
+ bufsz = 0;
+
+ if (rtpypath)
+ bufsz += strlen(rtpypath) + 1;
+
+ prefixsz = strlen(prefix) + 1;
+
+ while (1) {
+ char *delim = strchr(defpath, DELIM);
+
+ if (is_absolute(defpath) == 0)
+ /* Paths are relative to prefix */
+ bufsz += prefixsz;
+
+ if (delim)
+ bufsz += delim - defpath + 1;
+ else {
+ bufsz += strlen(defpath) + 1;
+ break;
+ }
+ defpath = delim + 1;
+ }
+
+ bufsz += strlen(zip_path) + 1;
+ bufsz += strlen(exec_prefix) + 1;
+
+ /* This is the only malloc call in this file */
+ buf = (char *)PyMem_Malloc(bufsz);
+
+ if (buf == NULL) {
+ /* We can't exit, so print a warning and limp along */
+ fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n");
+ fprintf(stderr, "Using default static PYTHONPATH.\n");
+ module_search_path = PYTHONPATH;
+ }
+ else {
+ /* Run-time value of $PYTHONPATH goes first */
+ if (rtpypath) {
+ strcpy(buf, rtpypath);
+ strcat(buf, delimiter);
+ }
+ else
+ buf[0] = '\0';
+
+ /* Next is the default zip path */
+ strcat(buf, zip_path);
+ strcat(buf, delimiter);
+
+ /* Next goes merge of compile-time $PYTHONPATH with
+ * dynamically located prefix.
+ */
+ defpath = pythonpath;
+ while (1) {
+ char *delim = strchr(defpath, DELIM);
+
+ if (is_absolute(defpath) != 1) {
+ strcat(buf, prefix);
+ strcat(buf, separator);
+ }
+
+ if (delim) {
+ size_t len = delim - defpath + 1;
+ size_t end = strlen(buf) + len;
+ strncat(buf, defpath, len);
+ *(buf + end) = '\0';
+ }
+ else {
+ strcat(buf, defpath);
+ break;
+ }
+ defpath = delim + 1;
+ }
+ strcat(buf, delimiter);
+
+ /* Finally, on goes the directory for dynamic-load modules */
+ strcat(buf, exec_prefix);
+
+ /* And publish the results */
+ module_search_path = buf;
+ }
+ /* At this point, exec_prefix is set to VOL:/Efi/StdLib/lib/python.27/dynalib.
+ We want to get back to the root value, so we have to remove the final three
+ segments to get VOL:/Efi/StdLib. Because we don't know what VOL is, and
+ EXEC_PREFIX is also indeterminate, we just remove the three final segments.
+ */
+ reduce(exec_prefix);
+ reduce(exec_prefix);
+ reduce(exec_prefix);
+ if (!exec_prefix[0]) {
+ strcpy(exec_prefix, volume_name);
+ }
+ bufsz = strlen(exec_prefix);
+ if(exec_prefix[bufsz-1] == ':') {
+ exec_prefix[bufsz] = SEP;
+ exec_prefix[bufsz+1] = 0;
+ }
+ if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: module_search_path = \"%s\"\n", __func__, __LINE__, module_search_path);
+ if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: prefix = \"%s\"\n", __func__, __LINE__, prefix);
+ if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: exec_prefix = \"%s\"\n", __func__, __LINE__, exec_prefix);
+ if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: progpath = \"%s\"\n", __func__, __LINE__, progpath);
+}
+
+
+/* External interface */
+
+char *
+Py_GetPath(void)
+{
+ if (!module_search_path)
+ calculate_path();
+ return module_search_path;
+}
+
+char *
+Py_GetPrefix(void)
+{
+ if (!module_search_path)
+ calculate_path();
+ return prefix;
+}
+
+char *
+Py_GetExecPrefix(void)
+{
+ if (!module_search_path)
+ calculate_path();
+ return exec_prefix;
+}
+
+char *
+Py_GetProgramFullPath(void)
+{
+ if (!module_search_path)
+ calculate_path();
+ return progpath;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/main.c b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/main.c new file mode 100644 index 0000000000..1abed3725a --- /dev/null +++ b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/main.c @@ -0,0 +1,704 @@ +/* Python interpreter main program */
+
+#include "Python.h"
+#include "osdefs.h"
+#include "code.h" /* For CO_FUTURE_DIVISION */
+#include "import.h"
+
+#ifdef __VMS
+#include <unixlib.h>
+#endif
+
+#if defined(MS_WINDOWS) || defined(__CYGWIN__)
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#endif
+
+#if (defined(PYOS_OS2) && !defined(PYCC_GCC)) || defined(MS_WINDOWS)
+#define PYTHONHOMEHELP "<prefix>\\lib"
+#else
+#if defined(PYOS_OS2) && defined(PYCC_GCC)
+#define PYTHONHOMEHELP "<prefix>/Lib"
+#else
+#define PYTHONHOMEHELP "<prefix>/pythonX.X"
+#endif
+#endif
+
+#include "pygetopt.h"
+
+#define COPYRIGHT \
+ "Type \"help\", \"copyright\", \"credits\" or \"license\" " \
+ "for more information."
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For Py_GetArgcArgv(); set by main() */
+static char **orig_argv;
+static int orig_argc;
+
+/* command line options */
+#define BASE_OPTS "3bBc:dEhiJm:OQ:RsStuUvVW:xX?"
+
+#ifndef RISCOS
+#define PROGRAM_OPTS BASE_OPTS
+#else /*RISCOS*/
+/* extra option saying that we are running under a special task window
+ frontend; especially my_readline will behave different */
+#define PROGRAM_OPTS BASE_OPTS "w"
+/* corresponding flag */
+extern int Py_RISCOSWimpFlag;
+#endif /*RISCOS*/
+
+/* Short usage message (with %s for argv0) */
+static char *usage_line =
+"usage: %s [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
+
+/* Long usage message, split into parts < 512 bytes */
+static char *usage_1 = "\
+Options and arguments (and corresponding environment variables):\n\
+-B : don't write .py[co] files on import; also PYTHONDONTWRITEBYTECODE=x\n\
+-c cmd : program passed in as string (terminates option list)\n\
+-d : debug output from parser; also PYTHONDEBUG=x\n\
+-E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\
+-h : print this help message and exit (also --help)\n\
+-i : inspect interactively after running script; forces a prompt even\n\
+";
+static char *usage_2 = "\
+ if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\
+-m mod : run library module as a script (terminates option list)\n\
+-O : optimize generated bytecode slightly; also PYTHONOPTIMIZE=x\n\
+-OO : remove doc-strings in addition to the -O optimizations\n\
+-R : use a pseudo-random salt to make hash() values of various types be\n\
+ unpredictable between separate invocations of the interpreter, as\n\
+ a defense against denial-of-service attacks\n\
+-Q arg : division options: -Qold (default), -Qwarn, -Qwarnall, -Qnew\n\
+-s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
+-S : don't imply 'import site' on initialization\n\
+-t : issue warnings about inconsistent tab usage (-tt: issue errors)\n\
+";
+static char *usage_3 = "\
+-u : unbuffered binary stdout and stderr; also PYTHONUNBUFFERED=x\n\
+ see man page for details on internal buffering relating to '-u'\n\
+-v : verbose (trace import statements); also PYTHONVERBOSE=x\n\
+ can be supplied multiple times to increase verbosity\n\
+-V : print the Python version number and exit (also --version)\n\
+-W arg : warning control; arg is action:message:category:module:lineno\n\
+ also PYTHONWARNINGS=arg\n\
+-x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\
+";
+static char *usage_4 = "\
+-3 : warn about Python 3.x incompatibilities that 2to3 cannot trivially fix\n\
+file : program read from script file\n\
+- : program read from stdin (default; interactive mode if a tty)\n\
+arg ...: arguments passed to program in sys.argv[1:]\n\n\
+Other environment variables:\n\
+PYTHONSTARTUP: file executed on interactive startup (no default)\n\
+PYTHONPATH : '%c'-separated list of directories prefixed to the\n\
+ default module search path. The result is sys.path.\n\
+";
+static char *usage_5 = "\
+PYTHONHOME : alternate <prefix> directory (or <prefix>%c<exec_prefix>).\n\
+ The default module search path uses %s.\n\
+PYTHONCASEOK : ignore case in 'import' statements (Windows).\n\
+PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n\
+";
+static char *usage_6 = "\
+PYTHONHASHSEED: if this variable is set to 'random', the effect is the same\n\
+ as specifying the -R option: a random value is used to seed the hashes of\n\
+ str, bytes and datetime objects. It can also be set to an integer\n\
+ in the range [0,4294967295] to get hash values with a predictable seed.\n\
+";
+
+
+static int
+usage(int exitcode, char* program)
+{
+ FILE *f = exitcode ? stderr : stdout;
+
+ fprintf(f, usage_line, program);
+ if (exitcode)
+ fprintf(f, "Try `python -h' for more information.\n");
+ else {
+ fputs(usage_1, f);
+ fputs(usage_2, f);
+ fputs(usage_3, f);
+ fprintf(f, usage_4, DELIM);
+ fprintf(f, usage_5, DELIM, PYTHONHOMEHELP);
+ fputs(usage_6, f);
+ }
+#if defined(__VMS)
+ if (exitcode == 0) {
+ /* suppress 'error' message */
+ return 1;
+ }
+ else {
+ /* STS$M_INHIB_MSG + SS$_ABORT */
+ return 0x1000002c;
+ }
+#else
+ return exitcode;
+#endif
+ /*NOTREACHED*/
+}
+
+static void RunStartupFile(PyCompilerFlags *cf)
+{
+ char *startup = Py_GETENV("PYTHONSTARTUP");
+ if (startup != NULL && startup[0] != '\0') {
+ FILE *fp = fopen(startup, "r");
+ if (fp != NULL) {
+ (void) PyRun_SimpleFileExFlags(fp, startup, 0, cf);
+ PyErr_Clear();
+ fclose(fp);
+ } else {
+ int save_errno;
+ save_errno = errno;
+ PySys_WriteStderr("Could not open PYTHONSTARTUP\n");
+ errno = save_errno;
+ PyErr_SetFromErrnoWithFilename(PyExc_IOError,
+ startup);
+ PyErr_Print();
+ PyErr_Clear();
+ }
+ }
+}
+
+
+static int RunModule(char *module, int set_argv0)
+{
+ PyObject *runpy, *runmodule, *runargs, *result;
+ runpy = PyImport_ImportModule("runpy");
+ if (runpy == NULL) {
+ fprintf(stderr, "Could not import runpy module\n");
+ return -1;
+ }
+ runmodule = PyObject_GetAttrString(runpy, "_run_module_as_main");
+ if (runmodule == NULL) {
+ fprintf(stderr, "Could not access runpy._run_module_as_main\n");
+ Py_DECREF(runpy);
+ return -1;
+ }
+ runargs = Py_BuildValue("(si)", module, set_argv0);
+ if (runargs == NULL) {
+ fprintf(stderr,
+ "Could not create arguments for runpy._run_module_as_main\n");
+ Py_DECREF(runpy);
+ Py_DECREF(runmodule);
+ return -1;
+ }
+ result = PyObject_Call(runmodule, runargs, NULL);
+ if (result == NULL) {
+ PyErr_Print();
+ }
+ Py_DECREF(runpy);
+ Py_DECREF(runmodule);
+ Py_DECREF(runargs);
+ if (result == NULL) {
+ return -1;
+ }
+ Py_DECREF(result);
+ return 0;
+}
+
+static int RunMainFromImporter(char *filename)
+{
+ PyObject *argv0 = NULL, *importer = NULL;
+
+ if ((argv0 = PyString_FromString(filename)) &&
+ (importer = PyImport_GetImporter(argv0)) &&
+ (importer->ob_type != &PyNullImporter_Type))
+ {
+ /* argv0 is usable as an import source, so
+ put it in sys.path[0] and import __main__ */
+ PyObject *sys_path = NULL;
+ if ((sys_path = PySys_GetObject("path")) &&
+ !PyList_SetItem(sys_path, 0, argv0))
+ {
+ Py_INCREF(argv0);
+ Py_DECREF(importer);
+ sys_path = NULL;
+ return RunModule("__main__", 0) != 0;
+ }
+ }
+ Py_XDECREF(argv0);
+ Py_XDECREF(importer);
+ if (PyErr_Occurred()) {
+ PyErr_Print();
+ return 1;
+ }
+ return -1;
+}
+
+
+/* Main program */
+
+int
+Py_Main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ char *command = NULL;
+ char *filename = NULL;
+ char *module = NULL;
+ FILE *fp = stdin;
+ char *p;
+ int unbuffered = 0;
+ int skipfirstline = 0;
+ int stdin_is_interactive = 0;
+ int help = 0;
+ int version = 0;
+ int saw_unbuffered_flag = 0;
+ PyCompilerFlags cf;
+
+ cf.cf_flags = 0;
+
+ orig_argc = argc; /* For Py_GetArgcArgv() */
+ orig_argv = argv;
+
+#ifdef RISCOS
+ Py_RISCOSWimpFlag = 0;
+#endif
+
+ /* Hash randomization needed early for all string operations
+ (including -W and -X options). */
+ _PyOS_opterr = 0; /* prevent printing the error in 1st pass */
+ while ((c = _PyOS_GetOpt(argc, argv, PROGRAM_OPTS)) != EOF) {
+ if (c == 'm' || c == 'c') {
+ /* -c / -m is the last option: following arguments are
+ not interpreter options. */
+ break;
+ }
+ switch (c) {
+ case 'E':
+ Py_IgnoreEnvironmentFlag++;
+ break;
+ case 'R':
+ Py_HashRandomizationFlag++;
+ break;
+ }
+ }
+ /* The variable is only tested for existence here; _PyRandom_Init will
+ check its value further. */
+ if (!Py_HashRandomizationFlag &&
+ (p = Py_GETENV("PYTHONHASHSEED")) && *p != '\0')
+ Py_HashRandomizationFlag = 1;
+
+ _PyRandom_Init();
+
+ PySys_ResetWarnOptions();
+ _PyOS_ResetGetOpt();
+
+ while ((c = _PyOS_GetOpt(argc, argv, PROGRAM_OPTS)) != EOF) {
+ if (c == 'c') {
+ /* -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);
+ if (command == NULL)
+ Py_FatalError(
+ "not enough memory to copy -c argument");
+ strcpy(command, _PyOS_optarg);
+ strcat(command, "\n");
+ break;
+ }
+
+ if (c == 'm') {
+ /* -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);
+ if (module == NULL)
+ Py_FatalError(
+ "not enough memory to copy -m argument");
+ strcpy(module, _PyOS_optarg);
+ break;
+ }
+
+ switch (c) {
+ case 'b':
+ Py_BytesWarningFlag++;
+ break;
+
+ case 'd':
+ Py_DebugFlag++;
+ break;
+
+ case '3':
+ Py_Py3kWarningFlag++;
+ if (!Py_DivisionWarningFlag)
+ Py_DivisionWarningFlag = 1;
+ break;
+
+ case 'Q':
+ if (strcmp(_PyOS_optarg, "old") == 0) {
+ Py_DivisionWarningFlag = 0;
+ break;
+ }
+ if (strcmp(_PyOS_optarg, "warn") == 0) {
+ Py_DivisionWarningFlag = 1;
+ break;
+ }
+ if (strcmp(_PyOS_optarg, "warnall") == 0) {
+ Py_DivisionWarningFlag = 2;
+ break;
+ }
+ if (strcmp(_PyOS_optarg, "new") == 0) {
+ /* This only affects __main__ */
+ cf.cf_flags |= CO_FUTURE_DIVISION;
+ /* And this tells the eval loop to treat
+ BINARY_DIVIDE as BINARY_TRUE_DIVIDE */
+ _Py_QnewFlag = 1;
+ break;
+ }
+ fprintf(stderr,
+ "-Q option should be `-Qold', "
+ "`-Qwarn', `-Qwarnall', or `-Qnew' only\n");
+ return usage(2, argv[0]);
+ /* NOTREACHED */
+
+ case 'i':
+ Py_InspectFlag++;
+ Py_InteractiveFlag++;
+ break;
+
+ /* case 'J': reserved for Jython */
+
+ case 'O':
+ Py_OptimizeFlag++;
+ break;
+
+ case 'B':
+ Py_DontWriteBytecodeFlag++;
+ break;
+
+ case 's':
+ Py_NoUserSiteDirectory++;
+ break;
+
+ case 'S':
+ Py_NoSiteFlag++;
+ break;
+
+ case 'E':
+ /* Already handled above */
+ break;
+
+ case 't':
+ Py_TabcheckFlag++;
+ break;
+
+ case 'u':
+ unbuffered++;
+ saw_unbuffered_flag = 1;
+ break;
+
+ case 'v':
+ Py_VerboseFlag++;
+ break;
+
+#ifdef RISCOS
+ case 'w':
+ Py_RISCOSWimpFlag = 1;
+ break;
+#endif
+
+ case 'x':
+ skipfirstline = 1;
+ break;
+
+ /* case 'X': reserved for implementation-specific arguments */
+
+ case 'U':
+ Py_UnicodeFlag++;
+ break;
+ case 'h':
+ case '?':
+ help++;
+ break;
+ case 'V':
+ version++;
+ break;
+
+ case 'W':
+ PySys_AddWarnOption(_PyOS_optarg);
+ break;
+
+ case 'R':
+ /* Already handled above */
+ break;
+
+ /* This space reserved for other options */
+
+ default:
+ return usage(2, argv[0]);
+ /*NOTREACHED*/
+
+ }
+ }
+
+ if (help)
+ return usage(0, argv[0]);
+
+ if (version) {
+ fprintf(stderr, "Python %s\n", PY_VERSION);
+ return 0;
+ }
+
+ if (Py_Py3kWarningFlag && !Py_TabcheckFlag)
+ /* -3 implies -t (but not -tt) */
+ Py_TabcheckFlag = 1;
+
+ if (!Py_InspectFlag &&
+ (p = Py_GETENV("PYTHONINSPECT")) && *p != '\0')
+ Py_InspectFlag = 1;
+ if (!saw_unbuffered_flag &&
+ (p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0')
+ unbuffered = 1;
+
+ if (!Py_NoUserSiteDirectory &&
+ (p = Py_GETENV("PYTHONNOUSERSITE")) && *p != '\0')
+ Py_NoUserSiteDirectory = 1;
+
+ if ((p = Py_GETENV("PYTHONWARNINGS")) && *p != '\0') {
+ char *buf, *warning;
+
+ buf = (char *)malloc(strlen(p) + 1);
+ if (buf == NULL)
+ Py_FatalError(
+ "not enough memory to copy PYTHONWARNINGS");
+ strcpy(buf, p);
+ for (warning = strtok(buf, ",");
+ warning != NULL;
+ warning = strtok(NULL, ","))
+ PySys_AddWarnOption(warning);
+ free(buf);
+ }
+
+ if (command == NULL && module == NULL && _PyOS_optind < argc &&
+ strcmp(argv[_PyOS_optind], "-") != 0)
+ {
+#ifdef __VMS
+ filename = decc$translate_vms(argv[_PyOS_optind]);
+ if (filename == (char *)0 || filename == (char *)-1)
+ filename = argv[_PyOS_optind];
+
+#else
+ filename = argv[_PyOS_optind];
+#endif
+ }
+
+ stdin_is_interactive = Py_FdIsInteractive(stdin, (char *)0);
+
+ if (unbuffered) {
+#if defined(MS_WINDOWS) || defined(__CYGWIN__)
+ _setmode(fileno(stdin), O_BINARY);
+ _setmode(fileno(stdout), O_BINARY);
+#endif
+#ifdef HAVE_SETVBUF
+ setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);
+ setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
+ setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);
+#else /* !HAVE_SETVBUF */
+ setbuf(stdin, (char *)NULL);
+ setbuf(stdout, (char *)NULL);
+ setbuf(stderr, (char *)NULL);
+#endif /* !HAVE_SETVBUF */
+ }
+ else if (Py_InteractiveFlag) {
+#ifdef MS_WINDOWS
+ /* Doesn't have to have line-buffered -- use unbuffered */
+ /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */
+ setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);
+#else /* !MS_WINDOWS */
+#ifdef HAVE_SETVBUF
+ setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);
+ setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
+#endif /* HAVE_SETVBUF */
+#endif /* !MS_WINDOWS */
+ /* Leave stderr alone - it should be unbuffered anyway. */
+ }
+#ifdef __VMS
+ else {
+ setvbuf (stdout, (char *)NULL, _IOLBF, BUFSIZ);
+ }
+#endif /* __VMS */
+
+#ifdef __APPLE__
+ /* On MacOS X, when the Python interpreter is embedded in an
+ application bundle, it gets executed by a bootstrapping script
+ that does os.execve() with an argv[0] that's different from the
+ actual Python executable. This is needed to keep the Finder happy,
+ or rather, to work around Apple's overly strict requirements of
+ the process name. However, we still need a usable sys.executable,
+ so the actual executable path is passed in an environment variable.
+ See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
+ script. */
+ if ((p = Py_GETENV("PYTHONEXECUTABLE")) && *p != '\0')
+ Py_SetProgramName(p);
+ else
+ Py_SetProgramName(argv[0]);
+#else
+ Py_SetProgramName(argv[0]);
+#endif
+ Py_Initialize();
+
+ if (Py_VerboseFlag ||
+ (command == NULL && filename == NULL && module == NULL && stdin_is_interactive)) {
+ fprintf(stderr, "Python %s on %s\n",
+ Py_GetVersion(), Py_GetPlatform());
+ if (!Py_NoSiteFlag)
+ fprintf(stderr, "%s\n", COPYRIGHT);
+ }
+
+ if (command != NULL) {
+ /* Backup _PyOS_optind and force sys.argv[0] = '-c' */
+ _PyOS_optind--;
+ argv[_PyOS_optind] = "-c";
+ }
+
+ if (module != NULL) {
+ /* Backup _PyOS_optind and force sys.argv[0] = '-c'
+ so that PySys_SetArgv correctly sets sys.path[0] to ''
+ rather than looking for a file called "-m". See
+ tracker issue #8202 for details. */
+ _PyOS_optind--;
+ argv[_PyOS_optind] = "-c";
+ }
+
+ PySys_SetArgv(argc-_PyOS_optind, argv+_PyOS_optind);
+
+ if ((Py_InspectFlag || (command == NULL && filename == NULL && module == NULL)) &&
+ isatty(fileno(stdin))) {
+ PyObject *v;
+ v = PyImport_ImportModule("readline");
+ if (v == NULL)
+ PyErr_Clear();
+ else
+ Py_DECREF(v);
+ }
+
+ if (command) {
+ sts = PyRun_SimpleStringFlags(command, &cf) != 0;
+ free(command);
+ } else if (module) {
+ sts = (RunModule(module, 1) != 0);
+ free(module);
+ }
+ else {
+
+ if (filename == NULL && stdin_is_interactive) {
+ Py_InspectFlag = 0; /* do exit on SystemExit */
+ RunStartupFile(&cf);
+ }
+ /* XXX */
+
+ sts = -1; /* keep track of whether we've already run __main__ */
+
+ if (filename != NULL) {
+ sts = RunMainFromImporter(filename);
+ }
+
+ if (sts==-1 && filename!=NULL) {
+ if ((fp = fopen(filename, "r")) == NULL) {
+ fprintf(stderr, "%s: can't open file '%s': [Errno %d] %s\n",
+ argv[0], filename, errno, strerror(errno));
+
+ return 2;
+ }
+ else if (skipfirstline) {
+ int ch;
+ /* Push back first newline so line numbers
+ remain the same */
+ while ((ch = getc(fp)) != EOF) {
+ if (ch == '\n') {
+ (void)ungetc(ch, fp);
+ break;
+ }
+ }
+ }
+ {
+ /* XXX: does this work on Win/Win64? (see posix_fstat) */
+ 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);
+ fclose(fp);
+ return 1;
+ }
+ }
+ }
+
+ if (sts==-1) {
+ /* call pending calls like signal handlers (SIGINT) */
+ if (Py_MakePendingCalls() == -1) {
+ PyErr_Print();
+ sts = 1;
+ } else {
+ sts = PyRun_AnyFileExFlags(
+ fp,
+ filename == NULL ? "<stdin>" : filename,
+ filename != NULL, &cf) != 0;
+ }
+ }
+
+ }
+
+ /* Check this environment variable at the end, to give programs the
+ * opportunity to set it from Python.
+ */
+ if (!Py_InspectFlag &&
+ (p = Py_GETENV("PYTHONINSPECT")) && *p != '\0')
+ {
+ Py_InspectFlag = 1;
+ }
+
+ if (Py_InspectFlag && stdin_is_interactive &&
+ (filename != NULL || command != NULL || module != NULL)) {
+ Py_InspectFlag = 0;
+ /* XXX */
+ sts = PyRun_AnyFileFlags(stdin, "<stdin>", &cf) != 0;
+ }
+
+ Py_Finalize();
+#ifdef RISCOS
+ if (Py_RISCOSWimpFlag)
+ fprintf(stderr, "\x0cq\x0c"); /* make frontend quit */
+#endif
+
+#ifdef __INSURE__
+ /* Insure++ is a memory analysis tool that aids in discovering
+ * memory leaks and other memory problems. On Python exit, the
+ * interned string dictionary is flagged as being in use at exit
+ * (which it is). Under normal circumstances, this is fine because
+ * the memory will be automatically reclaimed by the system. Under
+ * memory debugging, it's a huge source of useless noise, so we
+ * trade off slower shutdown for less distraction in the memory
+ * reports. -baw
+ */
+ _Py_ReleaseInternedStrings();
+#endif /* __INSURE__ */
+
+ return sts;
+}
+
+/* this is gonna seem *real weird*, but if you put some other code between
+ Py_Main() and Py_GetArgcArgv() you will need to adjust the test in the
+ while statement in Misc/gdbinit:ppystack */
+
+/* Make the *original* argc/argv available to other modules.
+ This is rare, but it is needed by the secureware extension. */
+
+void
+Py_GetArgcArgv(int *argc, char ***argv)
+{
+ *argc = orig_argc;
+ *argv = orig_argv;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/selectmodule.c b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/selectmodule.c new file mode 100644 index 0000000000..29e9d97671 --- /dev/null +++ b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/selectmodule.c @@ -0,0 +1,1956 @@ +/* select - Module containing unix select(2) call.
+ Under Unix, the file descriptors are small integers.
+ Under Win32, select only exists for sockets, and sockets may
+ have any value except INVALID_SOCKET.
+ Under BeOS, we suffer the same dichotomy as Win32; sockets can be anything
+ >= 0.
+*/
+
+#include "Python.h"
+#include <structmember.h>
+
+#ifdef __APPLE__
+ /* Perform runtime testing for a broken poll on OSX to make it easier
+ * to use the same binary on multiple releases of the OS.
+ */
+#undef HAVE_BROKEN_POLL
+#endif
+
+/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
+ 64 is too small (too many people have bumped into that limit).
+ Here we boost it.
+ Users who want even more than the boosted limit should #define
+ FD_SETSIZE higher before this; e.g., via compiler /D switch.
+*/
+#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
+#define FD_SETSIZE 512
+#endif
+
+#if defined(HAVE_POLL_H)
+#include <poll.h>
+#elif defined(HAVE_SYS_POLL_H)
+#include <sys/poll.h>
+#endif
+
+#ifdef __sgi
+/* This is missing from unistd.h */
+extern void bzero(void *, int);
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#if defined(PYOS_OS2) && !defined(PYCC_GCC)
+#include <sys/time.h>
+#include <utils.h>
+#endif
+
+#ifdef MS_WINDOWS
+# include <winsock2.h>
+#else
+# define SOCKET int
+# ifdef __BEOS__
+# include <net/socket.h>
+# elif defined(__VMS)
+# include <socket.h>
+# endif
+#endif
+
+static PyObject *SelectError;
+
+/* list of Python objects and their file descriptor */
+typedef struct {
+ PyObject *obj; /* owned reference */
+ SOCKET fd;
+ int sentinel; /* -1 == sentinel */
+} pylist;
+
+static void
+reap_obj(pylist fd2obj[FD_SETSIZE + 1])
+{
+ int i;
+ for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {
+ Py_CLEAR(fd2obj[i].obj);
+ }
+ fd2obj[0].sentinel = -1;
+}
+
+
+/* returns -1 and sets the Python exception if an error occurred, otherwise
+ returns a number >= 0
+*/
+static int
+seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
+{
+ int i;
+ int max = -1;
+ int index = 0;
+ PyObject* fast_seq = NULL;
+ PyObject* o = NULL;
+
+ fd2obj[0].obj = (PyObject*)0; /* set list to zero size */
+ FD_ZERO(set);
+
+ fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");
+ if (!fast_seq)
+ return -1;
+
+ for (i = 0; i < PySequence_Fast_GET_SIZE(fast_seq); i++) {
+ SOCKET v;
+
+ /* any intervening fileno() calls could decr this refcnt */
+ if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))
+ return -1;
+
+ Py_INCREF(o);
+ v = PyObject_AsFileDescriptor( o );
+ if (v == -1) goto finally;
+
+#if defined(_MSC_VER)
+ max = 0; /* not used for Win32 */
+#else /* !_MSC_VER */
+ if (!_PyIsSelectable_fd(v)) {
+ PyErr_SetString(PyExc_ValueError,
+ "filedescriptor out of range in select()");
+ goto finally;
+ }
+ if (v > max)
+ max = v;
+#endif /* _MSC_VER */
+ FD_SET(v, set);
+
+ /* add object and its file descriptor to the list */
+ if (index >= FD_SETSIZE) {
+ PyErr_SetString(PyExc_ValueError,
+ "too many file descriptors in select()");
+ goto finally;
+ }
+ fd2obj[index].obj = o;
+ fd2obj[index].fd = v;
+ fd2obj[index].sentinel = 0;
+ fd2obj[++index].sentinel = -1;
+ }
+ Py_DECREF(fast_seq);
+ return max+1;
+
+ finally:
+ Py_XDECREF(o);
+ Py_DECREF(fast_seq);
+ return -1;
+}
+
+/* returns NULL and sets the Python exception if an error occurred */
+static PyObject *
+set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])
+{
+ int i, j, count=0;
+ PyObject *list, *o;
+ SOCKET fd;
+
+ for (j = 0; fd2obj[j].sentinel >= 0; j++) {
+ if (FD_ISSET(fd2obj[j].fd, set))
+ count++;
+ }
+ list = PyList_New(count);
+ if (!list)
+ return NULL;
+
+ i = 0;
+ for (j = 0; fd2obj[j].sentinel >= 0; j++) {
+ fd = fd2obj[j].fd;
+ if (FD_ISSET(fd, set)) {
+ o = fd2obj[j].obj;
+ fd2obj[j].obj = NULL;
+ /* transfer ownership */
+ if (PyList_SetItem(list, i, o) < 0)
+ goto finally;
+
+ i++;
+ }
+ }
+ return list;
+ finally:
+ Py_DECREF(list);
+ return NULL;
+}
+
+#undef SELECT_USES_HEAP
+#if FD_SETSIZE > 1024
+#define SELECT_USES_HEAP
+#endif /* FD_SETSIZE > 1024 */
+
+static PyObject *
+select_select(PyObject *self, PyObject *args)
+{
+#ifdef SELECT_USES_HEAP
+ pylist *rfd2obj, *wfd2obj, *efd2obj;
+#else /* !SELECT_USES_HEAP */
+ /* XXX: All this should probably be implemented as follows:
+ * - find the highest descriptor we're interested in
+ * - add one
+ * - that's the size
+ * See: Stevens, APitUE, $12.5.1
+ */
+ pylist rfd2obj[FD_SETSIZE + 1];
+ pylist wfd2obj[FD_SETSIZE + 1];
+ pylist efd2obj[FD_SETSIZE + 1];
+#endif /* SELECT_USES_HEAP */
+ PyObject *ifdlist, *ofdlist, *efdlist;
+ PyObject *ret = NULL;
+ PyObject *tout = Py_None;
+ fd_set ifdset, ofdset, efdset;
+ double timeout;
+ struct timeval tv, *tvp;
+ long seconds;
+ int imax, omax, emax, max;
+ int n;
+
+ /* convert arguments */
+ if (!PyArg_UnpackTuple(args, "select", 3, 4,
+ &ifdlist, &ofdlist, &efdlist, &tout))
+ return NULL;
+
+ if (tout == Py_None)
+ tvp = (struct timeval *)0;
+ else if (!PyNumber_Check(tout)) {
+ PyErr_SetString(PyExc_TypeError,
+ "timeout must be a float or None");
+ return NULL;
+ }
+ else {
+ timeout = PyFloat_AsDouble(tout);
+ if (timeout == -1 && PyErr_Occurred())
+ return NULL;
+ if (timeout > (double)LONG_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "timeout period too long");
+ return NULL;
+ }
+ seconds = (long)timeout;
+ timeout = timeout - (double)seconds;
+ tv.tv_sec = seconds;
+ tv.tv_usec = (long)(timeout * 1E6);
+ tvp = &tv;
+ }
+
+
+#ifdef SELECT_USES_HEAP
+ /* Allocate memory for the lists */
+ rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
+ wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
+ efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);
+ if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {
+ if (rfd2obj) PyMem_DEL(rfd2obj);
+ if (wfd2obj) PyMem_DEL(wfd2obj);
+ if (efd2obj) PyMem_DEL(efd2obj);
+ return PyErr_NoMemory();
+ }
+#endif /* SELECT_USES_HEAP */
+ /* Convert sequences to fd_sets, and get maximum fd number
+ * propagates the Python exception set in seq2set()
+ */
+ rfd2obj[0].sentinel = -1;
+ wfd2obj[0].sentinel = -1;
+ efd2obj[0].sentinel = -1;
+ if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)
+ goto finally;
+ if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)
+ goto finally;
+ if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)
+ goto finally;
+ max = imax;
+ if (omax > max) max = omax;
+ if (emax > max) max = emax;
+
+ Py_BEGIN_ALLOW_THREADS
+ n = select(max, &ifdset, &ofdset, &efdset, tvp);
+ Py_END_ALLOW_THREADS
+
+#ifdef MS_WINDOWS
+ if (n == SOCKET_ERROR) {
+ PyErr_SetExcFromWindowsErr(SelectError, WSAGetLastError());
+ }
+#else
+ if (n < 0) {
+ PyErr_SetFromErrno(SelectError);
+ }
+#endif
+ else {
+ /* any of these three calls can raise an exception. it's more
+ convenient to test for this after all three calls... but
+ is that acceptable?
+ */
+ ifdlist = set2list(&ifdset, rfd2obj);
+ ofdlist = set2list(&ofdset, wfd2obj);
+ efdlist = set2list(&efdset, efd2obj);
+ if (PyErr_Occurred())
+ ret = NULL;
+ else
+ ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);
+
+ Py_DECREF(ifdlist);
+ Py_DECREF(ofdlist);
+ Py_DECREF(efdlist);
+ }
+
+ finally:
+ reap_obj(rfd2obj);
+ reap_obj(wfd2obj);
+ reap_obj(efd2obj);
+#ifdef SELECT_USES_HEAP
+ PyMem_DEL(rfd2obj);
+ PyMem_DEL(wfd2obj);
+ PyMem_DEL(efd2obj);
+#endif /* SELECT_USES_HEAP */
+ return ret;
+}
+
+#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
+/*
+ * poll() support
+ */
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *dict;
+ int ufd_uptodate;
+ int ufd_len;
+ struct pollfd *ufds;
+ int poll_running;
+} pollObject;
+
+static PyTypeObject poll_Type;
+
+/* Update the malloc'ed array of pollfds to match the dictionary
+ contained within a pollObject. Return 1 on success, 0 on an error.
+*/
+
+static int
+update_ufd_array(pollObject *self)
+{
+ Py_ssize_t i, pos;
+ PyObject *key, *value;
+ struct pollfd *old_ufds = self->ufds;
+
+ self->ufd_len = PyDict_Size(self->dict);
+ PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
+ if (self->ufds == NULL) {
+ self->ufds = old_ufds;
+ PyErr_NoMemory();
+ return 0;
+ }
+
+ i = pos = 0;
+ while (PyDict_Next(self->dict, &pos, &key, &value)) {
+ assert(i < self->ufd_len);
+ /* Never overflow */
+ self->ufds[i].fd = (int)PyInt_AsLong(key);
+ self->ufds[i].events = (short)(unsigned short)PyInt_AsLong(value);
+ i++;
+ }
+ assert(i == self->ufd_len);
+ self->ufd_uptodate = 1;
+ return 1;
+}
+
+static int
+ushort_converter(PyObject *obj, void *ptr)
+{
+ unsigned long uval;
+
+ uval = PyLong_AsUnsignedLong(obj);
+ if (uval == (unsigned long)-1 && PyErr_Occurred())
+ return 0;
+ if (uval > USHRT_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "Python int too large for C unsigned short");
+ return 0;
+ }
+
+ *(unsigned short *)ptr = Py_SAFE_DOWNCAST(uval, unsigned long, unsigned short);
+ return 1;
+}
+
+PyDoc_STRVAR(poll_register_doc,
+"register(fd [, eventmask] ) -> None\n\n\
+Register a file descriptor with the polling object.\n\
+fd -- either an integer, or an object with a fileno() method returning an\n\
+ int.\n\
+events -- an optional bitmask describing the type of events to check for");
+
+static PyObject *
+poll_register(pollObject *self, PyObject *args)
+{
+ PyObject *o, *key, *value;
+ int fd;
+ unsigned short events = POLLIN | POLLPRI | POLLOUT;
+ int err;
+
+ if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events))
+ return NULL;
+
+ fd = PyObject_AsFileDescriptor(o);
+ if (fd == -1) return NULL;
+
+ /* Add entry to the internal dictionary: the key is the
+ file descriptor, and the value is the event mask. */
+ key = PyInt_FromLong(fd);
+ if (key == NULL)
+ return NULL;
+ value = PyInt_FromLong(events);
+ if (value == NULL) {
+ Py_DECREF(key);
+ return NULL;
+ }
+ err = PyDict_SetItem(self->dict, key, value);
+ Py_DECREF(key);
+ Py_DECREF(value);
+ if (err < 0)
+ return NULL;
+
+ self->ufd_uptodate = 0;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(poll_modify_doc,
+"modify(fd, eventmask) -> None\n\n\
+Modify an already registered file descriptor.\n\
+fd -- either an integer, or an object with a fileno() method returning an\n\
+ int.\n\
+events -- an optional bitmask describing the type of events to check for");
+
+static PyObject *
+poll_modify(pollObject *self, PyObject *args)
+{
+ PyObject *o, *key, *value;
+ int fd;
+ unsigned short events;
+ int err;
+
+ if (!PyArg_ParseTuple(args, "OO&:modify", &o, ushort_converter, &events))
+ return NULL;
+
+ fd = PyObject_AsFileDescriptor(o);
+ if (fd == -1) return NULL;
+
+ /* Modify registered fd */
+ key = PyInt_FromLong(fd);
+ if (key == NULL)
+ return NULL;
+ if (PyDict_GetItem(self->dict, key) == NULL) {
+ errno = ENOENT;
+ PyErr_SetFromErrno(PyExc_IOError);
+ return NULL;
+ }
+ value = PyInt_FromLong(events);
+ if (value == NULL) {
+ Py_DECREF(key);
+ return NULL;
+ }
+ err = PyDict_SetItem(self->dict, key, value);
+ Py_DECREF(key);
+ Py_DECREF(value);
+ if (err < 0)
+ return NULL;
+
+ self->ufd_uptodate = 0;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+PyDoc_STRVAR(poll_unregister_doc,
+"unregister(fd) -> None\n\n\
+Remove a file descriptor being tracked by the polling object.");
+
+static PyObject *
+poll_unregister(pollObject *self, PyObject *o)
+{
+ PyObject *key;
+ int fd;
+
+ fd = PyObject_AsFileDescriptor( o );
+ if (fd == -1)
+ return NULL;
+
+ /* Check whether the fd is already in the array */
+ key = PyInt_FromLong(fd);
+ if (key == NULL)
+ return NULL;
+
+ if (PyDict_DelItem(self->dict, key) == -1) {
+ Py_DECREF(key);
+ /* This will simply raise the KeyError set by PyDict_DelItem
+ if the file descriptor isn't registered. */
+ return NULL;
+ }
+
+ Py_DECREF(key);
+ self->ufd_uptodate = 0;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(poll_poll_doc,
+"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\
+Polls the set of registered file descriptors, returning a list containing \n\
+any descriptors that have events or errors to report.");
+
+static PyObject *
+poll_poll(pollObject *self, PyObject *args)
+{
+ PyObject *result_list = NULL, *tout = NULL;
+ int timeout = 0, poll_result, i, j;
+ PyObject *value = NULL, *num = NULL;
+
+ if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
+ return NULL;
+ }
+
+ /* Check values for timeout */
+ if (tout == NULL || tout == Py_None)
+ timeout = -1;
+ else if (!PyNumber_Check(tout)) {
+ PyErr_SetString(PyExc_TypeError,
+ "timeout must be an integer or None");
+ return NULL;
+ }
+ else {
+ tout = PyNumber_Int(tout);
+ if (!tout)
+ return NULL;
+ timeout = _PyInt_AsInt(tout);
+ Py_DECREF(tout);
+ if (timeout == -1 && PyErr_Occurred())
+ return NULL;
+ }
+
+ /* Avoid concurrent poll() invocation, issue 8865 */
+ if (self->poll_running) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "concurrent poll() invocation");
+ return NULL;
+ }
+
+ /* Ensure the ufd array is up to date */
+ if (!self->ufd_uptodate)
+ if (update_ufd_array(self) == 0)
+ return NULL;
+
+ self->poll_running = 1;
+
+ /* call poll() */
+ Py_BEGIN_ALLOW_THREADS
+ poll_result = poll(self->ufds, self->ufd_len, timeout);
+ Py_END_ALLOW_THREADS
+
+ self->poll_running = 0;
+
+ if (poll_result < 0) {
+ PyErr_SetFromErrno(SelectError);
+ return NULL;
+ }
+
+ /* build the result list */
+
+ result_list = PyList_New(poll_result);
+ if (!result_list)
+ return NULL;
+ else {
+ for (i = 0, j = 0; j < poll_result; j++) {
+ /* skip to the next fired descriptor */
+ while (!self->ufds[i].revents) {
+ i++;
+ }
+ /* if we hit a NULL return, set value to NULL
+ and break out of loop; code at end will
+ clean up result_list */
+ value = PyTuple_New(2);
+ if (value == NULL)
+ goto error;
+ num = PyInt_FromLong(self->ufds[i].fd);
+ if (num == NULL) {
+ Py_DECREF(value);
+ goto error;
+ }
+ PyTuple_SET_ITEM(value, 0, num);
+
+ /* The &0xffff is a workaround for AIX. 'revents'
+ is a 16-bit short, and IBM assigned POLLNVAL
+ to be 0x8000, so the conversion to int results
+ in a negative number. See SF bug #923315. */
+ num = PyInt_FromLong(self->ufds[i].revents & 0xffff);
+ if (num == NULL) {
+ Py_DECREF(value);
+ goto error;
+ }
+ PyTuple_SET_ITEM(value, 1, num);
+ if ((PyList_SetItem(result_list, j, value)) == -1) {
+ Py_DECREF(value);
+ goto error;
+ }
+ i++;
+ }
+ }
+ return result_list;
+
+ error:
+ Py_DECREF(result_list);
+ return NULL;
+}
+
+static PyMethodDef poll_methods[] = {
+ {"register", (PyCFunction)poll_register,
+ METH_VARARGS, poll_register_doc},
+ {"modify", (PyCFunction)poll_modify,
+ METH_VARARGS, poll_modify_doc},
+ {"unregister", (PyCFunction)poll_unregister,
+ METH_O, poll_unregister_doc},
+ {"poll", (PyCFunction)poll_poll,
+ METH_VARARGS, poll_poll_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+static pollObject *
+newPollObject(void)
+{
+ pollObject *self;
+ self = PyObject_New(pollObject, &poll_Type);
+ if (self == NULL)
+ return NULL;
+ /* ufd_uptodate is a Boolean, denoting whether the
+ array pointed to by ufds matches the contents of the dictionary. */
+ self->ufd_uptodate = 0;
+ self->ufds = NULL;
+ self->poll_running = 0;
+ self->dict = PyDict_New();
+ if (self->dict == NULL) {
+ Py_DECREF(self);
+ return NULL;
+ }
+ return self;
+}
+
+static void
+poll_dealloc(pollObject *self)
+{
+ if (self->ufds != NULL)
+ PyMem_DEL(self->ufds);
+ Py_XDECREF(self->dict);
+ PyObject_Del(self);
+}
+
+static PyObject *
+poll_getattr(pollObject *self, char *name)
+{
+ return Py_FindMethod(poll_methods, (PyObject *)self, name);
+}
+
+static PyTypeObject poll_Type = {
+ /* The ob_type field must be initialized in the module init function
+ * to be portable to Windows without using C++. */
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "select.poll", /*tp_name*/
+ sizeof(pollObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)poll_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)poll_getattr, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+};
+
+PyDoc_STRVAR(poll_doc,
+"Returns a polling object, which supports registering and\n\
+unregistering file descriptors, and then polling them for I/O events.");
+
+static PyObject *
+select_poll(PyObject *self, PyObject *unused)
+{
+ return (PyObject *)newPollObject();
+}
+
+#ifdef __APPLE__
+/*
+ * On some systems poll() sets errno on invalid file descriptors. We test
+ * for this at runtime because this bug may be fixed or introduced between
+ * OS releases.
+ */
+static int select_have_broken_poll(void)
+{
+ int poll_test;
+ int filedes[2];
+
+ struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
+
+ /* Create a file descriptor to make invalid */
+ if (pipe(filedes) < 0) {
+ return 1;
+ }
+ poll_struct.fd = filedes[0];
+ close(filedes[0]);
+ close(filedes[1]);
+ poll_test = poll(&poll_struct, 1, 0);
+ if (poll_test < 0) {
+ return 1;
+ } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
+ return 1;
+ }
+ return 0;
+}
+#endif /* __APPLE__ */
+
+#endif /* HAVE_POLL */
+
+#ifdef HAVE_EPOLL
+/* **************************************************************************
+ * epoll interface for Linux 2.6
+ *
+ * Written by Christian Heimes
+ * Inspired by Twisted's _epoll.pyx and select.poll()
+ */
+
+#ifdef HAVE_SYS_EPOLL_H
+#include <sys/epoll.h>
+#endif
+
+typedef struct {
+ PyObject_HEAD
+ SOCKET epfd; /* epoll control file descriptor */
+} pyEpoll_Object;
+
+static PyTypeObject pyEpoll_Type;
+#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))
+
+static PyObject *
+pyepoll_err_closed(void)
+{
+ PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");
+ return NULL;
+}
+
+static int
+pyepoll_internal_close(pyEpoll_Object *self)
+{
+ int save_errno = 0;
+ if (self->epfd >= 0) {
+ int epfd = self->epfd;
+ self->epfd = -1;
+ Py_BEGIN_ALLOW_THREADS
+ if (close(epfd) < 0)
+ save_errno = errno;
+ Py_END_ALLOW_THREADS
+ }
+ return save_errno;
+}
+
+static PyObject *
+newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)
+{
+ pyEpoll_Object *self;
+
+ if (sizehint == -1) {
+ sizehint = FD_SETSIZE-1;
+ }
+ else if (sizehint < 1) {
+ PyErr_Format(PyExc_ValueError,
+ "sizehint must be greater zero, got %d",
+ sizehint);
+ return NULL;
+ }
+
+ assert(type != NULL && type->tp_alloc != NULL);
+ self = (pyEpoll_Object *) type->tp_alloc(type, 0);
+ if (self == NULL)
+ return NULL;
+
+ if (fd == -1) {
+ Py_BEGIN_ALLOW_THREADS
+ self->epfd = epoll_create(sizehint);
+ Py_END_ALLOW_THREADS
+ }
+ else {
+ self->epfd = fd;
+ }
+ if (self->epfd < 0) {
+ Py_DECREF(self);
+ PyErr_SetFromErrno(PyExc_IOError);
+ return NULL;
+ }
+ return (PyObject *)self;
+}
+
+
+static PyObject *
+pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ int sizehint = -1;
+ static char *kwlist[] = {"sizehint", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:epoll", kwlist,
+ &sizehint))
+ return NULL;
+
+ return newPyEpoll_Object(type, sizehint, -1);
+}
+
+
+static void
+pyepoll_dealloc(pyEpoll_Object *self)
+{
+ (void)pyepoll_internal_close(self);
+ Py_TYPE(self)->tp_free(self);
+}
+
+static PyObject*
+pyepoll_close(pyEpoll_Object *self)
+{
+ errno = pyepoll_internal_close(self);
+ if (errno < 0) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(pyepoll_close_doc,
+"close() -> None\n\
+\n\
+Close the epoll control file descriptor. Further operations on the epoll\n\
+object will raise an exception.");
+
+static PyObject*
+pyepoll_get_closed(pyEpoll_Object *self)
+{
+ if (self->epfd < 0)
+ Py_RETURN_TRUE;
+ else
+ Py_RETURN_FALSE;
+}
+
+static PyObject*
+pyepoll_fileno(pyEpoll_Object *self)
+{
+ if (self->epfd < 0)
+ return pyepoll_err_closed();
+ return PyInt_FromLong(self->epfd);
+}
+
+PyDoc_STRVAR(pyepoll_fileno_doc,
+"fileno() -> int\n\
+\n\
+Return the epoll control file descriptor.");
+
+static PyObject*
+pyepoll_fromfd(PyObject *cls, PyObject *args)
+{
+ SOCKET fd;
+
+ if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
+ return NULL;
+
+ return newPyEpoll_Object((PyTypeObject*)cls, -1, fd);
+}
+
+PyDoc_STRVAR(pyepoll_fromfd_doc,
+"fromfd(fd) -> epoll\n\
+\n\
+Create an epoll object from a given control fd.");
+
+static PyObject *
+pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)
+{
+ struct epoll_event ev;
+ int result;
+ int fd;
+
+ if (epfd < 0)
+ return pyepoll_err_closed();
+
+ fd = PyObject_AsFileDescriptor(pfd);
+ if (fd == -1) {
+ return NULL;
+ }
+
+ switch(op) {
+ case EPOLL_CTL_ADD:
+ case EPOLL_CTL_MOD:
+ ev.events = events;
+ ev.data.fd = fd;
+ Py_BEGIN_ALLOW_THREADS
+ result = epoll_ctl(epfd, op, fd, &ev);
+ Py_END_ALLOW_THREADS
+ break;
+ case EPOLL_CTL_DEL:
+ /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL
+ * operation required a non-NULL pointer in event, even
+ * though this argument is ignored. */
+ Py_BEGIN_ALLOW_THREADS
+ result = epoll_ctl(epfd, op, fd, &ev);
+ if (errno == EBADF) {
+ /* fd already closed */
+ result = 0;
+ errno = 0;
+ }
+ Py_END_ALLOW_THREADS
+ break;
+ default:
+ result = -1;
+ errno = EINVAL;
+ }
+
+ if (result < 0) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+static PyObject *
+pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
+{
+ PyObject *pfd;
+ unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;
+ static char *kwlist[] = {"fd", "eventmask", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,
+ &pfd, &events)) {
+ return NULL;
+ }
+
+ return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);
+}
+
+PyDoc_STRVAR(pyepoll_register_doc,
+"register(fd[, eventmask]) -> None\n\
+\n\
+Registers a new fd or raises an IOError if the fd is already registered.\n\
+fd is the target file descriptor of the operation.\n\
+events is a bit set composed of the various EPOLL constants; the default\n\
+is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\
+\n\
+The epoll interface supports all file descriptors that support poll.");
+
+static PyObject *
+pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
+{
+ PyObject *pfd;
+ unsigned int events;
+ static char *kwlist[] = {"fd", "eventmask", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,
+ &pfd, &events)) {
+ return NULL;
+ }
+
+ return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);
+}
+
+PyDoc_STRVAR(pyepoll_modify_doc,
+"modify(fd, eventmask) -> None\n\
+\n\
+fd is the target file descriptor of the operation\n\
+events is a bit set composed of the various EPOLL constants");
+
+static PyObject *
+pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
+{
+ PyObject *pfd;
+ static char *kwlist[] = {"fd", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,
+ &pfd)) {
+ return NULL;
+ }
+
+ return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);
+}
+
+PyDoc_STRVAR(pyepoll_unregister_doc,
+"unregister(fd) -> None\n\
+\n\
+fd is the target file descriptor of the operation.");
+
+static PyObject *
+pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)
+{
+ double dtimeout = -1.;
+ int timeout;
+ int maxevents = -1;
+ int nfds, i;
+ PyObject *elist = NULL, *etuple = NULL;
+ struct epoll_event *evs = NULL;
+ static char *kwlist[] = {"timeout", "maxevents", NULL};
+
+ if (self->epfd < 0)
+ return pyepoll_err_closed();
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,
+ &dtimeout, &maxevents)) {
+ return NULL;
+ }
+
+ if (dtimeout < 0) {
+ timeout = -1;
+ }
+ else if (dtimeout * 1000.0 > INT_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "timeout is too large");
+ return NULL;
+ }
+ else {
+ timeout = (int)(dtimeout * 1000.0);
+ }
+
+ if (maxevents == -1) {
+ maxevents = FD_SETSIZE-1;
+ }
+ else if (maxevents < 1) {
+ PyErr_Format(PyExc_ValueError,
+ "maxevents must be greater than 0, got %d",
+ maxevents);
+ return NULL;
+ }
+
+ evs = PyMem_New(struct epoll_event, maxevents);
+ if (evs == NULL) {
+ Py_DECREF(self);
+ PyErr_NoMemory();
+ return NULL;
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ nfds = epoll_wait(self->epfd, evs, maxevents, timeout);
+ Py_END_ALLOW_THREADS
+ if (nfds < 0) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ goto error;
+ }
+
+ elist = PyList_New(nfds);
+ if (elist == NULL) {
+ goto error;
+ }
+
+ for (i = 0; i < nfds; i++) {
+ etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);
+ if (etuple == NULL) {
+ Py_CLEAR(elist);
+ goto error;
+ }
+ PyList_SET_ITEM(elist, i, etuple);
+ }
+
+ error:
+ PyMem_Free(evs);
+ return elist;
+}
+
+PyDoc_STRVAR(pyepoll_poll_doc,
+"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\
+\n\
+Wait for events on the epoll file descriptor for a maximum time of timeout\n\
+in seconds (as float). -1 makes poll wait indefinitely.\n\
+Up to maxevents are returned to the caller.");
+
+static PyMethodDef pyepoll_methods[] = {
+ {"fromfd", (PyCFunction)pyepoll_fromfd,
+ METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},
+ {"close", (PyCFunction)pyepoll_close, METH_NOARGS,
+ pyepoll_close_doc},
+ {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,
+ pyepoll_fileno_doc},
+ {"modify", (PyCFunction)pyepoll_modify,
+ METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},
+ {"register", (PyCFunction)pyepoll_register,
+ METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},
+ {"unregister", (PyCFunction)pyepoll_unregister,
+ METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},
+ {"poll", (PyCFunction)pyepoll_poll,
+ METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},
+ {NULL, NULL},
+};
+
+static PyGetSetDef pyepoll_getsetlist[] = {
+ {"closed", (getter)pyepoll_get_closed, NULL,
+ "True if the epoll handler is closed"},
+ {0},
+};
+
+PyDoc_STRVAR(pyepoll_doc,
+"select.epoll([sizehint=-1])\n\
+\n\
+Returns an epolling object\n\
+\n\
+sizehint must be a positive integer or -1 for the default size. The\n\
+sizehint is used to optimize internal data structures. It doesn't limit\n\
+the maximum number of monitored events.");
+
+static PyTypeObject pyEpoll_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "select.epoll", /* tp_name */
+ sizeof(pyEpoll_Object), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)pyepoll_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ pyepoll_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ pyepoll_methods, /* tp_methods */
+ 0, /* tp_members */
+ pyepoll_getsetlist, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ pyepoll_new, /* tp_new */
+ 0, /* tp_free */
+};
+
+#endif /* HAVE_EPOLL */
+
+#ifdef HAVE_KQUEUE
+/* **************************************************************************
+ * kqueue interface for BSD
+ *
+ * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_SYS_EVENT_H
+#include <sys/event.h>
+#endif
+
+PyDoc_STRVAR(kqueue_event_doc,
+"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\
+\n\
+This object is the equivalent of the struct kevent for the C API.\n\
+\n\
+See the kqueue manpage for more detailed information about the meaning\n\
+of the arguments.\n\
+\n\
+One minor note: while you might hope that udata could store a\n\
+reference to a python object, it cannot, because it is impossible to\n\
+keep a proper reference count of the object once it's passed into the\n\
+kernel. Therefore, I have restricted it to only storing an integer. I\n\
+recommend ignoring it and simply using the 'ident' field to key off\n\
+of. You could also set up a dictionary on the python side to store a\n\
+udata->object mapping.");
+
+typedef struct {
+ PyObject_HEAD
+ struct kevent e;
+} kqueue_event_Object;
+
+static PyTypeObject kqueue_event_Type;
+
+#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))
+
+typedef struct {
+ PyObject_HEAD
+ SOCKET kqfd; /* kqueue control fd */
+} kqueue_queue_Object;
+
+static PyTypeObject kqueue_queue_Type;
+
+#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))
+
+#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)
+# error uintptr_t does not match void *!
+#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)
+# define T_UINTPTRT T_ULONGLONG
+# define T_INTPTRT T_LONGLONG
+# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong
+# define UINTPTRT_FMT_UNIT "K"
+# define INTPTRT_FMT_UNIT "L"
+#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)
+# define T_UINTPTRT T_ULONG
+# define T_INTPTRT T_LONG
+# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
+# define UINTPTRT_FMT_UNIT "k"
+# define INTPTRT_FMT_UNIT "l"
+#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)
+# define T_UINTPTRT T_UINT
+# define T_INTPTRT T_INT
+# define PyLong_AsUintptr_t PyLong_AsUnsignedLong
+# define UINTPTRT_FMT_UNIT "I"
+# define INTPTRT_FMT_UNIT "i"
+#else
+# error uintptr_t does not match int, long, or long long!
+#endif
+
+/*
+ * kevent is not standard and its members vary across BSDs.
+ */
+#if !defined(__OpenBSD__)
+# define IDENT_TYPE T_UINTPTRT
+# define IDENT_CAST Py_intptr_t
+# define DATA_TYPE T_INTPTRT
+# define DATA_FMT_UNIT INTPTRT_FMT_UNIT
+# define IDENT_AsType PyLong_AsUintptr_t
+#else
+# define IDENT_TYPE T_UINT
+# define IDENT_CAST int
+# define DATA_TYPE T_INT
+# define DATA_FMT_UNIT "i"
+# define IDENT_AsType PyLong_AsUnsignedLong
+#endif
+
+/* Unfortunately, we can't store python objects in udata, because
+ * kevents in the kernel can be removed without warning, which would
+ * forever lose the refcount on the object stored with it.
+ */
+
+#define KQ_OFF(x) offsetof(kqueue_event_Object, x)
+static struct PyMemberDef kqueue_event_members[] = {
+ {"ident", IDENT_TYPE, KQ_OFF(e.ident)},
+ {"filter", T_SHORT, KQ_OFF(e.filter)},
+ {"flags", T_USHORT, KQ_OFF(e.flags)},
+ {"fflags", T_UINT, KQ_OFF(e.fflags)},
+ {"data", DATA_TYPE, KQ_OFF(e.data)},
+ {"udata", T_UINTPTRT, KQ_OFF(e.udata)},
+ {NULL} /* Sentinel */
+};
+#undef KQ_OFF
+
+static PyObject *
+
+kqueue_event_repr(kqueue_event_Object *s)
+{
+ char buf[1024];
+ PyOS_snprintf(
+ buf, sizeof(buf),
+ "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "
+ "data=0x%zd udata=%p>",
+ (size_t)(s->e.ident), s->e.filter, s->e.flags,
+ s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);
+ return PyString_FromString(buf);
+}
+
+static int
+kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)
+{
+ PyObject *pfd;
+ static char *kwlist[] = {"ident", "filter", "flags", "fflags",
+ "data", "udata", NULL};
+ static char *fmt = "O|hHI" DATA_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";
+
+ EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
+ &pfd, &(self->e.filter), &(self->e.flags),
+ &(self->e.fflags), &(self->e.data), &(self->e.udata))) {
+ return -1;
+ }
+
+ if (PyLong_Check(pfd)
+#if IDENT_TYPE == T_UINT
+ && PyLong_AsUnsignedLong(pfd) <= UINT_MAX
+#endif
+ ) {
+ self->e.ident = IDENT_AsType(pfd);
+ }
+ else {
+ self->e.ident = PyObject_AsFileDescriptor(pfd);
+ }
+ if (PyErr_Occurred()) {
+ return -1;
+ }
+ return 0;
+}
+
+static PyObject *
+kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,
+ int op)
+{
+ Py_intptr_t result = 0;
+
+ if (!kqueue_event_Check(o)) {
+ if (op == Py_EQ || op == Py_NE) {
+ PyObject *res = op == Py_EQ ? Py_False : Py_True;
+ Py_INCREF(res);
+ return res;
+ }
+ PyErr_Format(PyExc_TypeError,
+ "can't compare %.200s to %.200s",
+ Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);
+ return NULL;
+ }
+ if (((result = (IDENT_CAST)(s->e.ident - o->e.ident)) == 0) &&
+ ((result = s->e.filter - o->e.filter) == 0) &&
+ ((result = s->e.flags - o->e.flags) == 0) &&
+ ((result = (int)(s->e.fflags - o->e.fflags)) == 0) &&
+ ((result = s->e.data - o->e.data) == 0) &&
+ ((result = s->e.udata - o->e.udata) == 0)
+ ) {
+ result = 0;
+ }
+
+ switch (op) {
+ case Py_EQ:
+ result = (result == 0);
+ break;
+ case Py_NE:
+ result = (result != 0);
+ break;
+ case Py_LE:
+ result = (result <= 0);
+ break;
+ case Py_GE:
+ result = (result >= 0);
+ break;
+ case Py_LT:
+ result = (result < 0);
+ break;
+ case Py_GT:
+ result = (result > 0);
+ break;
+ }
+ return PyBool_FromLong((long)result);
+}
+
+static PyTypeObject kqueue_event_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "select.kevent", /* tp_name */
+ sizeof(kqueue_event_Object), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc)kqueue_event_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ kqueue_event_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ kqueue_event_members, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)kqueue_event_init, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+ 0, /* tp_free */
+};
+
+static PyObject *
+kqueue_queue_err_closed(void)
+{
+ PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");
+ return NULL;
+}
+
+static int
+kqueue_queue_internal_close(kqueue_queue_Object *self)
+{
+ int save_errno = 0;
+ if (self->kqfd >= 0) {
+ int kqfd = self->kqfd;
+ self->kqfd = -1;
+ Py_BEGIN_ALLOW_THREADS
+ if (close(kqfd) < 0)
+ save_errno = errno;
+ Py_END_ALLOW_THREADS
+ }
+ return save_errno;
+}
+
+static PyObject *
+newKqueue_Object(PyTypeObject *type, SOCKET fd)
+{
+ kqueue_queue_Object *self;
+ assert(type != NULL && type->tp_alloc != NULL);
+ self = (kqueue_queue_Object *) type->tp_alloc(type, 0);
+ if (self == NULL) {
+ return NULL;
+ }
+
+ if (fd == -1) {
+ Py_BEGIN_ALLOW_THREADS
+ self->kqfd = kqueue();
+ Py_END_ALLOW_THREADS
+ }
+ else {
+ self->kqfd = fd;
+ }
+ if (self->kqfd < 0) {
+ Py_DECREF(self);
+ PyErr_SetFromErrno(PyExc_IOError);
+ return NULL;
+ }
+ return (PyObject *)self;
+}
+
+static PyObject *
+kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+
+ if ((args != NULL && PyObject_Size(args)) ||
+ (kwds != NULL && PyObject_Size(kwds))) {
+ PyErr_SetString(PyExc_ValueError,
+ "select.kqueue doesn't accept arguments");
+ return NULL;
+ }
+
+ return newKqueue_Object(type, -1);
+}
+
+static void
+kqueue_queue_dealloc(kqueue_queue_Object *self)
+{
+ kqueue_queue_internal_close(self);
+ Py_TYPE(self)->tp_free(self);
+}
+
+static PyObject*
+kqueue_queue_close(kqueue_queue_Object *self)
+{
+ errno = kqueue_queue_internal_close(self);
+ if (errno < 0) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(kqueue_queue_close_doc,
+"close() -> None\n\
+\n\
+Close the kqueue control file descriptor. Further operations on the kqueue\n\
+object will raise an exception.");
+
+static PyObject*
+kqueue_queue_get_closed(kqueue_queue_Object *self)
+{
+ if (self->kqfd < 0)
+ Py_RETURN_TRUE;
+ else
+ Py_RETURN_FALSE;
+}
+
+static PyObject*
+kqueue_queue_fileno(kqueue_queue_Object *self)
+{
+ if (self->kqfd < 0)
+ return kqueue_queue_err_closed();
+ return PyInt_FromLong(self->kqfd);
+}
+
+PyDoc_STRVAR(kqueue_queue_fileno_doc,
+"fileno() -> int\n\
+\n\
+Return the kqueue control file descriptor.");
+
+static PyObject*
+kqueue_queue_fromfd(PyObject *cls, PyObject *args)
+{
+ SOCKET fd;
+
+ if (!PyArg_ParseTuple(args, "i:fromfd", &fd))
+ return NULL;
+
+ return newKqueue_Object((PyTypeObject*)cls, fd);
+}
+
+PyDoc_STRVAR(kqueue_queue_fromfd_doc,
+"fromfd(fd) -> kqueue\n\
+\n\
+Create a kqueue object from a given control fd.");
+
+static PyObject *
+kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)
+{
+ int nevents = 0;
+ int gotevents = 0;
+ int nchanges = 0;
+ int i = 0;
+ PyObject *otimeout = NULL;
+ PyObject *ch = NULL;
+ PyObject *it = NULL, *ei = NULL;
+ PyObject *result = NULL;
+ struct kevent *evl = NULL;
+ struct kevent *chl = NULL;
+ struct timespec timeoutspec;
+ struct timespec *ptimeoutspec;
+
+ if (self->kqfd < 0)
+ return kqueue_queue_err_closed();
+
+ if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))
+ return NULL;
+
+ if (nevents < 0) {
+ PyErr_Format(PyExc_ValueError,
+ "Length of eventlist must be 0 or positive, got %d",
+ nevents);
+ return NULL;
+ }
+
+ if (otimeout == Py_None || otimeout == NULL) {
+ ptimeoutspec = NULL;
+ }
+ else if (PyNumber_Check(otimeout)) {
+ double timeout;
+ long seconds;
+
+ timeout = PyFloat_AsDouble(otimeout);
+ if (timeout == -1 && PyErr_Occurred())
+ return NULL;
+ if (timeout > (double)LONG_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "timeout period too long");
+ return NULL;
+ }
+ if (timeout < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "timeout must be positive or None");
+ return NULL;
+ }
+
+ seconds = (long)timeout;
+ timeout = timeout - (double)seconds;
+ timeoutspec.tv_sec = seconds;
+ timeoutspec.tv_nsec = (long)(timeout * 1E9);
+ ptimeoutspec = &timeoutspec;
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "timeout argument must be an number "
+ "or None, got %.200s",
+ Py_TYPE(otimeout)->tp_name);
+ return NULL;
+ }
+
+ if (ch != NULL && ch != Py_None) {
+ it = PyObject_GetIter(ch);
+ if (it == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "changelist is not iterable");
+ return NULL;
+ }
+ nchanges = PyObject_Size(ch);
+ if (nchanges < 0) {
+ goto error;
+ }
+
+ chl = PyMem_New(struct kevent, nchanges);
+ if (chl == NULL) {
+ PyErr_NoMemory();
+ goto error;
+ }
+ i = 0;
+ while ((ei = PyIter_Next(it)) != NULL) {
+ if (!kqueue_event_Check(ei)) {
+ Py_DECREF(ei);
+ PyErr_SetString(PyExc_TypeError,
+ "changelist must be an iterable of "
+ "select.kevent objects");
+ goto error;
+ } else {
+ chl[i++] = ((kqueue_event_Object *)ei)->e;
+ }
+ Py_DECREF(ei);
+ }
+ }
+ Py_CLEAR(it);
+
+ /* event list */
+ if (nevents) {
+ evl = PyMem_New(struct kevent, nevents);
+ if (evl == NULL) {
+ PyErr_NoMemory();
+ goto error;
+ }
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ gotevents = kevent(self->kqfd, chl, nchanges,
+ evl, nevents, ptimeoutspec);
+ Py_END_ALLOW_THREADS
+
+ if (gotevents == -1) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ goto error;
+ }
+
+ result = PyList_New(gotevents);
+ if (result == NULL) {
+ goto error;
+ }
+
+ for (i = 0; i < gotevents; i++) {
+ kqueue_event_Object *ch;
+
+ ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);
+ if (ch == NULL) {
+ goto error;
+ }
+ ch->e = evl[i];
+ PyList_SET_ITEM(result, i, (PyObject *)ch);
+ }
+ PyMem_Free(chl);
+ PyMem_Free(evl);
+ return result;
+
+ error:
+ PyMem_Free(chl);
+ PyMem_Free(evl);
+ Py_XDECREF(result);
+ Py_XDECREF(it);
+ return NULL;
+}
+
+PyDoc_STRVAR(kqueue_queue_control_doc,
+"control(changelist, max_events[, timeout=None]) -> eventlist\n\
+\n\
+Calls the kernel kevent function.\n\
+- changelist must be a list of kevent objects describing the changes\n\
+ to be made to the kernel's watch list or None.\n\
+- max_events lets you specify the maximum number of events that the\n\
+ kernel will return.\n\
+- timeout is the maximum time to wait in seconds, or else None,\n\
+ to wait forever. timeout accepts floats for smaller timeouts, too.");
+
+
+static PyMethodDef kqueue_queue_methods[] = {
+ {"fromfd", (PyCFunction)kqueue_queue_fromfd,
+ METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},
+ {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,
+ kqueue_queue_close_doc},
+ {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,
+ kqueue_queue_fileno_doc},
+ {"control", (PyCFunction)kqueue_queue_control,
+ METH_VARARGS , kqueue_queue_control_doc},
+ {NULL, NULL},
+};
+
+static PyGetSetDef kqueue_queue_getsetlist[] = {
+ {"closed", (getter)kqueue_queue_get_closed, NULL,
+ "True if the kqueue handler is closed"},
+ {0},
+};
+
+PyDoc_STRVAR(kqueue_queue_doc,
+"Kqueue syscall wrapper.\n\
+\n\
+For example, to start watching a socket for input:\n\
+>>> kq = kqueue()\n\
+>>> sock = socket()\n\
+>>> sock.connect((host, port))\n\
+>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\
+\n\
+To wait one second for it to become writeable:\n\
+>>> kq.control(None, 1, 1000)\n\
+\n\
+To stop listening:\n\
+>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");
+
+static PyTypeObject kqueue_queue_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "select.kqueue", /* tp_name */
+ sizeof(kqueue_queue_Object), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)kqueue_queue_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ kqueue_queue_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ kqueue_queue_methods, /* tp_methods */
+ 0, /* tp_members */
+ kqueue_queue_getsetlist, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ kqueue_queue_new, /* tp_new */
+ 0, /* tp_free */
+};
+
+#endif /* HAVE_KQUEUE */
+/* ************************************************************************ */
+
+PyDoc_STRVAR(select_doc,
+"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
+\n\
+Wait until one or more file descriptors are ready for some kind of I/O.\n\
+The first three arguments are sequences of file descriptors to be waited for:\n\
+rlist -- wait until ready for reading\n\
+wlist -- wait until ready for writing\n\
+xlist -- wait for an ``exceptional condition''\n\
+If only one kind of condition is required, pass [] for the other lists.\n\
+A file descriptor is either a socket or file object, or a small integer\n\
+gotten from a fileno() method call on one of those.\n\
+\n\
+The optional 4th argument specifies a timeout in seconds; it may be\n\
+a floating point number to specify fractions of seconds. If it is absent\n\
+or None, the call will never time out.\n\
+\n\
+The return value is a tuple of three lists corresponding to the first three\n\
+arguments; each contains the subset of the corresponding file descriptors\n\
+that are ready.\n\
+\n\
+*** IMPORTANT NOTICE ***\n\
+On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\
+descriptors can be used.");
+
+static PyMethodDef select_methods[] = {
+ {"select", select_select, METH_VARARGS, select_doc},
+#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
+ {"poll", select_poll, METH_NOARGS, poll_doc},
+#endif /* HAVE_POLL */
+ {0, 0}, /* sentinel */
+};
+
+PyDoc_STRVAR(module_doc,
+"This module supports asynchronous I/O on multiple file descriptors.\n\
+\n\
+*** IMPORTANT NOTICE ***\n\
+On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
+
+PyMODINIT_FUNC
+initselect(void)
+{
+ PyObject *m;
+ m = Py_InitModule3("select", select_methods, module_doc);
+ if (m == NULL)
+ return;
+
+ SelectError = PyErr_NewException("select.error", NULL, NULL);
+ Py_INCREF(SelectError);
+ PyModule_AddObject(m, "error", SelectError);
+
+#ifdef PIPE_BUF
+#ifdef HAVE_BROKEN_PIPE_BUF
+#undef PIPE_BUF
+#define PIPE_BUF 512
+#endif
+ PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF);
+#endif
+
+#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
+#ifdef __APPLE__
+ if (select_have_broken_poll()) {
+ if (PyObject_DelAttrString(m, "poll") == -1) {
+ PyErr_Clear();
+ }
+ } else {
+#else
+ {
+#endif
+ Py_TYPE(&poll_Type) = &PyType_Type;
+ PyModule_AddIntConstant(m, "POLLIN", POLLIN);
+ PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
+ PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
+ PyModule_AddIntConstant(m, "POLLERR", POLLERR);
+ PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
+ PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
+
+#ifdef POLLRDNORM
+ PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
+#endif
+#ifdef POLLRDBAND
+ PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
+#endif
+#ifdef POLLWRNORM
+ PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
+#endif
+#ifdef POLLWRBAND
+ PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
+#endif
+#ifdef POLLMSG
+ PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
+#endif
+ }
+#endif /* HAVE_POLL */
+
+#ifdef HAVE_EPOLL
+ Py_TYPE(&pyEpoll_Type) = &PyType_Type;
+ if (PyType_Ready(&pyEpoll_Type) < 0)
+ return;
+
+ Py_INCREF(&pyEpoll_Type);
+ PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
+
+ PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);
+ PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);
+ PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);
+ PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);
+ PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);
+ PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);
+#ifdef EPOLLONESHOT
+ /* Kernel 2.6.2+ */
+ PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);
+#endif
+ /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */
+ PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);
+ PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);
+ PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);
+ PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);
+ PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);
+#endif /* HAVE_EPOLL */
+
+#ifdef HAVE_KQUEUE
+ kqueue_event_Type.tp_new = PyType_GenericNew;
+ Py_TYPE(&kqueue_event_Type) = &PyType_Type;
+ if(PyType_Ready(&kqueue_event_Type) < 0)
+ return;
+
+ Py_INCREF(&kqueue_event_Type);
+ PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
+
+ Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
+ if(PyType_Ready(&kqueue_queue_Type) < 0)
+ return;
+ Py_INCREF(&kqueue_queue_Type);
+ PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
+
+ /* event filters */
+ PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);
+ PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);
+ PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);
+ PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);
+ PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);
+#ifdef EVFILT_NETDEV
+ PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);
+#endif
+ PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);
+ PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);
+
+ /* event flags */
+ PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);
+ PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);
+ PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);
+ PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);
+ PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);
+ PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);
+
+ PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);
+ PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);
+
+ PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);
+ PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);
+
+ /* READ WRITE filter flag */
+ PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);
+
+ /* VNODE filter flags */
+ PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);
+ PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);
+ PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);
+ PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);
+ PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);
+ PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);
+ PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);
+
+ /* PROC filter flags */
+ PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);
+ PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);
+ PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);
+ PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);
+ PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);
+
+ PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);
+ PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);
+ PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);
+
+ /* NETDEV filter flags */
+#ifdef EVFILT_NETDEV
+ PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);
+ PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);
+ PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);
+#endif
+
+#endif /* HAVE_KQUEUE */
+}
diff --git a/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/zlib/gzguts.h b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/zlib/gzguts.h new file mode 100644 index 0000000000..bef9749ee8 --- /dev/null +++ b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/zlib/gzguts.h @@ -0,0 +1,209 @@ +/* gzguts.h -- zlib internal header definitions for gz* operations
+ * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#ifdef _LARGEFILE64_SOURCE
+# ifndef _LARGEFILE_SOURCE
+# define _LARGEFILE_SOURCE 1
+# endif
+# ifdef _FILE_OFFSET_BITS
+# undef _FILE_OFFSET_BITS
+# endif
+#endif
+
+#ifdef HAVE_HIDDEN
+# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+#else
+# define ZLIB_INTERNAL
+#endif
+
+#include <stdio.h>
+#include "zlib.h"
+#ifdef STDC
+# include <string.h>
+# include <stdlib.h>
+# include <limits.h>
+#endif
+#include <fcntl.h>
+
+#ifdef _WIN32
+# include <stddef.h>
+#endif
+
+#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32)
+# include <io.h>
+#endif
+
+#ifdef WINAPI_FAMILY
+# define open _open
+# define read _read
+# define write _write
+# define close _close
+#endif
+
+#ifdef NO_DEFLATE /* for compatibility with old definition */
+# define NO_GZCOMPRESS
+#endif
+
+#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
+# ifndef HAVE_VSNPRINTF
+# define HAVE_VSNPRINTF
+# endif
+#endif
+
+#if defined(__CYGWIN__)
+# ifndef HAVE_VSNPRINTF
+# define HAVE_VSNPRINTF
+# endif
+#endif
+
+#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410)
+# ifndef HAVE_VSNPRINTF
+# define HAVE_VSNPRINTF
+# endif
+#endif
+
+#ifndef HAVE_VSNPRINTF
+# ifdef MSDOS
+/* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
+ but for now we just assume it doesn't. */
+# define NO_vsnprintf
+# endif
+# ifdef __TURBOC__
+# define NO_vsnprintf
+# endif
+# ifdef WIN32
+/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
+# if !defined(vsnprintf) && !defined(NO_vsnprintf)
+# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 )
+# define vsnprintf _vsnprintf
+# endif
+# endif
+# endif
+# ifdef __SASC
+# define NO_vsnprintf
+# endif
+# ifdef VMS
+# define NO_vsnprintf
+# endif
+# ifdef __OS400__
+# define NO_vsnprintf
+# endif
+# ifdef __MVS__
+# define NO_vsnprintf
+# endif
+#endif
+
+/* unlike snprintf (which is required in C99, yet still not supported by
+ Microsoft more than a decade later!), _snprintf does not guarantee null
+ termination of the result -- however this is only used in gzlib.c where
+ the result is assured to fit in the space provided */
+#ifdef _MSC_VER
+# define snprintf _snprintf
+#endif
+
+#ifndef local
+# define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+/* gz* functions always use library allocation functions */
+#ifndef STDC
+ extern voidp malloc OF((uInt size));
+ extern void free OF((voidpf ptr));
+#endif
+
+/* get errno and strerror definition */
+#if defined UNDER_CE
+# include <windows.h>
+# define zstrerror() gz_strwinerror((DWORD)GetLastError())
+#else
+# ifndef NO_STRERROR
+# include <errno.h>
+# define zstrerror() strerror(errno)
+# else
+# define zstrerror() "stdio error (consult errno)"
+# endif
+#endif
+
+/* provide prototypes for these when building zlib without LFS */
+#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0
+ ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+ ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
+ ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
+ ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
+#endif
+
+/* default memLevel */
+#if MAX_MEM_LEVEL >= 8
+# define DEF_MEM_LEVEL 8
+#else
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
+#endif
+
+/* default i/o buffer size -- double this for output when reading (this and
+ twice this must be able to fit in an unsigned type) */
+#define GZBUFSIZE 8192
+
+/* gzip modes, also provide a little integrity check on the passed structure */
+#define GZ_NONE 0
+#define GZ_READ 7247
+#define GZ_WRITE 31153
+#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */
+
+/* values for gz_state how */
+#define LOOK 0 /* look for a gzip header */
+#define COPY 1 /* copy input directly */
+#define GZIP 2 /* decompress a gzip stream */
+
+/* internal gzip file state data structure */
+typedef struct {
+ /* exposed contents for gzgetc() macro */
+ struct gzFile_s x; /* "x" for exposed */
+ /* x.have: number of bytes available at x.next */
+ /* x.next: next output data to deliver or write */
+ /* x.pos: current position in uncompressed data */
+ /* used for both reading and writing */
+ int mode; /* see gzip modes above */
+ int fd; /* file descriptor */
+ char *path; /* path or fd for error messages */
+ unsigned size; /* buffer size, zero if not allocated yet */
+ unsigned want; /* requested buffer size, default is GZBUFSIZE */
+ unsigned char *in; /* input buffer */
+ unsigned char *out; /* output buffer (double-sized when reading) */
+ int direct; /* 0 if processing gzip, 1 if transparent */
+ /* just for reading */
+ int how; /* 0: get header, 1: copy, 2: decompress */
+ z_off64_t start; /* where the gzip data started, for rewinding */
+ int eof; /* true if end of input file reached */
+ int past; /* true if read requested past end */
+ /* just for writing */
+ int level; /* compression level */
+ int strategy; /* compression strategy */
+ /* seek request */
+ z_off64_t skip; /* amount to skip (already rewound if backwards) */
+ int seek; /* true if seek request pending */
+ /* error information */
+ int err; /* error code */
+ char *msg; /* error message */
+ /* zlib inflate or deflate stream */
+ z_stream strm; /* stream structure in-place (not a pointer) */
+} gz_state;
+typedef gz_state FAR *gz_statep;
+
+/* shared functions */
+void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *));
+#if defined UNDER_CE
+char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error));
+#endif
+
+/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t
+ value -- needed when comparing unsigned to z_off64_t, which is signed
+ (possible z_off64_t types off_t, off64_t, and long are all signed) */
+#ifdef INT_MAX
+# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX)
+#else
+unsigned ZLIB_INTERNAL gz_intmax OF((void));
+# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())
+#endif
diff --git a/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/zlib/zutil.h b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/zlib/zutil.h new file mode 100644 index 0000000000..f4e4d05917 --- /dev/null +++ b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Modules/zlib/zutil.h @@ -0,0 +1,253 @@ +/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995-2013 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZUTIL_H
+#define ZUTIL_H
+
+#ifdef HAVE_HIDDEN
+# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+#else
+# define ZLIB_INTERNAL
+#endif
+
+#include "zlib.h"
+
+#if defined(STDC) && !defined(Z_SOLO)
+# if !(defined(_WIN32_WCE) && defined(_MSC_VER))
+# include <stddef.h>
+# endif
+# include <string.h>
+# include <stdlib.h>
+#endif
+
+#ifdef Z_SOLO
+ typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */
+#endif
+
+#ifndef local
+# define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+typedef unsigned char uch;
+typedef uch FAR uchf;
+typedef unsigned short ush;
+typedef ush FAR ushf;
+typedef unsigned long ulg;
+
+extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
+/* (size given to avoid silly warnings with Visual C++) */
+
+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
+
+#define ERR_RETURN(strm,err) \
+ return (strm->msg = ERR_MSG(err), (err))
+/* To be used only when the state is known to be valid */
+
+ /* common constants */
+
+#ifndef DEF_WBITS
+# define DEF_WBITS MAX_WBITS
+#endif
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#if MAX_MEM_LEVEL >= 8
+# define DEF_MEM_LEVEL 8
+#else
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
+#endif
+/* default memLevel */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES 2
+/* The three kinds of block type */
+
+#define MIN_MATCH 3
+#define MAX_MATCH 258
+/* The minimum and maximum match lengths */
+
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
+
+ /* target dependencies */
+
+#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
+# define OS_CODE 0x00
+# ifndef Z_SOLO
+# if defined(__TURBOC__) || defined(__BORLANDC__)
+# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
+ /* Allow compilation with ANSI keywords only enabled */
+ void _Cdecl farfree( void *block );
+ void *_Cdecl farmalloc( unsigned long nbytes );
+# else
+# include <alloc.h>
+# endif
+# else /* MSC or DJGPP */
+# include <malloc.h>
+# endif
+# endif
+#endif
+
+#ifdef AMIGA
+# define OS_CODE 0x01
+#endif
+
+#if defined(VAXC) || defined(VMS)
+# define OS_CODE 0x02
+# define F_OPEN(name, mode) \
+ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
+#endif
+
+#if defined(ATARI) || defined(atarist)
+# define OS_CODE 0x05
+#endif
+
+#ifdef OS2
+# define OS_CODE 0x06
+# if defined(M_I86) && !defined(Z_SOLO)
+# include <malloc.h>
+# endif
+#endif
+
+#if defined(MACOS) || defined(TARGET_OS_MAC)
+# define OS_CODE 0x07
+# ifndef Z_SOLO
+# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+# include <unix.h> /* for fdopen */
+# else
+# ifndef fdopen
+# define fdopen(fd,mode) NULL /* No fdopen() */
+# endif
+# endif
+# endif
+#endif
+
+#ifdef TOPS20
+# define OS_CODE 0x0a
+#endif
+
+#ifdef WIN32
+# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */
+# define OS_CODE 0x0b
+# endif
+#endif
+
+#ifdef __50SERIES /* Prime/PRIMOS */
+# define OS_CODE 0x0f
+#endif
+
+#if defined(_BEOS_) || defined(RISCOS)
+# define fdopen(fd,mode) NULL /* No fdopen() */
+#endif
+
+#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX
+# if defined(_WIN32_WCE)
+# define fdopen(fd,mode) NULL /* No fdopen() */
+# ifndef _PTRDIFF_T_DEFINED
+ typedef int ptrdiff_t;
+# define _PTRDIFF_T_DEFINED
+# endif
+# else
+# define fdopen(fd,type) _fdopen(fd,type)
+# endif
+#endif
+
+#if defined(__BORLANDC__) && !defined(MSDOS)
+ #pragma warn -8004
+ #pragma warn -8008
+ #pragma warn -8066
+#endif
+
+/* provide prototypes for these when building zlib without LFS */
+#if !defined(_WIN32) && \
+ (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)
+ ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+#endif
+
+ /* common defaults */
+
+#ifndef OS_CODE
+# define OS_CODE 0x03 /* assume Unix */
+#endif
+
+#ifndef F_OPEN
+# define F_OPEN(name, mode) fopen((name), (mode))
+#endif
+
+ /* functions */
+
+#if defined(pyr) || defined(Z_SOLO)
+# define NO_MEMCPY
+#endif
+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
+ /* Use our own functions for small and medium model with MSC <= 5.0.
+ * You may have to use the same strategy for Borland C (untested).
+ * The __SC__ check is for Symantec.
+ */
+# define NO_MEMCPY
+#endif
+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
+# define HAVE_MEMCPY
+#endif
+#ifdef HAVE_MEMCPY
+# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
+# define zmemcpy _fmemcpy
+# define zmemcmp _fmemcmp
+# define zmemzero(dest, len) _fmemset(dest, 0, len)
+# else
+# define zmemcpy memcpy
+# define zmemcmp memcmp
+# define zmemzero(dest, len) memset(dest, 0, len)
+# endif
+#else
+ void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
+ int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
+ void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len));
+#endif
+
+/* Diagnostic functions */
+#ifdef DEBUG
+# include <stdio.h>
+ extern int ZLIB_INTERNAL z_verbose;
+ extern void ZLIB_INTERNAL z_error OF((char *m));
+# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
+# define Trace(x) {if (z_verbose>=0) fprintf x ;}
+# define Tracev(x) {if (z_verbose>0) fprintf x ;}
+# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
+# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
+# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
+#else
+# define Assert(cond,msg)
+# define Trace(x)
+# define Tracev(x)
+# define Tracevv(x)
+# define Tracec(c,x)
+# define Tracecv(c,x)
+#endif
+
+#ifndef Z_SOLO
+ voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
+ unsigned size));
+ void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr));
+#endif
+
+#define ZALLOC(strm, items, size) \
+ (*((strm)->zalloc))((strm)->opaque, (items), (size))
+#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
+
+/* Reverse the bytes in a 32-bit value */
+#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
+ (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
+
+#endif /* ZUTIL_H */
diff --git a/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Objects/longobject.c b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Objects/longobject.c new file mode 100644 index 0000000000..2c367ac8e1 --- /dev/null +++ b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Objects/longobject.c @@ -0,0 +1,4401 @@ +/* Long (arbitrary precision) integer object implementation */
+
+/* XXX The functional organization of this file is terrible */
+
+#include "Python.h"
+#include "longintrepr.h"
+#include "structseq.h"
+
+#include <float.h>
+#include <ctype.h>
+#include <stddef.h>
+
+/* For long multiplication, use the O(N**2) school algorithm unless
+ * both operands contain more than KARATSUBA_CUTOFF digits (this
+ * being an internal Python long digit, in base PyLong_BASE).
+ */
+#define KARATSUBA_CUTOFF 70
+#define KARATSUBA_SQUARE_CUTOFF (2 * KARATSUBA_CUTOFF)
+
+/* For exponentiation, use the binary left-to-right algorithm
+ * unless the exponent contains more than FIVEARY_CUTOFF digits.
+ * In that case, do 5 bits at a time. The potential drawback is that
+ * a table of 2**5 intermediate results is computed.
+ */
+#define FIVEARY_CUTOFF 8
+
+#define ABS(x) ((x) < 0 ? -(x) : (x))
+
+#undef MIN
+#undef MAX
+#define MAX(x, y) ((x) < (y) ? (y) : (x))
+#define MIN(x, y) ((x) > (y) ? (y) : (x))
+
+#define SIGCHECK(PyTryBlock) \
+ do { \
+ if (--_Py_Ticker < 0) { \
+ _Py_Ticker = _Py_CheckInterval; \
+ if (PyErr_CheckSignals()) PyTryBlock \
+ } \
+ } while(0)
+
+/* Normalize (remove leading zeros from) a long int object.
+ Doesn't attempt to free the storage--in most cases, due to the nature
+ of the algorithms used, this could save at most be one word anyway. */
+
+static PyLongObject *
+long_normalize(register PyLongObject *v)
+{
+ Py_ssize_t j = ABS(Py_SIZE(v));
+ Py_ssize_t i = j;
+
+ while (i > 0 && v->ob_digit[i-1] == 0)
+ --i;
+ if (i != j)
+ Py_SIZE(v) = (Py_SIZE(v) < 0) ? -(i) : i;
+ return v;
+}
+
+/* Allocate a new long int object with size digits.
+ Return NULL and set exception if we run out of memory. */
+
+#define MAX_LONG_DIGITS \
+ ((PY_SSIZE_T_MAX - offsetof(PyLongObject, ob_digit))/sizeof(digit))
+
+PyLongObject *
+_PyLong_New(Py_ssize_t size)
+{
+ if (size > (Py_ssize_t)MAX_LONG_DIGITS) {
+ PyErr_SetString(PyExc_OverflowError,
+ "too many digits in integer");
+ return NULL;
+ }
+ /* coverity[ampersand_in_size] */
+ /* XXX(nnorwitz): PyObject_NEW_VAR / _PyObject_VAR_SIZE need to detect
+ overflow */
+ return PyObject_NEW_VAR(PyLongObject, &PyLong_Type, size);
+}
+
+PyObject *
+_PyLong_Copy(PyLongObject *src)
+{
+ PyLongObject *result;
+ Py_ssize_t i;
+
+ assert(src != NULL);
+ i = src->ob_size;
+ if (i < 0)
+ i = -(i);
+ result = _PyLong_New(i);
+ if (result != NULL) {
+ result->ob_size = src->ob_size;
+ while (--i >= 0)
+ result->ob_digit[i] = src->ob_digit[i];
+ }
+ return (PyObject *)result;
+}
+
+/* Create a new long int object from a C long int */
+
+PyObject *
+PyLong_FromLong(long ival)
+{
+ PyLongObject *v;
+ unsigned long abs_ival;
+ unsigned long t; /* unsigned so >> doesn't propagate sign bit */
+ int ndigits = 0;
+ int negative = 0;
+
+ if (ival < 0) {
+ /* if LONG_MIN == -LONG_MAX-1 (true on most platforms) then
+ ANSI C says that the result of -ival is undefined when ival
+ == LONG_MIN. Hence the following workaround. */
+ abs_ival = (unsigned long)(-1-ival) + 1;
+ negative = 1;
+ }
+ else {
+ abs_ival = (unsigned long)ival;
+ }
+
+ /* Count the number of Python digits.
+ We used to pick 5 ("big enough for anything"), but that's a
+ waste of time and space given that 5*15 = 75 bits are rarely
+ needed. */
+ t = abs_ival;
+ while (t) {
+ ++ndigits;
+ t >>= PyLong_SHIFT;
+ }
+ v = _PyLong_New(ndigits);
+ if (v != NULL) {
+ digit *p = v->ob_digit;
+ v->ob_size = negative ? -ndigits : ndigits;
+ t = abs_ival;
+ while (t) {
+ *p++ = (digit)(t & PyLong_MASK);
+ t >>= PyLong_SHIFT;
+ }
+ }
+ return (PyObject *)v;
+}
+
+/* Create a new long int object from a C unsigned long int */
+
+PyObject *
+PyLong_FromUnsignedLong(unsigned long ival)
+{
+ PyLongObject *v;
+ unsigned long t;
+ int ndigits = 0;
+
+ /* Count the number of Python digits. */
+ t = (unsigned long)ival;
+ while (t) {
+ ++ndigits;
+ t >>= PyLong_SHIFT;
+ }
+ v = _PyLong_New(ndigits);
+ if (v != NULL) {
+ digit *p = v->ob_digit;
+ Py_SIZE(v) = ndigits;
+ while (ival) {
+ *p++ = (digit)(ival & PyLong_MASK);
+ ival >>= PyLong_SHIFT;
+ }
+ }
+ return (PyObject *)v;
+}
+
+/* Create a new long int object from a C double */
+
+PyObject *
+PyLong_FromDouble(double dval)
+{
+ PyLongObject *v;
+ double frac;
+ int i, ndig, expo, neg;
+ neg = 0;
+ if (Py_IS_INFINITY(dval)) {
+ PyErr_SetString(PyExc_OverflowError,
+ "cannot convert float infinity to integer");
+ return NULL;
+ }
+ if (Py_IS_NAN(dval)) {
+ PyErr_SetString(PyExc_ValueError,
+ "cannot convert float NaN to integer");
+ return NULL;
+ }
+ if (dval < 0.0) {
+ neg = 1;
+ dval = -dval;
+ }
+ frac = frexp(dval, &expo); /* dval = frac*2**expo; 0.0 <= frac < 1.0 */
+ if (expo <= 0)
+ return PyLong_FromLong(0L);
+ ndig = (expo-1) / PyLong_SHIFT + 1; /* Number of 'digits' in result */
+ v = _PyLong_New(ndig);
+ if (v == NULL)
+ return NULL;
+ frac = ldexp(frac, (expo-1) % PyLong_SHIFT + 1);
+ for (i = ndig; --i >= 0; ) {
+ digit bits = (digit)frac;
+ v->ob_digit[i] = bits;
+ frac = frac - (double)bits;
+ frac = ldexp(frac, PyLong_SHIFT);
+ }
+ if (neg)
+ Py_SIZE(v) = -(Py_SIZE(v));
+ return (PyObject *)v;
+}
+
+/* Checking for overflow in PyLong_AsLong is a PITA since C doesn't define
+ * anything about what happens when a signed integer operation overflows,
+ * and some compilers think they're doing you a favor by being "clever"
+ * then. The bit pattern for the largest postive signed long is
+ * (unsigned long)LONG_MAX, and for the smallest negative signed long
+ * it is abs(LONG_MIN), which we could write -(unsigned long)LONG_MIN.
+ * However, some other compilers warn about applying unary minus to an
+ * unsigned operand. Hence the weird "0-".
+ */
+#define PY_ABS_LONG_MIN (0-(unsigned long)LONG_MIN)
+#define PY_ABS_SSIZE_T_MIN (0-(size_t)PY_SSIZE_T_MIN)
+
+/* Get a C long int from a Python long or Python int object.
+ On overflow, returns -1 and sets *overflow to 1 or -1 depending
+ on the sign of the result. Otherwise *overflow is 0.
+
+ For other errors (e.g., type error), returns -1 and sets an error
+ condition.
+*/
+
+long
+PyLong_AsLongAndOverflow(PyObject *vv, int *overflow)
+{
+ /* This version by Tim Peters */
+ register PyLongObject *v;
+ unsigned long x, prev;
+ long res;
+ Py_ssize_t i;
+ int sign;
+ int do_decref = 0; /* if nb_int was called */
+
+ *overflow = 0;
+ if (vv == NULL) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+
+ if(PyInt_Check(vv))
+ return PyInt_AsLong(vv);
+
+ if (!PyLong_Check(vv)) {
+ PyNumberMethods *nb;
+ nb = vv->ob_type->tp_as_number;
+ if (nb == NULL || nb->nb_int == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "an integer is required");
+ return -1;
+ }
+ vv = (*nb->nb_int) (vv);
+ if (vv == NULL)
+ return -1;
+ do_decref = 1;
+ if(PyInt_Check(vv)) {
+ res = PyInt_AsLong(vv);
+ goto exit;
+ }
+ if (!PyLong_Check(vv)) {
+ Py_DECREF(vv);
+ PyErr_SetString(PyExc_TypeError,
+ "nb_int should return int object");
+ return -1;
+ }
+ }
+
+ res = -1;
+ v = (PyLongObject *)vv;
+ i = Py_SIZE(v);
+
+ switch (i) {
+ case -1:
+ res = -(sdigit)v->ob_digit[0];
+ break;
+ case 0:
+ res = 0;
+ break;
+ case 1:
+ res = v->ob_digit[0];
+ break;
+ default:
+ sign = 1;
+ x = 0;
+ if (i < 0) {
+ sign = -1;
+ i = -(i);
+ }
+ while (--i >= 0) {
+ prev = x;
+ x = (x << PyLong_SHIFT) + v->ob_digit[i];
+ if ((x >> PyLong_SHIFT) != prev) {
+ *overflow = sign;
+ goto exit;
+ }
+ }
+ /* Haven't lost any bits, but casting to long requires extra
+ * care (see comment above).
+ */
+ if (x <= (unsigned long)LONG_MAX) {
+ res = (long)x * sign;
+ }
+ else if (sign < 0 && x == PY_ABS_LONG_MIN) {
+ res = LONG_MIN;
+ }
+ else {
+ *overflow = sign;
+ /* res is already set to -1 */
+ }
+ }
+ exit:
+ if (do_decref) {
+ Py_DECREF(vv);
+ }
+ return res;
+}
+
+/* Get a C long int from a long int object.
+ Returns -1 and sets an error condition if overflow occurs. */
+
+long
+PyLong_AsLong(PyObject *obj)
+{
+ int overflow;
+ long result = PyLong_AsLongAndOverflow(obj, &overflow);
+ if (overflow) {
+ /* XXX: could be cute and give a different
+ message for overflow == -1 */
+ PyErr_SetString(PyExc_OverflowError,
+ "Python int too large to convert to C long");
+ }
+ return result;
+}
+
+/* Get a C int from a long int object or any object that has an __int__
+ method. Return -1 and set an error if overflow occurs. */
+
+int
+_PyLong_AsInt(PyObject *obj)
+{
+ int overflow;
+ long result = PyLong_AsLongAndOverflow(obj, &overflow);
+ if (overflow || result > INT_MAX || result < INT_MIN) {
+ /* XXX: could be cute and give a different
+ message for overflow == -1 */
+ PyErr_SetString(PyExc_OverflowError,
+ "Python int too large to convert to C int");
+ return -1;
+ }
+ return (int)result;
+}
+
+/* Get a Py_ssize_t from a long int object.
+ Returns -1 and sets an error condition if overflow occurs. */
+
+Py_ssize_t
+PyLong_AsSsize_t(PyObject *vv) {
+ register PyLongObject *v;
+ size_t x, prev;
+ Py_ssize_t i;
+ int sign;
+
+ if (vv == NULL || !PyLong_Check(vv)) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ v = (PyLongObject *)vv;
+ i = v->ob_size;
+ sign = 1;
+ x = 0;
+ if (i < 0) {
+ sign = -1;
+ i = -(i);
+ }
+ while (--i >= 0) {
+ prev = x;
+ x = (x << PyLong_SHIFT) | v->ob_digit[i];
+ if ((x >> PyLong_SHIFT) != prev)
+ goto overflow;
+ }
+ /* Haven't lost any bits, but casting to a signed type requires
+ * extra care (see comment above).
+ */
+ if (x <= (size_t)PY_SSIZE_T_MAX) {
+ return (Py_ssize_t)x * sign;
+ }
+ else if (sign < 0 && x == PY_ABS_SSIZE_T_MIN) {
+ return PY_SSIZE_T_MIN;
+ }
+ /* else overflow */
+
+ overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "long int too large to convert to int");
+ return -1;
+}
+
+/* Get a C unsigned long int from a long int object.
+ Returns -1 and sets an error condition if overflow occurs. */
+
+unsigned long
+PyLong_AsUnsignedLong(PyObject *vv)
+{
+ register PyLongObject *v;
+ unsigned long x, prev;
+ Py_ssize_t i;
+
+ if (vv == NULL || !PyLong_Check(vv)) {
+ if (vv != NULL && PyInt_Check(vv)) {
+ long val = PyInt_AsLong(vv);
+ if (val < 0) {
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value "
+ "to unsigned long");
+ return (unsigned long) -1;
+ }
+ return val;
+ }
+ PyErr_BadInternalCall();
+ return (unsigned long) -1;
+ }
+ v = (PyLongObject *)vv;
+ i = Py_SIZE(v);
+ x = 0;
+ if (i < 0) {
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to unsigned long");
+ return (unsigned long) -1;
+ }
+ while (--i >= 0) {
+ prev = x;
+ x = (x << PyLong_SHIFT) | v->ob_digit[i];
+ if ((x >> PyLong_SHIFT) != prev) {
+ PyErr_SetString(PyExc_OverflowError,
+ "long int too large to convert");
+ return (unsigned long) -1;
+ }
+ }
+ return x;
+}
+
+/* Get a C unsigned long int from a long int object, ignoring the high bits.
+ Returns -1 and sets an error condition if an error occurs. */
+
+unsigned long
+PyLong_AsUnsignedLongMask(PyObject *vv)
+{
+ register PyLongObject *v;
+ unsigned long x;
+ Py_ssize_t i;
+ int sign;
+
+ if (vv == NULL || !PyLong_Check(vv)) {
+ if (vv != NULL && PyInt_Check(vv))
+ return PyInt_AsUnsignedLongMask(vv);
+ PyErr_BadInternalCall();
+ return (unsigned long) -1;
+ }
+ v = (PyLongObject *)vv;
+ i = v->ob_size;
+ sign = 1;
+ x = 0;
+ if (i < 0) {
+ sign = -1;
+ i = -i;
+ }
+ while (--i >= 0) {
+ x = (x << PyLong_SHIFT) | v->ob_digit[i];
+ }
+ return x * sign;
+}
+
+int
+_PyLong_Sign(PyObject *vv)
+{
+ PyLongObject *v = (PyLongObject *)vv;
+
+ assert(v != NULL);
+ assert(PyLong_Check(v));
+
+ return Py_SIZE(v) == 0 ? 0 : (Py_SIZE(v) < 0 ? -1 : 1);
+}
+
+size_t
+_PyLong_NumBits(PyObject *vv)
+{
+ PyLongObject *v = (PyLongObject *)vv;
+ size_t result = 0;
+ Py_ssize_t ndigits;
+
+ assert(v != NULL);
+ assert(PyLong_Check(v));
+ ndigits = ABS(Py_SIZE(v));
+ assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0);
+ if (ndigits > 0) {
+ digit msd = v->ob_digit[ndigits - 1];
+
+ result = (ndigits - 1) * PyLong_SHIFT;
+ if (result / PyLong_SHIFT != (size_t)(ndigits - 1))
+ goto Overflow;
+ do {
+ ++result;
+ if (result == 0)
+ goto Overflow;
+ msd >>= 1;
+ } while (msd);
+ }
+ return result;
+
+ Overflow:
+ PyErr_SetString(PyExc_OverflowError, "long has too many bits "
+ "to express in a platform size_t");
+ return (size_t)-1;
+}
+
+PyObject *
+_PyLong_FromByteArray(const unsigned char* bytes, size_t n,
+ int little_endian, int is_signed)
+{
+ const unsigned char* pstartbyte; /* LSB of bytes */
+ int incr; /* direction to move pstartbyte */
+ const unsigned char* pendbyte; /* MSB of bytes */
+ size_t numsignificantbytes; /* number of bytes that matter */
+ Py_ssize_t ndigits; /* number of Python long digits */
+ PyLongObject* v; /* result */
+ Py_ssize_t idigit = 0; /* next free index in v->ob_digit */
+
+ if (n == 0)
+ return PyLong_FromLong(0L);
+
+ if (little_endian) {
+ pstartbyte = bytes;
+ pendbyte = bytes + n - 1;
+ incr = 1;
+ }
+ else {
+ pstartbyte = bytes + n - 1;
+ pendbyte = bytes;
+ incr = -1;
+ }
+
+ if (is_signed)
+ is_signed = *pendbyte >= 0x80;
+
+ /* Compute numsignificantbytes. This consists of finding the most
+ significant byte. Leading 0 bytes are insignificant if the number
+ is positive, and leading 0xff bytes if negative. */
+ {
+ size_t i;
+ const unsigned char* p = pendbyte;
+ const int pincr = -incr; /* search MSB to LSB */
+ const unsigned char insignficant = is_signed ? 0xff : 0x00;
+
+ for (i = 0; i < n; ++i, p += pincr) {
+ if (*p != insignficant)
+ break;
+ }
+ numsignificantbytes = n - i;
+ /* 2's-comp is a bit tricky here, e.g. 0xff00 == -0x0100, so
+ actually has 2 significant bytes. OTOH, 0xff0001 ==
+ -0x00ffff, so we wouldn't *need* to bump it there; but we
+ do for 0xffff = -0x0001. To be safe without bothering to
+ check every case, bump it regardless. */
+ if (is_signed && numsignificantbytes < n)
+ ++numsignificantbytes;
+ }
+
+ /* How many Python long digits do we need? We have
+ 8*numsignificantbytes bits, and each Python long digit has
+ PyLong_SHIFT bits, so it's the ceiling of the quotient. */
+ /* catch overflow before it happens */
+ if (numsignificantbytes > (PY_SSIZE_T_MAX - PyLong_SHIFT) / 8) {
+ PyErr_SetString(PyExc_OverflowError,
+ "byte array too long to convert to int");
+ return NULL;
+ }
+ ndigits = (numsignificantbytes * 8 + PyLong_SHIFT - 1) / PyLong_SHIFT;
+ v = _PyLong_New(ndigits);
+ if (v == NULL)
+ return NULL;
+
+ /* Copy the bits over. The tricky parts are computing 2's-comp on
+ the fly for signed numbers, and dealing with the mismatch between
+ 8-bit bytes and (probably) 15-bit Python digits.*/
+ {
+ size_t i;
+ twodigits carry = 1; /* for 2's-comp calculation */
+ twodigits accum = 0; /* sliding register */
+ unsigned int accumbits = 0; /* number of bits in accum */
+ const unsigned char* p = pstartbyte;
+
+ for (i = 0; i < numsignificantbytes; ++i, p += incr) {
+ twodigits thisbyte = *p;
+ /* Compute correction for 2's comp, if needed. */
+ if (is_signed) {
+ thisbyte = (0xff ^ thisbyte) + carry;
+ carry = thisbyte >> 8;
+ thisbyte &= 0xff;
+ }
+ /* Because we're going LSB to MSB, thisbyte is
+ more significant than what's already in accum,
+ so needs to be prepended to accum. */
+ accum |= (twodigits)thisbyte << accumbits;
+ accumbits += 8;
+ if (accumbits >= PyLong_SHIFT) {
+ /* There's enough to fill a Python digit. */
+ assert(idigit < ndigits);
+ v->ob_digit[idigit] = (digit)(accum & PyLong_MASK);
+ ++idigit;
+ accum >>= PyLong_SHIFT;
+ accumbits -= PyLong_SHIFT;
+ assert(accumbits < PyLong_SHIFT);
+ }
+ }
+ assert(accumbits < PyLong_SHIFT);
+ if (accumbits) {
+ assert(idigit < ndigits);
+ v->ob_digit[idigit] = (digit)accum;
+ ++idigit;
+ }
+ }
+
+ Py_SIZE(v) = is_signed ? -idigit : idigit;
+ return (PyObject *)long_normalize(v);
+}
+
+int
+_PyLong_AsByteArray(PyLongObject* v,
+ unsigned char* bytes, size_t n,
+ int little_endian, int is_signed)
+{
+ Py_ssize_t i; /* index into v->ob_digit */
+ Py_ssize_t ndigits; /* |v->ob_size| */
+ twodigits accum; /* sliding register */
+ unsigned int accumbits; /* # bits in accum */
+ int do_twos_comp; /* store 2's-comp? is_signed and v < 0 */
+ digit carry; /* for computing 2's-comp */
+ size_t j; /* # bytes filled */
+ unsigned char* p; /* pointer to next byte in bytes */
+ int pincr; /* direction to move p */
+
+ assert(v != NULL && PyLong_Check(v));
+
+ if (Py_SIZE(v) < 0) {
+ ndigits = -(Py_SIZE(v));
+ if (!is_signed) {
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative long to unsigned");
+ return -1;
+ }
+ do_twos_comp = 1;
+ }
+ else {
+ ndigits = Py_SIZE(v);
+ do_twos_comp = 0;
+ }
+
+ if (little_endian) {
+ p = bytes;
+ pincr = 1;
+ }
+ else {
+ p = bytes + n - 1;
+ pincr = -1;
+ }
+
+ /* Copy over all the Python digits.
+ It's crucial that every Python digit except for the MSD contribute
+ exactly PyLong_SHIFT bits to the total, so first assert that the long is
+ normalized. */
+ assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0);
+ j = 0;
+ accum = 0;
+ accumbits = 0;
+ carry = do_twos_comp ? 1 : 0;
+ for (i = 0; i < ndigits; ++i) {
+ digit thisdigit = v->ob_digit[i];
+ if (do_twos_comp) {
+ thisdigit = (thisdigit ^ PyLong_MASK) + carry;
+ carry = thisdigit >> PyLong_SHIFT;
+ thisdigit &= PyLong_MASK;
+ }
+ /* Because we're going LSB to MSB, thisdigit is more
+ significant than what's already in accum, so needs to be
+ prepended to accum. */
+ accum |= (twodigits)thisdigit << accumbits;
+
+ /* The most-significant digit may be (probably is) at least
+ partly empty. */
+ if (i == ndigits - 1) {
+ /* Count # of sign bits -- they needn't be stored,
+ * although for signed conversion we need later to
+ * make sure at least one sign bit gets stored. */
+ digit s = do_twos_comp ? thisdigit ^ PyLong_MASK : thisdigit;
+ while (s != 0) {
+ s >>= 1;
+ accumbits++;
+ }
+ }
+ else
+ accumbits += PyLong_SHIFT;
+
+ /* Store as many bytes as possible. */
+ while (accumbits >= 8) {
+ if (j >= n)
+ goto Overflow;
+ ++j;
+ *p = (unsigned char)(accum & 0xff);
+ p += pincr;
+ accumbits -= 8;
+ accum >>= 8;
+ }
+ }
+
+ /* Store the straggler (if any). */
+ assert(accumbits < 8);
+ assert(carry == 0); /* else do_twos_comp and *every* digit was 0 */
+ if (accumbits > 0) {
+ if (j >= n)
+ goto Overflow;
+ ++j;
+ if (do_twos_comp) {
+ /* Fill leading bits of the byte with sign bits
+ (appropriately pretending that the long had an
+ infinite supply of sign bits). */
+ accum |= (~(twodigits)0) << accumbits;
+ }
+ *p = (unsigned char)(accum & 0xff);
+ p += pincr;
+ }
+ else if (j == n && n > 0 && is_signed) {
+ /* The main loop filled the byte array exactly, so the code
+ just above didn't get to ensure there's a sign bit, and the
+ loop below wouldn't add one either. Make sure a sign bit
+ exists. */
+ unsigned char msb = *(p - pincr);
+ int sign_bit_set = msb >= 0x80;
+ assert(accumbits == 0);
+ if (sign_bit_set == do_twos_comp)
+ return 0;
+ else
+ goto Overflow;
+ }
+
+ /* Fill remaining bytes with copies of the sign bit. */
+ {
+ unsigned char signbyte = do_twos_comp ? 0xffU : 0U;
+ for ( ; j < n; ++j, p += pincr)
+ *p = signbyte;
+ }
+
+ return 0;
+
+ Overflow:
+ PyErr_SetString(PyExc_OverflowError, "long too big to convert");
+ return -1;
+
+}
+
+/* Create a new long (or int) object from a C pointer */
+
+PyObject *
+PyLong_FromVoidPtr(void *p)
+{
+#if SIZEOF_VOID_P <= SIZEOF_LONG
+ if ((long)p < 0)
+ return PyLong_FromUnsignedLong((unsigned long)p);
+ return PyInt_FromLong((long)p);
+#else
+
+#ifndef HAVE_LONG_LONG
+# error "PyLong_FromVoidPtr: sizeof(void*) > sizeof(long), but no long long"
+#endif
+#if SIZEOF_LONG_LONG < SIZEOF_VOID_P
+# error "PyLong_FromVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)"
+#endif
+ /* optimize null pointers */
+ if (p == NULL)
+ return PyInt_FromLong(0);
+ return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)p);
+
+#endif /* SIZEOF_VOID_P <= SIZEOF_LONG */
+}
+
+/* Get a C pointer from a long object (or an int object in some cases) */
+
+void *
+PyLong_AsVoidPtr(PyObject *vv)
+{
+ /* This function will allow int or long objects. If vv is neither,
+ then the PyLong_AsLong*() functions will raise the exception:
+ PyExc_SystemError, "bad argument to internal function"
+ */
+#if SIZEOF_VOID_P <= SIZEOF_LONG
+ long x;
+
+ if (PyInt_Check(vv))
+ x = PyInt_AS_LONG(vv);
+ else if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0)
+ x = PyLong_AsLong(vv);
+ else
+ x = PyLong_AsUnsignedLong(vv);
+#else
+
+#ifndef HAVE_LONG_LONG
+# error "PyLong_AsVoidPtr: sizeof(void*) > sizeof(long), but no long long"
+#endif
+#if SIZEOF_LONG_LONG < SIZEOF_VOID_P
+# error "PyLong_AsVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)"
+#endif
+ PY_LONG_LONG x;
+
+ if (PyInt_Check(vv))
+ x = PyInt_AS_LONG(vv);
+ else if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0)
+ x = PyLong_AsLongLong(vv);
+ else
+ x = PyLong_AsUnsignedLongLong(vv);
+
+#endif /* SIZEOF_VOID_P <= SIZEOF_LONG */
+
+ if (x == -1 && PyErr_Occurred())
+ return NULL;
+ return (void *)x;
+}
+
+#ifdef HAVE_LONG_LONG
+
+/* Initial PY_LONG_LONG support by Chris Herborth (chrish@qnx.com), later
+ * rewritten to use the newer PyLong_{As,From}ByteArray API.
+ */
+
+#define IS_LITTLE_ENDIAN (int)*(unsigned char*)&one
+#define PY_ABS_LLONG_MIN (0-(unsigned PY_LONG_LONG)PY_LLONG_MIN)
+
+/* Create a new long int object from a C PY_LONG_LONG int. */
+
+PyObject *
+PyLong_FromLongLong(PY_LONG_LONG ival)
+{
+ PyLongObject *v;
+ unsigned PY_LONG_LONG abs_ival;
+ unsigned PY_LONG_LONG t; /* unsigned so >> doesn't propagate sign bit */
+ int ndigits = 0;
+ int negative = 0;
+
+ if (ival < 0) {
+ /* avoid signed overflow on negation; see comments
+ in PyLong_FromLong above. */
+ abs_ival = (unsigned PY_LONG_LONG)(-1-ival) + 1;
+ negative = 1;
+ }
+ else {
+ abs_ival = (unsigned PY_LONG_LONG)ival;
+ }
+
+ /* Count the number of Python digits.
+ We used to pick 5 ("big enough for anything"), but that's a
+ waste of time and space given that 5*15 = 75 bits are rarely
+ needed. */
+ t = abs_ival;
+ while (t) {
+ ++ndigits;
+ t >>= PyLong_SHIFT;
+ }
+ v = _PyLong_New(ndigits);
+ if (v != NULL) {
+ digit *p = v->ob_digit;
+ Py_SIZE(v) = negative ? -ndigits : ndigits;
+ t = abs_ival;
+ while (t) {
+ *p++ = (digit)(t & PyLong_MASK);
+ t >>= PyLong_SHIFT;
+ }
+ }
+ return (PyObject *)v;
+}
+
+/* Create a new long int object from a C unsigned PY_LONG_LONG int. */
+
+PyObject *
+PyLong_FromUnsignedLongLong(unsigned PY_LONG_LONG ival)
+{
+ PyLongObject *v;
+ unsigned PY_LONG_LONG t;
+ int ndigits = 0;
+
+ /* Count the number of Python digits. */
+ t = (unsigned PY_LONG_LONG)ival;
+ while (t) {
+ ++ndigits;
+ t >>= PyLong_SHIFT;
+ }
+ v = _PyLong_New(ndigits);
+ if (v != NULL) {
+ digit *p = v->ob_digit;
+ Py_SIZE(v) = ndigits;
+ while (ival) {
+ *p++ = (digit)(ival & PyLong_MASK);
+ ival >>= PyLong_SHIFT;
+ }
+ }
+ return (PyObject *)v;
+}
+
+/* Create a new long int object from a C Py_ssize_t. */
+
+PyObject *
+PyLong_FromSsize_t(Py_ssize_t ival)
+{
+ Py_ssize_t bytes = ival;
+ int one = 1;
+ return _PyLong_FromByteArray((unsigned char *)&bytes,
+ SIZEOF_SIZE_T, IS_LITTLE_ENDIAN, 1);
+}
+
+/* Create a new long int object from a C size_t. */
+
+PyObject *
+PyLong_FromSize_t(size_t ival)
+{
+ size_t bytes = ival;
+ int one = 1;
+ return _PyLong_FromByteArray((unsigned char *)&bytes,
+ SIZEOF_SIZE_T, IS_LITTLE_ENDIAN, 0);
+}
+
+/* Get a C PY_LONG_LONG int from a long int object.
+ Return -1 and set an error if overflow occurs. */
+
+PY_LONG_LONG
+PyLong_AsLongLong(PyObject *vv)
+{
+ PY_LONG_LONG bytes;
+ int one = 1;
+ int res;
+
+ if (vv == NULL) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ if (!PyLong_Check(vv)) {
+ PyNumberMethods *nb;
+ PyObject *io;
+ if (PyInt_Check(vv))
+ return (PY_LONG_LONG)PyInt_AsLong(vv);
+ if ((nb = vv->ob_type->tp_as_number) == NULL ||
+ nb->nb_int == NULL) {
+ PyErr_SetString(PyExc_TypeError, "an integer is required");
+ return -1;
+ }
+ io = (*nb->nb_int) (vv);
+ if (io == NULL)
+ return -1;
+ if (PyInt_Check(io)) {
+ bytes = PyInt_AsLong(io);
+ Py_DECREF(io);
+ return bytes;
+ }
+ if (PyLong_Check(io)) {
+ bytes = PyLong_AsLongLong(io);
+ Py_DECREF(io);
+ return bytes;
+ }
+ Py_DECREF(io);
+ PyErr_SetString(PyExc_TypeError, "integer conversion failed");
+ return -1;
+ }
+
+ res = _PyLong_AsByteArray((PyLongObject *)vv, (unsigned char *)&bytes,
+ SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 1);
+
+ /* Plan 9 can't handle PY_LONG_LONG in ? : expressions */
+ if (res < 0)
+ return (PY_LONG_LONG)-1;
+ else
+ return bytes;
+}
+
+/* Get a C unsigned PY_LONG_LONG int from a long int object.
+ Return -1 and set an error if overflow occurs. */
+
+unsigned PY_LONG_LONG
+PyLong_AsUnsignedLongLong(PyObject *vv)
+{
+ unsigned PY_LONG_LONG bytes;
+ int one = 1;
+ int res;
+
+ if (vv == NULL || !PyLong_Check(vv)) {
+ PyErr_BadInternalCall();
+ return (unsigned PY_LONG_LONG)-1;
+ }
+
+ res = _PyLong_AsByteArray((PyLongObject *)vv, (unsigned char *)&bytes,
+ SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 0);
+
+ /* Plan 9 can't handle PY_LONG_LONG in ? : expressions */
+ if (res < 0)
+ return (unsigned PY_LONG_LONG)res;
+ else
+ return bytes;
+}
+
+/* Get a C unsigned long int from a long int object, ignoring the high bits.
+ Returns -1 and sets an error condition if an error occurs. */
+
+unsigned PY_LONG_LONG
+PyLong_AsUnsignedLongLongMask(PyObject *vv)
+{
+ register PyLongObject *v;
+ unsigned PY_LONG_LONG x;
+ Py_ssize_t i;
+ int sign;
+
+ if (vv == NULL || !PyLong_Check(vv)) {
+ PyErr_BadInternalCall();
+ return (unsigned long) -1;
+ }
+ v = (PyLongObject *)vv;
+ i = v->ob_size;
+ sign = 1;
+ x = 0;
+ if (i < 0) {
+ sign = -1;
+ i = -i;
+ }
+ while (--i >= 0) {
+ x = (x << PyLong_SHIFT) | v->ob_digit[i];
+ }
+ return x * sign;
+}
+
+/* Get a C long long int from a Python long or Python int object.
+ On overflow, returns -1 and sets *overflow to 1 or -1 depending
+ on the sign of the result. Otherwise *overflow is 0.
+
+ For other errors (e.g., type error), returns -1 and sets an error
+ condition.
+*/
+
+PY_LONG_LONG
+PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow)
+{
+ /* This version by Tim Peters */
+ register PyLongObject *v;
+ unsigned PY_LONG_LONG x, prev;
+ PY_LONG_LONG res;
+ Py_ssize_t i;
+ int sign;
+ int do_decref = 0; /* if nb_int was called */
+
+ *overflow = 0;
+ if (vv == NULL) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+
+ if (PyInt_Check(vv))
+ return PyInt_AsLong(vv);
+
+ if (!PyLong_Check(vv)) {
+ PyNumberMethods *nb;
+ nb = vv->ob_type->tp_as_number;
+ if (nb == NULL || nb->nb_int == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "an integer is required");
+ return -1;
+ }
+ vv = (*nb->nb_int) (vv);
+ if (vv == NULL)
+ return -1;
+ do_decref = 1;
+ if(PyInt_Check(vv)) {
+ res = PyInt_AsLong(vv);
+ goto exit;
+ }
+ if (!PyLong_Check(vv)) {
+ Py_DECREF(vv);
+ PyErr_SetString(PyExc_TypeError,
+ "nb_int should return int object");
+ return -1;
+ }
+ }
+
+ res = -1;
+ v = (PyLongObject *)vv;
+ i = Py_SIZE(v);
+
+ switch (i) {
+ case -1:
+ res = -(sdigit)v->ob_digit[0];
+ break;
+ case 0:
+ res = 0;
+ break;
+ case 1:
+ res = v->ob_digit[0];
+ break;
+ default:
+ sign = 1;
+ x = 0;
+ if (i < 0) {
+ sign = -1;
+ i = -(i);
+ }
+ while (--i >= 0) {
+ prev = x;
+ x = (x << PyLong_SHIFT) + v->ob_digit[i];
+ if ((x >> PyLong_SHIFT) != prev) {
+ *overflow = sign;
+ goto exit;
+ }
+ }
+ /* Haven't lost any bits, but casting to long requires extra
+ * care (see comment above).
+ */
+ if (x <= (unsigned PY_LONG_LONG)PY_LLONG_MAX) {
+ res = (PY_LONG_LONG)x * sign;
+ }
+ else if (sign < 0 && x == PY_ABS_LLONG_MIN) {
+ res = PY_LLONG_MIN;
+ }
+ else {
+ *overflow = sign;
+ /* res is already set to -1 */
+ }
+ }
+ exit:
+ if (do_decref) {
+ Py_DECREF(vv);
+ }
+ return res;
+}
+
+#undef IS_LITTLE_ENDIAN
+
+#endif /* HAVE_LONG_LONG */
+
+
+static int
+convert_binop(PyObject *v, PyObject *w, PyLongObject **a, PyLongObject **b) {
+ if (PyLong_Check(v)) {
+ *a = (PyLongObject *) v;
+ Py_INCREF(v);
+ }
+ else if (PyInt_Check(v)) {
+ *a = (PyLongObject *) PyLong_FromLong(PyInt_AS_LONG(v));
+ }
+ else {
+ return 0;
+ }
+ if (PyLong_Check(w)) {
+ *b = (PyLongObject *) w;
+ Py_INCREF(w);
+ }
+ else if (PyInt_Check(w)) {
+ *b = (PyLongObject *) PyLong_FromLong(PyInt_AS_LONG(w));
+ }
+ else {
+ Py_DECREF(*a);
+ return 0;
+ }
+ return 1;
+}
+
+#define CONVERT_BINOP(v, w, a, b) \
+ do { \
+ if (!convert_binop(v, w, a, b)) { \
+ Py_INCREF(Py_NotImplemented); \
+ return Py_NotImplemented; \
+ } \
+ } while(0) \
+
+/* bits_in_digit(d) returns the unique integer k such that 2**(k-1) <= d <
+ 2**k if d is nonzero, else 0. */
+
+static const unsigned char BitLengthTable[32] = {
+ 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+};
+
+static int
+bits_in_digit(digit d)
+{
+ int d_bits = 0;
+ while (d >= 32) {
+ d_bits += 6;
+ d >>= 6;
+ }
+ d_bits += (int)BitLengthTable[d];
+ return d_bits;
+}
+
+/* x[0:m] and y[0:n] are digit vectors, LSD first, m >= n required. x[0:n]
+ * is modified in place, by adding y to it. Carries are propagated as far as
+ * x[m-1], and the remaining carry (0 or 1) is returned.
+ */
+static digit
+v_iadd(digit *x, Py_ssize_t m, digit *y, Py_ssize_t n)
+{
+ Py_ssize_t i;
+ digit carry = 0;
+
+ assert(m >= n);
+ for (i = 0; i < n; ++i) {
+ carry += x[i] + y[i];
+ x[i] = carry & PyLong_MASK;
+ carry >>= PyLong_SHIFT;
+ assert((carry & 1) == carry);
+ }
+ for (; carry && i < m; ++i) {
+ carry += x[i];
+ x[i] = carry & PyLong_MASK;
+ carry >>= PyLong_SHIFT;
+ assert((carry & 1) == carry);
+ }
+ return carry;
+}
+
+/* x[0:m] and y[0:n] are digit vectors, LSD first, m >= n required. x[0:n]
+ * is modified in place, by subtracting y from it. Borrows are propagated as
+ * far as x[m-1], and the remaining borrow (0 or 1) is returned.
+ */
+static digit
+v_isub(digit *x, Py_ssize_t m, digit *y, Py_ssize_t n)
+{
+ Py_ssize_t i;
+ digit borrow = 0;
+
+ assert(m >= n);
+ for (i = 0; i < n; ++i) {
+ borrow = x[i] - y[i] - borrow;
+ x[i] = borrow & PyLong_MASK;
+ borrow >>= PyLong_SHIFT;
+ borrow &= 1; /* keep only 1 sign bit */
+ }
+ for (; borrow && i < m; ++i) {
+ borrow = x[i] - borrow;
+ x[i] = borrow & PyLong_MASK;
+ borrow >>= PyLong_SHIFT;
+ borrow &= 1;
+ }
+ return borrow;
+}
+
+/* Shift digit vector a[0:m] d bits left, with 0 <= d < PyLong_SHIFT. Put
+ * result in z[0:m], and return the d bits shifted out of the top.
+ */
+static digit
+v_lshift(digit *z, digit *a, Py_ssize_t m, int d)
+{
+ Py_ssize_t i;
+ digit carry = 0;
+
+ assert(0 <= d && d < PyLong_SHIFT);
+ for (i=0; i < m; i++) {
+ twodigits acc = (twodigits)a[i] << d | carry;
+ z[i] = (digit)acc & PyLong_MASK;
+ carry = (digit)(acc >> PyLong_SHIFT);
+ }
+ return carry;
+}
+
+/* Shift digit vector a[0:m] d bits right, with 0 <= d < PyLong_SHIFT. Put
+ * result in z[0:m], and return the d bits shifted out of the bottom.
+ */
+static digit
+v_rshift(digit *z, digit *a, Py_ssize_t m, int d)
+{
+ Py_ssize_t i;
+ digit carry = 0;
+ digit mask = ((digit)1 << d) - 1U;
+
+ assert(0 <= d && d < PyLong_SHIFT);
+ for (i=m; i-- > 0;) {
+ twodigits acc = (twodigits)carry << PyLong_SHIFT | a[i];
+ carry = (digit)acc & mask;
+ z[i] = (digit)(acc >> d);
+ }
+ return carry;
+}
+
+/* Divide long pin, w/ size digits, by non-zero digit n, storing quotient
+ in pout, and returning the remainder. pin and pout point at the LSD.
+ It's OK for pin == pout on entry, which saves oodles of mallocs/frees in
+ _PyLong_Format, but that should be done with great care since longs are
+ immutable. */
+
+static digit
+inplace_divrem1(digit *pout, digit *pin, Py_ssize_t size, digit n)
+{
+ twodigits rem = 0;
+
+ assert(n > 0 && n <= PyLong_MASK);
+ pin += size;
+ pout += size;
+ while (--size >= 0) {
+ digit hi;
+ rem = (rem << PyLong_SHIFT) | *--pin;
+ *--pout = hi = (digit)(rem / n);
+ rem -= (twodigits)hi * n;
+ }
+ return (digit)rem;
+}
+
+/* Divide a long integer by a digit, returning both the quotient
+ (as function result) and the remainder (through *prem).
+ The sign of a is ignored; n should not be zero. */
+
+static PyLongObject *
+divrem1(PyLongObject *a, digit n, digit *prem)
+{
+ const Py_ssize_t size = ABS(Py_SIZE(a));
+ PyLongObject *z;
+
+ assert(n > 0 && n <= PyLong_MASK);
+ z = _PyLong_New(size);
+ if (z == NULL)
+ return NULL;
+ *prem = inplace_divrem1(z->ob_digit, a->ob_digit, size, n);
+ return long_normalize(z);
+}
+
+/* Convert a long integer to a base 10 string. Returns a new non-shared
+ string. (Return value is non-shared so that callers can modify the
+ returned value if necessary.) */
+
+static PyObject *
+long_to_decimal_string(PyObject *aa, int addL)
+{
+ PyLongObject *scratch, *a;
+ PyObject *str;
+ Py_ssize_t size, strlen, size_a, i, j;
+ digit *pout, *pin, rem, tenpow;
+ char *p;
+ int negative;
+
+ a = (PyLongObject *)aa;
+ if (a == NULL || !PyLong_Check(a)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ size_a = ABS(Py_SIZE(a));
+ negative = Py_SIZE(a) < 0;
+
+ /* quick and dirty upper bound for the number of digits
+ required to express a in base _PyLong_DECIMAL_BASE:
+
+ #digits = 1 + floor(log2(a) / log2(_PyLong_DECIMAL_BASE))
+
+ But log2(a) < size_a * PyLong_SHIFT, and
+ log2(_PyLong_DECIMAL_BASE) = log2(10) * _PyLong_DECIMAL_SHIFT
+ > 3 * _PyLong_DECIMAL_SHIFT
+ */
+ if (size_a > PY_SSIZE_T_MAX / PyLong_SHIFT) {
+ PyErr_SetString(PyExc_OverflowError,
+ "long is too large to format");
+ return NULL;
+ }
+ /* the expression size_a * PyLong_SHIFT is now safe from overflow */
+ size = 1 + size_a * PyLong_SHIFT / (3 * _PyLong_DECIMAL_SHIFT);
+ scratch = _PyLong_New(size);
+ if (scratch == NULL)
+ return NULL;
+
+ /* convert array of base _PyLong_BASE digits in pin to an array of
+ base _PyLong_DECIMAL_BASE digits in pout, following Knuth (TAOCP,
+ Volume 2 (3rd edn), section 4.4, Method 1b). */
+ pin = a->ob_digit;
+ pout = scratch->ob_digit;
+ size = 0;
+ for (i = size_a; --i >= 0; ) {
+ digit hi = pin[i];
+ for (j = 0; j < size; j++) {
+ twodigits z = (twodigits)pout[j] << PyLong_SHIFT | hi;
+ hi = (digit)(z / _PyLong_DECIMAL_BASE);
+ pout[j] = (digit)(z - (twodigits)hi *
+ _PyLong_DECIMAL_BASE);
+ }
+ while (hi) {
+ pout[size++] = hi % _PyLong_DECIMAL_BASE;
+ hi /= _PyLong_DECIMAL_BASE;
+ }
+ /* check for keyboard interrupt */
+ SIGCHECK({
+ Py_DECREF(scratch);
+ return NULL;
+ });
+ }
+ /* pout should have at least one digit, so that the case when a = 0
+ works correctly */
+ if (size == 0)
+ pout[size++] = 0;
+
+ /* calculate exact length of output string, and allocate */
+ strlen = (addL != 0) + negative +
+ 1 + (size - 1) * _PyLong_DECIMAL_SHIFT;
+ tenpow = 10;
+ rem = pout[size-1];
+ while (rem >= tenpow) {
+ tenpow *= 10;
+ strlen++;
+ }
+ str = PyString_FromStringAndSize(NULL, strlen);
+ if (str == NULL) {
+ Py_DECREF(scratch);
+ return NULL;
+ }
+
+ /* fill the string right-to-left */
+ p = PyString_AS_STRING(str) + strlen;
+ *p = '\0';
+ if (addL)
+ *--p = 'L';
+ /* pout[0] through pout[size-2] contribute exactly
+ _PyLong_DECIMAL_SHIFT digits each */
+ for (i=0; i < size - 1; i++) {
+ rem = pout[i];
+ for (j = 0; j < _PyLong_DECIMAL_SHIFT; j++) {
+ *--p = '0' + rem % 10;
+ rem /= 10;
+ }
+ }
+ /* pout[size-1]: always produce at least one decimal digit */
+ rem = pout[i];
+ do {
+ *--p = '0' + rem % 10;
+ rem /= 10;
+ } while (rem != 0);
+
+ /* and sign */
+ if (negative)
+ *--p = '-';
+
+ /* check we've counted correctly */
+ assert(p == PyString_AS_STRING(str));
+ Py_DECREF(scratch);
+ return (PyObject *)str;
+}
+
+/* Convert the long to a string object with given base,
+ appending a base prefix of 0[box] if base is 2, 8 or 16.
+ Add a trailing "L" if addL is non-zero.
+ If newstyle is zero, then use the pre-2.6 behavior of octal having
+ a leading "0", instead of the prefix "0o" */
+PyAPI_FUNC(PyObject *)
+_PyLong_Format(PyObject *aa, int base, int addL, int newstyle)
+{
+ register PyLongObject *a = (PyLongObject *)aa;
+ PyStringObject *str;
+ Py_ssize_t i, sz;
+ Py_ssize_t size_a;
+ char *p;
+ int bits;
+ char sign = '\0';
+
+ if (base == 10)
+ return long_to_decimal_string((PyObject *)a, addL);
+
+ if (a == NULL || !PyLong_Check(a)) {
+ PyErr_BadInternalCall();
+ return NULL;
+ }
+ assert(base >= 2 && base <= 36);
+ size_a = ABS(Py_SIZE(a));
+
+ /* Compute a rough upper bound for the length of the string */
+ i = base;
+ bits = 0;
+ while (i > 1) {
+ ++bits;
+ i >>= 1;
+ }
+ i = 5 + (addL ? 1 : 0);
+ /* ensure we don't get signed overflow in sz calculation */
+ if (size_a > (PY_SSIZE_T_MAX - i) / PyLong_SHIFT) {
+ PyErr_SetString(PyExc_OverflowError,
+ "long is too large to format");
+ return NULL;
+ }
+ sz = i + 1 + (size_a * PyLong_SHIFT - 1) / bits;
+ assert(sz >= 0);
+ str = (PyStringObject *) PyString_FromStringAndSize((char *)0, sz);
+ if (str == NULL)
+ return NULL;
+ p = PyString_AS_STRING(str) + sz;
+ *p = '\0';
+ if (addL)
+ *--p = 'L';
+ if (a->ob_size < 0)
+ sign = '-';
+
+ if (a->ob_size == 0) {
+ *--p = '0';
+ }
+ else if ((base & (base - 1)) == 0) {
+ /* JRH: special case for power-of-2 bases */
+ twodigits accum = 0;
+ int accumbits = 0; /* # of bits in accum */
+ int basebits = 1; /* # of bits in base-1 */
+ i = base;
+ while ((i >>= 1) > 1)
+ ++basebits;
+
+ for (i = 0; i < size_a; ++i) {
+ accum |= (twodigits)a->ob_digit[i] << accumbits;
+ accumbits += PyLong_SHIFT;
+ assert(accumbits >= basebits);
+ do {
+ char cdigit = (char)(accum & (base - 1));
+ cdigit += (cdigit < 10) ? '0' : 'a'-10;
+ assert(p > PyString_AS_STRING(str));
+ *--p = cdigit;
+ accumbits -= basebits;
+ accum >>= basebits;
+ } while (i < size_a-1 ? accumbits >= basebits : accum > 0);
+ }
+ }
+ else {
+ /* Not 0, and base not a power of 2. Divide repeatedly by
+ base, but for speed use the highest power of base that
+ fits in a digit. */
+ Py_ssize_t size = size_a;
+ digit *pin = a->ob_digit;
+ PyLongObject *scratch;
+ /* powbasw <- largest power of base that fits in a digit. */
+ digit powbase = base; /* powbase == base ** power */
+ int power = 1;
+ for (;;) {
+ twodigits newpow = powbase * (twodigits)base;
+ if (newpow >> PyLong_SHIFT)
+ /* doesn't fit in a digit */
+ break;
+ powbase = (digit)newpow;
+ ++power;
+ }
+
+ /* Get a scratch area for repeated division. */
+ scratch = _PyLong_New(size);
+ if (scratch == NULL) {
+ Py_DECREF(str);
+ return NULL;
+ }
+
+ /* Repeatedly divide by powbase. */
+ do {
+ int ntostore = power;
+ digit rem = inplace_divrem1(scratch->ob_digit,
+ pin, size, powbase);
+ pin = scratch->ob_digit; /* no need to use a again */
+ if (pin[size - 1] == 0)
+ --size;
+ SIGCHECK({
+ Py_DECREF(scratch);
+ Py_DECREF(str);
+ return NULL;
+ });
+
+ /* Break rem into digits. */
+ assert(ntostore > 0);
+ do {
+ digit nextrem = (digit)(rem / base);
+ char c = (char)(rem - nextrem * base);
+ assert(p > PyString_AS_STRING(str));
+ c += (c < 10) ? '0' : 'a'-10;
+ *--p = c;
+ rem = nextrem;
+ --ntostore;
+ /* Termination is a bit delicate: must not
+ store leading zeroes, so must get out if
+ remaining quotient and rem are both 0. */
+ } while (ntostore && (size || rem));
+ } while (size != 0);
+ Py_DECREF(scratch);
+ }
+
+ if (base == 2) {
+ *--p = 'b';
+ *--p = '0';
+ }
+ else if (base == 8) {
+ if (newstyle) {
+ *--p = 'o';
+ *--p = '0';
+ }
+ else
+ if (size_a != 0)
+ *--p = '0';
+ }
+ else if (base == 16) {
+ *--p = 'x';
+ *--p = '0';
+ }
+ else if (base != 10) {
+ *--p = '#';
+ *--p = '0' + base%10;
+ if (base > 10)
+ *--p = '0' + base/10;
+ }
+ if (sign)
+ *--p = sign;
+ if (p != PyString_AS_STRING(str)) {
+ char *q = PyString_AS_STRING(str);
+ assert(p > q);
+ do {
+ } while ((*q++ = *p++) != '\0');
+ q--;
+ _PyString_Resize((PyObject **)&str,
+ (Py_ssize_t) (q - PyString_AS_STRING(str)));
+ }
+ return (PyObject *)str;
+}
+
+/* Table of digit values for 8-bit string -> integer conversion.
+ * '0' maps to 0, ..., '9' maps to 9.
+ * 'a' and 'A' map to 10, ..., 'z' and 'Z' map to 35.
+ * All other indices map to 37.
+ * Note that when converting a base B string, a char c is a legitimate
+ * base B digit iff _PyLong_DigitValue[Py_CHARMASK(c)] < B.
+ */
+int _PyLong_DigitValue[256] = {
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 37, 37, 37, 37, 37, 37,
+ 37, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 37, 37, 37, 37, 37,
+ 37, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+};
+
+/* *str points to the first digit in a string of base `base` digits. base
+ * is a power of 2 (2, 4, 8, 16, or 32). *str is set to point to the first
+ * non-digit (which may be *str!). A normalized long is returned.
+ * The point to this routine is that it takes time linear in the number of
+ * string characters.
+ */
+static PyLongObject *
+long_from_binary_base(char **str, int base)
+{
+ char *p = *str;
+ char *start = p;
+ int bits_per_char;
+ Py_ssize_t n;
+ PyLongObject *z;
+ twodigits accum;
+ int bits_in_accum;
+ digit *pdigit;
+
+ assert(base >= 2 && base <= 32 && (base & (base - 1)) == 0);
+ n = base;
+ for (bits_per_char = -1; n; ++bits_per_char)
+ n >>= 1;
+ /* n <- total # of bits needed, while setting p to end-of-string */
+ while (_PyLong_DigitValue[Py_CHARMASK(*p)] < base)
+ ++p;
+ *str = p;
+ /* n <- # of Python digits needed, = ceiling(n/PyLong_SHIFT). */
+ n = (p - start) * bits_per_char + PyLong_SHIFT - 1;
+ if (n / bits_per_char < p - start) {
+ PyErr_SetString(PyExc_ValueError,
+ "long string too large to convert");
+ return NULL;
+ }
+ n = n / PyLong_SHIFT;
+ z = _PyLong_New(n);
+ if (z == NULL)
+ return NULL;
+ /* Read string from right, and fill in long from left; i.e.,
+ * from least to most significant in both.
+ */
+ accum = 0;
+ bits_in_accum = 0;
+ pdigit = z->ob_digit;
+ while (--p >= start) {
+ int k = _PyLong_DigitValue[Py_CHARMASK(*p)];
+ assert(k >= 0 && k < base);
+ accum |= (twodigits)k << bits_in_accum;
+ bits_in_accum += bits_per_char;
+ if (bits_in_accum >= PyLong_SHIFT) {
+ *pdigit++ = (digit)(accum & PyLong_MASK);
+ assert(pdigit - z->ob_digit <= n);
+ accum >>= PyLong_SHIFT;
+ bits_in_accum -= PyLong_SHIFT;
+ assert(bits_in_accum < PyLong_SHIFT);
+ }
+ }
+ if (bits_in_accum) {
+ assert(bits_in_accum <= PyLong_SHIFT);
+ *pdigit++ = (digit)accum;
+ assert(pdigit - z->ob_digit <= n);
+ }
+ while (pdigit - z->ob_digit < n)
+ *pdigit++ = 0;
+ return long_normalize(z);
+}
+
+PyObject *
+PyLong_FromString(char *str, char **pend, int base)
+{
+ int sign = 1;
+ char *start, *orig_str = str;
+ PyLongObject *z;
+ PyObject *strobj, *strrepr;
+ Py_ssize_t slen;
+
+ if ((base != 0 && base < 2) || base > 36) {
+ PyErr_SetString(PyExc_ValueError,
+ "long() arg 2 must be >= 2 and <= 36");
+ return NULL;
+ }
+ while (*str != '\0' && isspace(Py_CHARMASK(*str)))
+ str++;
+ if (*str == '+')
+ ++str;
+ else if (*str == '-') {
+ ++str;
+ sign = -1;
+ }
+ while (*str != '\0' && isspace(Py_CHARMASK(*str)))
+ str++;
+ if (base == 0) {
+ /* No base given. Deduce the base from the contents
+ of the string */
+ if (str[0] != '0')
+ base = 10;
+ else if (str[1] == 'x' || str[1] == 'X')
+ base = 16;
+ else if (str[1] == 'o' || str[1] == 'O')
+ base = 8;
+ else if (str[1] == 'b' || str[1] == 'B')
+ base = 2;
+ else
+ /* "old" (C-style) octal literal, still valid in
+ 2.x, although illegal in 3.x */
+ base = 8;
+ }
+ /* Whether or not we were deducing the base, skip leading chars
+ as needed */
+ if (str[0] == '0' &&
+ ((base == 16 && (str[1] == 'x' || str[1] == 'X')) ||
+ (base == 8 && (str[1] == 'o' || str[1] == 'O')) ||
+ (base == 2 && (str[1] == 'b' || str[1] == 'B'))))
+ str += 2;
+
+ start = str;
+ if ((base & (base - 1)) == 0)
+ z = long_from_binary_base(&str, base);
+ else {
+/***
+Binary bases can be converted in time linear in the number of digits, because
+Python's representation base is binary. Other bases (including decimal!) use
+the simple quadratic-time algorithm below, complicated by some speed tricks.
+
+First some math: the largest integer that can be expressed in N base-B digits
+is B**N-1. Consequently, if we have an N-digit input in base B, the worst-
+case number of Python digits needed to hold it is the smallest integer n s.t.
+
+ PyLong_BASE**n-1 >= B**N-1 [or, adding 1 to both sides]
+ PyLong_BASE**n >= B**N [taking logs to base PyLong_BASE]
+ n >= log(B**N)/log(PyLong_BASE) = N * log(B)/log(PyLong_BASE)
+
+The static array log_base_PyLong_BASE[base] == log(base)/log(PyLong_BASE) so
+we can compute this quickly. A Python long with that much space is reserved
+near the start, and the result is computed into it.
+
+The input string is actually treated as being in base base**i (i.e., i digits
+are processed at a time), where two more static arrays hold:
+
+ convwidth_base[base] = the largest integer i such that
+ base**i <= PyLong_BASE
+ convmultmax_base[base] = base ** convwidth_base[base]
+
+The first of these is the largest i such that i consecutive input digits
+must fit in a single Python digit. The second is effectively the input
+base we're really using.
+
+Viewing the input as a sequence <c0, c1, ..., c_n-1> of digits in base
+convmultmax_base[base], the result is "simply"
+
+ (((c0*B + c1)*B + c2)*B + c3)*B + ... ))) + c_n-1
+
+where B = convmultmax_base[base].
+
+Error analysis: as above, the number of Python digits `n` needed is worst-
+case
+
+ n >= N * log(B)/log(PyLong_BASE)
+
+where `N` is the number of input digits in base `B`. This is computed via
+
+ size_z = (Py_ssize_t)((scan - str) * log_base_PyLong_BASE[base]) + 1;
+
+below. Two numeric concerns are how much space this can waste, and whether
+the computed result can be too small. To be concrete, assume PyLong_BASE =
+2**15, which is the default (and it's unlikely anyone changes that).
+
+Waste isn't a problem: provided the first input digit isn't 0, the difference
+between the worst-case input with N digits and the smallest input with N
+digits is about a factor of B, but B is small compared to PyLong_BASE so at
+most one allocated Python digit can remain unused on that count. If
+N*log(B)/log(PyLong_BASE) is mathematically an exact integer, then truncating
+that and adding 1 returns a result 1 larger than necessary. However, that
+can't happen: whenever B is a power of 2, long_from_binary_base() is called
+instead, and it's impossible for B**i to be an integer power of 2**15 when B
+is not a power of 2 (i.e., it's impossible for N*log(B)/log(PyLong_BASE) to be
+an exact integer when B is not a power of 2, since B**i has a prime factor
+other than 2 in that case, but (2**15)**j's only prime factor is 2).
+
+The computed result can be too small if the true value of
+N*log(B)/log(PyLong_BASE) is a little bit larger than an exact integer, but
+due to roundoff errors (in computing log(B), log(PyLong_BASE), their quotient,
+and/or multiplying that by N) yields a numeric result a little less than that
+integer. Unfortunately, "how close can a transcendental function get to an
+integer over some range?" questions are generally theoretically intractable.
+Computer analysis via continued fractions is practical: expand
+log(B)/log(PyLong_BASE) via continued fractions, giving a sequence i/j of "the
+best" rational approximations. Then j*log(B)/log(PyLong_BASE) is
+approximately equal to (the integer) i. This shows that we can get very close
+to being in trouble, but very rarely. For example, 76573 is a denominator in
+one of the continued-fraction approximations to log(10)/log(2**15), and
+indeed:
+
+ >>> log(10)/log(2**15)*76573
+ 16958.000000654003
+
+is very close to an integer. If we were working with IEEE single-precision,
+rounding errors could kill us. Finding worst cases in IEEE double-precision
+requires better-than-double-precision log() functions, and Tim didn't bother.
+Instead the code checks to see whether the allocated space is enough as each
+new Python digit is added, and copies the whole thing to a larger long if not.
+This should happen extremely rarely, and in fact I don't have a test case
+that triggers it(!). Instead the code was tested by artificially allocating
+just 1 digit at the start, so that the copying code was exercised for every
+digit beyond the first.
+***/
+ register twodigits c; /* current input character */
+ Py_ssize_t size_z;
+ int i;
+ int convwidth;
+ twodigits convmultmax, convmult;
+ digit *pz, *pzstop;
+ char* scan;
+
+ static double log_base_PyLong_BASE[37] = {0.0e0,};
+ static int convwidth_base[37] = {0,};
+ static twodigits convmultmax_base[37] = {0,};
+
+ if (log_base_PyLong_BASE[base] == 0.0) {
+ twodigits convmax = base;
+ int i = 1;
+
+ log_base_PyLong_BASE[base] = (log((double)base) /
+ log((double)PyLong_BASE));
+ for (;;) {
+ twodigits next = convmax * base;
+ if (next > PyLong_BASE)
+ break;
+ convmax = next;
+ ++i;
+ }
+ convmultmax_base[base] = convmax;
+ assert(i > 0);
+ convwidth_base[base] = i;
+ }
+
+ /* Find length of the string of numeric characters. */
+ scan = str;
+ while (_PyLong_DigitValue[Py_CHARMASK(*scan)] < base)
+ ++scan;
+
+ /* Create a long object that can contain the largest possible
+ * integer with this base and length. Note that there's no
+ * need to initialize z->ob_digit -- no slot is read up before
+ * being stored into.
+ */
+ size_z = (Py_ssize_t)((scan - str) * log_base_PyLong_BASE[base]) + 1;
+ /* Uncomment next line to test exceedingly rare copy code */
+ /* size_z = 1; */
+ assert(size_z > 0);
+ z = _PyLong_New(size_z);
+ if (z == NULL)
+ return NULL;
+ Py_SIZE(z) = 0;
+
+ /* `convwidth` consecutive input digits are treated as a single
+ * digit in base `convmultmax`.
+ */
+ convwidth = convwidth_base[base];
+ convmultmax = convmultmax_base[base];
+
+ /* Work ;-) */
+ while (str < scan) {
+ /* grab up to convwidth digits from the input string */
+ c = (digit)_PyLong_DigitValue[Py_CHARMASK(*str++)];
+ for (i = 1; i < convwidth && str != scan; ++i, ++str) {
+ c = (twodigits)(c * base +
+ _PyLong_DigitValue[Py_CHARMASK(*str)]);
+ assert(c < PyLong_BASE);
+ }
+
+ convmult = convmultmax;
+ /* Calculate the shift only if we couldn't get
+ * convwidth digits.
+ */
+ if (i != convwidth) {
+ convmult = base;
+ for ( ; i > 1; --i)
+ convmult *= base;
+ }
+
+ /* Multiply z by convmult, and add c. */
+ pz = z->ob_digit;
+ pzstop = pz + Py_SIZE(z);
+ for (; pz < pzstop; ++pz) {
+ c += (twodigits)*pz * convmult;
+ *pz = (digit)(c & PyLong_MASK);
+ c >>= PyLong_SHIFT;
+ }
+ /* carry off the current end? */
+ if (c) {
+ assert(c < PyLong_BASE);
+ if (Py_SIZE(z) < size_z) {
+ *pz = (digit)c;
+ ++Py_SIZE(z);
+ }
+ else {
+ PyLongObject *tmp;
+ /* Extremely rare. Get more space. */
+ assert(Py_SIZE(z) == size_z);
+ tmp = _PyLong_New(size_z + 1);
+ if (tmp == NULL) {
+ Py_DECREF(z);
+ return NULL;
+ }
+ memcpy(tmp->ob_digit,
+ z->ob_digit,
+ sizeof(digit) * size_z);
+ Py_DECREF(z);
+ z = tmp;
+ z->ob_digit[size_z] = (digit)c;
+ ++size_z;
+ }
+ }
+ }
+ }
+ if (z == NULL)
+ return NULL;
+ if (str == start)
+ goto onError;
+ if (sign < 0)
+ Py_SIZE(z) = -(Py_SIZE(z));
+ if (*str == 'L' || *str == 'l')
+ str++;
+ while (*str && isspace(Py_CHARMASK(*str)))
+ str++;
+ if (*str != '\0')
+ goto onError;
+ if (pend)
+ *pend = str;
+ return (PyObject *) z;
+
+ onError:
+ Py_XDECREF(z);
+ slen = strlen(orig_str) < 200 ? strlen(orig_str) : 200;
+ strobj = PyString_FromStringAndSize(orig_str, slen);
+ if (strobj == NULL)
+ return NULL;
+ strrepr = PyObject_Repr(strobj);
+ Py_DECREF(strobj);
+ if (strrepr == NULL)
+ return NULL;
+ PyErr_Format(PyExc_ValueError,
+ "invalid literal for long() with base %d: %s",
+ base, PyString_AS_STRING(strrepr));
+ Py_DECREF(strrepr);
+ return NULL;
+}
+
+#ifdef Py_USING_UNICODE
+PyObject *
+PyLong_FromUnicode(Py_UNICODE *u, Py_ssize_t length, int base)
+{
+ PyObject *result;
+ char *buffer = (char *)PyMem_MALLOC(length+1);
+
+ if (buffer == NULL)
+ return NULL;
+
+ if (PyUnicode_EncodeDecimal(u, length, buffer, NULL)) {
+ PyMem_FREE(buffer);
+ return NULL;
+ }
+ result = PyLong_FromString(buffer, NULL, base);
+ PyMem_FREE(buffer);
+ return result;
+}
+#endif
+
+/* forward */
+static PyLongObject *x_divrem
+ (PyLongObject *, PyLongObject *, PyLongObject **);
+static PyObject *long_long(PyObject *v);
+
+/* Long division with remainder, top-level routine */
+
+static int
+long_divrem(PyLongObject *a, PyLongObject *b,
+ PyLongObject **pdiv, PyLongObject **prem)
+{
+ Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b));
+ PyLongObject *z;
+
+ if (size_b == 0) {
+ PyErr_SetString(PyExc_ZeroDivisionError,
+ "long division or modulo by zero");
+ return -1;
+ }
+ if (size_a < size_b ||
+ (size_a == size_b &&
+ a->ob_digit[size_a-1] < b->ob_digit[size_b-1])) {
+ /* |a| < |b|. */
+ *pdiv = _PyLong_New(0);
+ if (*pdiv == NULL)
+ return -1;
+ Py_INCREF(a);
+ *prem = (PyLongObject *) a;
+ return 0;
+ }
+ if (size_b == 1) {
+ digit rem = 0;
+ z = divrem1(a, b->ob_digit[0], &rem);
+ if (z == NULL)
+ return -1;
+ *prem = (PyLongObject *) PyLong_FromLong((long)rem);
+ if (*prem == NULL) {
+ Py_DECREF(z);
+ return -1;
+ }
+ }
+ else {
+ z = x_divrem(a, b, prem);
+ if (z == NULL)
+ return -1;
+ }
+ /* Set the signs.
+ The quotient z has the sign of a*b;
+ the remainder r has the sign of a,
+ so a = b*z + r. */
+ if ((a->ob_size < 0) != (b->ob_size < 0))
+ z->ob_size = -(z->ob_size);
+ if (a->ob_size < 0 && (*prem)->ob_size != 0)
+ (*prem)->ob_size = -((*prem)->ob_size);
+ *pdiv = z;
+ return 0;
+}
+
+/* Unsigned long division with remainder -- the algorithm. The arguments v1
+ and w1 should satisfy 2 <= ABS(Py_SIZE(w1)) <= ABS(Py_SIZE(v1)). */
+
+static PyLongObject *
+x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem)
+{
+ PyLongObject *v, *w, *a;
+ Py_ssize_t i, k, size_v, size_w;
+ int d;
+ digit wm1, wm2, carry, q, r, vtop, *v0, *vk, *w0, *ak;
+ twodigits vv;
+ sdigit zhi;
+ stwodigits z;
+
+ /* We follow Knuth [The Art of Computer Programming, Vol. 2 (3rd
+ edn.), section 4.3.1, Algorithm D], except that we don't explicitly
+ handle the special case when the initial estimate q for a quotient
+ digit is >= PyLong_BASE: the max value for q is PyLong_BASE+1, and
+ that won't overflow a digit. */
+
+ /* allocate space; w will also be used to hold the final remainder */
+ size_v = ABS(Py_SIZE(v1));
+ size_w = ABS(Py_SIZE(w1));
+ assert(size_v >= size_w && size_w >= 2); /* Assert checks by div() */
+ v = _PyLong_New(size_v+1);
+ if (v == NULL) {
+ *prem = NULL;
+ return NULL;
+ }
+ w = _PyLong_New(size_w);
+ if (w == NULL) {
+ Py_DECREF(v);
+ *prem = NULL;
+ return NULL;
+ }
+
+ /* normalize: shift w1 left so that its top digit is >= PyLong_BASE/2.
+ shift v1 left by the same amount. Results go into w and v. */
+ d = PyLong_SHIFT - bits_in_digit(w1->ob_digit[size_w-1]);
+ carry = v_lshift(w->ob_digit, w1->ob_digit, size_w, d);
+ assert(carry == 0);
+ carry = v_lshift(v->ob_digit, v1->ob_digit, size_v, d);
+ if (carry != 0 || v->ob_digit[size_v-1] >= w->ob_digit[size_w-1]) {
+ v->ob_digit[size_v] = carry;
+ size_v++;
+ }
+
+ /* Now v->ob_digit[size_v-1] < w->ob_digit[size_w-1], so quotient has
+ at most (and usually exactly) k = size_v - size_w digits. */
+ k = size_v - size_w;
+ assert(k >= 0);
+ a = _PyLong_New(k);
+ if (a == NULL) {
+ Py_DECREF(w);
+ Py_DECREF(v);
+ *prem = NULL;
+ return NULL;
+ }
+ v0 = v->ob_digit;
+ w0 = w->ob_digit;
+ wm1 = w0[size_w-1];
+ wm2 = w0[size_w-2];
+ for (vk = v0+k, ak = a->ob_digit + k; vk-- > v0;) {
+ /* inner loop: divide vk[0:size_w+1] by w0[0:size_w], giving
+ single-digit quotient q, remainder in vk[0:size_w]. */
+
+ SIGCHECK({
+ Py_DECREF(a);
+ Py_DECREF(w);
+ Py_DECREF(v);
+ *prem = NULL;
+ return NULL;
+ });
+
+ /* estimate quotient digit q; may overestimate by 1 (rare) */
+ vtop = vk[size_w];
+ assert(vtop <= wm1);
+ vv = ((twodigits)vtop << PyLong_SHIFT) | vk[size_w-1];
+ q = (digit)(vv / wm1);
+ r = (digit)(vv - (twodigits)wm1 * q); /* r = vv % wm1 */
+ while ((twodigits)wm2 * q > (((twodigits)r << PyLong_SHIFT)
+ | vk[size_w-2])) {
+ --q;
+ r += wm1;
+ if (r >= PyLong_BASE)
+ break;
+ }
+ assert(q <= PyLong_BASE);
+
+ /* subtract q*w0[0:size_w] from vk[0:size_w+1] */
+ zhi = 0;
+ for (i = 0; i < size_w; ++i) {
+ /* invariants: -PyLong_BASE <= -q <= zhi <= 0;
+ -PyLong_BASE * q <= z < PyLong_BASE */
+ z = (sdigit)vk[i] + zhi -
+ (stwodigits)q * (stwodigits)w0[i];
+ vk[i] = (digit)z & PyLong_MASK;
+ zhi = (sdigit)Py_ARITHMETIC_RIGHT_SHIFT(stwodigits,
+ z, PyLong_SHIFT);
+ }
+
+ /* add w back if q was too large (this branch taken rarely) */
+ assert((sdigit)vtop + zhi == -1 || (sdigit)vtop + zhi == 0);
+ if ((sdigit)vtop + zhi < 0) {
+ carry = 0;
+ for (i = 0; i < size_w; ++i) {
+ carry += vk[i] + w0[i];
+ vk[i] = carry & PyLong_MASK;
+ carry >>= PyLong_SHIFT;
+ }
+ --q;
+ }
+
+ /* store quotient digit */
+ assert(q < PyLong_BASE);
+ *--ak = q;
+ }
+
+ /* unshift remainder; we reuse w to store the result */
+ carry = v_rshift(w0, v0, size_w, d);
+ assert(carry==0);
+ Py_DECREF(v);
+
+ *prem = long_normalize(w);
+ return long_normalize(a);
+}
+
+/* For a nonzero PyLong a, express a in the form x * 2**e, with 0.5 <=
+ abs(x) < 1.0 and e >= 0; return x and put e in *e. Here x is
+ rounded to DBL_MANT_DIG significant bits using round-half-to-even.
+ If a == 0, return 0.0 and set *e = 0. If the resulting exponent
+ e is larger than PY_SSIZE_T_MAX, raise OverflowError and return
+ -1.0. */
+
+/* attempt to define 2.0**DBL_MANT_DIG as a compile-time constant */
+#if DBL_MANT_DIG == 53
+#define EXP2_DBL_MANT_DIG 9007199254740992.0
+#else
+#define EXP2_DBL_MANT_DIG (ldexp(1.0, DBL_MANT_DIG))
+#endif
+
+double
+_PyLong_Frexp(PyLongObject *a, Py_ssize_t *e)
+{
+ Py_ssize_t a_size, a_bits, shift_digits, shift_bits, x_size;
+ /* See below for why x_digits is always large enough. */
+ digit rem, x_digits[2 + (DBL_MANT_DIG + 1) / PyLong_SHIFT];
+ double dx;
+ /* Correction term for round-half-to-even rounding. For a digit x,
+ "x + half_even_correction[x & 7]" gives x rounded to the nearest
+ multiple of 4, rounding ties to a multiple of 8. */
+ static const int half_even_correction[8] = {0, -1, -2, 1, 0, -1, 2, 1};
+
+ a_size = ABS(Py_SIZE(a));
+ if (a_size == 0) {
+ /* Special case for 0: significand 0.0, exponent 0. */
+ *e = 0;
+ return 0.0;
+ }
+ a_bits = bits_in_digit(a->ob_digit[a_size-1]);
+ /* The following is an overflow-free version of the check
+ "if ((a_size - 1) * PyLong_SHIFT + a_bits > PY_SSIZE_T_MAX) ..." */
+ if (a_size >= (PY_SSIZE_T_MAX - 1) / PyLong_SHIFT + 1 &&
+ (a_size > (PY_SSIZE_T_MAX - 1) / PyLong_SHIFT + 1 ||
+ a_bits > (PY_SSIZE_T_MAX - 1) % PyLong_SHIFT + 1))
+ goto overflow;
+ a_bits = (a_size - 1) * PyLong_SHIFT + a_bits;
+
+ /* Shift the first DBL_MANT_DIG + 2 bits of a into x_digits[0:x_size]
+ (shifting left if a_bits <= DBL_MANT_DIG + 2).
+
+ Number of digits needed for result: write // for floor division.
+ Then if shifting left, we end up using
+
+ 1 + a_size + (DBL_MANT_DIG + 2 - a_bits) // PyLong_SHIFT
+
+ digits. If shifting right, we use
+
+ a_size - (a_bits - DBL_MANT_DIG - 2) // PyLong_SHIFT
+
+ digits. Using a_size = 1 + (a_bits - 1) // PyLong_SHIFT along with
+ the inequalities
+
+ m // PyLong_SHIFT + n // PyLong_SHIFT <= (m + n) // PyLong_SHIFT
+ m // PyLong_SHIFT - n // PyLong_SHIFT <=
+ 1 + (m - n - 1) // PyLong_SHIFT,
+
+ valid for any integers m and n, we find that x_size satisfies
+
+ x_size <= 2 + (DBL_MANT_DIG + 1) // PyLong_SHIFT
+
+ in both cases.
+ */
+ if (a_bits <= DBL_MANT_DIG + 2) {
+ shift_digits = (DBL_MANT_DIG + 2 - a_bits) / PyLong_SHIFT;
+ shift_bits = (DBL_MANT_DIG + 2 - a_bits) % PyLong_SHIFT;
+ x_size = 0;
+ while (x_size < shift_digits)
+ x_digits[x_size++] = 0;
+ rem = v_lshift(x_digits + x_size, a->ob_digit, a_size,
+ (int)shift_bits);
+ x_size += a_size;
+ x_digits[x_size++] = rem;
+ }
+ else {
+ shift_digits = (a_bits - DBL_MANT_DIG - 2) / PyLong_SHIFT;
+ shift_bits = (a_bits - DBL_MANT_DIG - 2) % PyLong_SHIFT;
+ rem = v_rshift(x_digits, a->ob_digit + shift_digits,
+ a_size - shift_digits, (int)shift_bits);
+ x_size = a_size - shift_digits;
+ /* For correct rounding below, we need the least significant
+ bit of x to be 'sticky' for this shift: if any of the bits
+ shifted out was nonzero, we set the least significant bit
+ of x. */
+ if (rem)
+ x_digits[0] |= 1;
+ else
+ while (shift_digits > 0)
+ if (a->ob_digit[--shift_digits]) {
+ x_digits[0] |= 1;
+ break;
+ }
+ }
+ assert(1 <= x_size &&
+ x_size <= (Py_ssize_t)(sizeof(x_digits)/sizeof(digit)));
+
+ /* Round, and convert to double. */
+ x_digits[0] += half_even_correction[x_digits[0] & 7];
+ dx = x_digits[--x_size];
+ while (x_size > 0)
+ dx = dx * PyLong_BASE + x_digits[--x_size];
+
+ /* Rescale; make correction if result is 1.0. */
+ dx /= 4.0 * EXP2_DBL_MANT_DIG;
+ if (dx == 1.0) {
+ if (a_bits == PY_SSIZE_T_MAX)
+ goto overflow;
+ dx = 0.5;
+ a_bits += 1;
+ }
+
+ *e = a_bits;
+ return Py_SIZE(a) < 0 ? -dx : dx;
+
+ overflow:
+ /* exponent > PY_SSIZE_T_MAX */
+ PyErr_SetString(PyExc_OverflowError,
+ "huge integer: number of bits overflows a Py_ssize_t");
+ *e = 0;
+ return -1.0;
+}
+
+/* Get a C double from a long int object. Rounds to the nearest double,
+ using the round-half-to-even rule in the case of a tie. */
+
+double
+PyLong_AsDouble(PyObject *v)
+{
+ Py_ssize_t exponent;
+ double x;
+
+ if (v == NULL || !PyLong_Check(v)) {
+ PyErr_BadInternalCall();
+ return -1.0;
+ }
+ x = _PyLong_Frexp((PyLongObject *)v, &exponent);
+ if ((x == -1.0 && PyErr_Occurred()) || exponent > DBL_MAX_EXP) {
+ PyErr_SetString(PyExc_OverflowError,
+ "long int too large to convert to float");
+ return -1.0;
+ }
+ return ldexp(x, (int)exponent);
+}
+
+/* Methods */
+
+static void
+long_dealloc(PyObject *v)
+{
+ Py_TYPE(v)->tp_free(v);
+}
+
+static PyObject *
+long_repr(PyObject *v)
+{
+ return _PyLong_Format(v, 10, 1, 0);
+}
+
+static PyObject *
+long_str(PyObject *v)
+{
+ return _PyLong_Format(v, 10, 0, 0);
+}
+
+static int
+long_compare(PyLongObject *a, PyLongObject *b)
+{
+ Py_ssize_t sign;
+
+ if (Py_SIZE(a) != Py_SIZE(b)) {
+ sign = Py_SIZE(a) - Py_SIZE(b);
+ }
+ else {
+ Py_ssize_t i = ABS(Py_SIZE(a));
+ while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
+ ;
+ if (i < 0)
+ sign = 0;
+ else {
+ sign = (sdigit)a->ob_digit[i] - (sdigit)b->ob_digit[i];
+ if (Py_SIZE(a) < 0)
+ sign = -sign;
+ }
+ }
+ return sign < 0 ? -1 : sign > 0 ? 1 : 0;
+}
+
+static long
+long_hash(PyLongObject *v)
+{
+ unsigned long x;
+ Py_ssize_t i;
+ int sign;
+
+ /* This is designed so that Python ints and longs with the
+ same value hash to the same value, otherwise comparisons
+ of mapping keys will turn out weird */
+ i = v->ob_size;
+ sign = 1;
+ x = 0;
+ if (i < 0) {
+ sign = -1;
+ i = -(i);
+ }
+ /* The following loop produces a C unsigned long x such that x is
+ congruent to the absolute value of v modulo ULONG_MAX. The
+ resulting x is nonzero if and only if v is. */
+ while (--i >= 0) {
+ /* Force a native long #-bits (32 or 64) circular shift */
+ x = (x >> (8*SIZEOF_LONG-PyLong_SHIFT)) | (x << PyLong_SHIFT);
+ x += v->ob_digit[i];
+ /* If the addition above overflowed we compensate by
+ incrementing. This preserves the value modulo
+ ULONG_MAX. */
+ if (x < v->ob_digit[i])
+ x++;
+ }
+ x = x * sign;
+ if (x == (unsigned long)-1)
+ x = (unsigned long)-2;
+ return (long)x;
+}
+
+
+/* Add the absolute values of two long integers. */
+
+static PyLongObject *
+x_add(PyLongObject *a, PyLongObject *b)
+{
+ Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b));
+ PyLongObject *z;
+ Py_ssize_t i;
+ digit carry = 0;
+
+ /* Ensure a is the larger of the two: */
+ if (size_a < size_b) {
+ { PyLongObject *temp = a; a = b; b = temp; }
+ { Py_ssize_t size_temp = size_a;
+ size_a = size_b;
+ size_b = size_temp; }
+ }
+ z = _PyLong_New(size_a+1);
+ if (z == NULL)
+ return NULL;
+ for (i = 0; i < size_b; ++i) {
+ carry += a->ob_digit[i] + b->ob_digit[i];
+ z->ob_digit[i] = carry & PyLong_MASK;
+ carry >>= PyLong_SHIFT;
+ }
+ for (; i < size_a; ++i) {
+ carry += a->ob_digit[i];
+ z->ob_digit[i] = carry & PyLong_MASK;
+ carry >>= PyLong_SHIFT;
+ }
+ z->ob_digit[i] = carry;
+ return long_normalize(z);
+}
+
+/* Subtract the absolute values of two integers. */
+
+static PyLongObject *
+x_sub(PyLongObject *a, PyLongObject *b)
+{
+ Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b));
+ PyLongObject *z;
+ Py_ssize_t i;
+ int sign = 1;
+ digit borrow = 0;
+
+ /* Ensure a is the larger of the two: */
+ if (size_a < size_b) {
+ sign = -1;
+ { PyLongObject *temp = a; a = b; b = temp; }
+ { Py_ssize_t size_temp = size_a;
+ size_a = size_b;
+ size_b = size_temp; }
+ }
+ else if (size_a == size_b) {
+ /* Find highest digit where a and b differ: */
+ i = size_a;
+ while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
+ ;
+ if (i < 0)
+ return _PyLong_New(0);
+ if (a->ob_digit[i] < b->ob_digit[i]) {
+ sign = -1;
+ { PyLongObject *temp = a; a = b; b = temp; }
+ }
+ size_a = size_b = i+1;
+ }
+ z = _PyLong_New(size_a);
+ if (z == NULL)
+ return NULL;
+ for (i = 0; i < size_b; ++i) {
+ /* The following assumes unsigned arithmetic
+ works module 2**N for some N>PyLong_SHIFT. */
+ borrow = a->ob_digit[i] - b->ob_digit[i] - borrow;
+ z->ob_digit[i] = borrow & PyLong_MASK;
+ borrow >>= PyLong_SHIFT;
+ borrow &= 1; /* Keep only one sign bit */
+ }
+ for (; i < size_a; ++i) {
+ borrow = a->ob_digit[i] - borrow;
+ z->ob_digit[i] = borrow & PyLong_MASK;
+ borrow >>= PyLong_SHIFT;
+ borrow &= 1; /* Keep only one sign bit */
+ }
+ assert(borrow == 0);
+ if (sign < 0)
+ z->ob_size = -(z->ob_size);
+ return long_normalize(z);
+}
+
+static PyObject *
+long_add(PyLongObject *v, PyLongObject *w)
+{
+ PyLongObject *a, *b, *z;
+
+ CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);
+
+ if (a->ob_size < 0) {
+ if (b->ob_size < 0) {
+ z = x_add(a, b);
+ if (z != NULL && z->ob_size != 0)
+ z->ob_size = -(z->ob_size);
+ }
+ else
+ z = x_sub(b, a);
+ }
+ else {
+ if (b->ob_size < 0)
+ z = x_sub(a, b);
+ else
+ z = x_add(a, b);
+ }
+ Py_DECREF(a);
+ Py_DECREF(b);
+ return (PyObject *)z;
+}
+
+static PyObject *
+long_sub(PyLongObject *v, PyLongObject *w)
+{
+ PyLongObject *a, *b, *z;
+
+ CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);
+
+ if (a->ob_size < 0) {
+ if (b->ob_size < 0)
+ z = x_sub(a, b);
+ else
+ z = x_add(a, b);
+ if (z != NULL && z->ob_size != 0)
+ z->ob_size = -(z->ob_size);
+ }
+ else {
+ if (b->ob_size < 0)
+ z = x_add(a, b);
+ else
+ z = x_sub(a, b);
+ }
+ Py_DECREF(a);
+ Py_DECREF(b);
+ return (PyObject *)z;
+}
+
+/* Grade school multiplication, ignoring the signs.
+ * Returns the absolute value of the product, or NULL if error.
+ */
+static PyLongObject *
+x_mul(PyLongObject *a, PyLongObject *b)
+{
+ PyLongObject *z;
+ Py_ssize_t size_a = ABS(Py_SIZE(a));
+ Py_ssize_t size_b = ABS(Py_SIZE(b));
+ Py_ssize_t i;
+
+ z = _PyLong_New(size_a + size_b);
+ if (z == NULL)
+ return NULL;
+
+ memset(z->ob_digit, 0, Py_SIZE(z) * sizeof(digit));
+ if (a == b) {
+ /* Efficient squaring per HAC, Algorithm 14.16:
+ * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
+ * Gives slightly less than a 2x speedup when a == b,
+ * via exploiting that each entry in the multiplication
+ * pyramid appears twice (except for the size_a squares).
+ */
+ for (i = 0; i < size_a; ++i) {
+ twodigits carry;
+ twodigits f = a->ob_digit[i];
+ digit *pz = z->ob_digit + (i << 1);
+ digit *pa = a->ob_digit + i + 1;
+ digit *paend = a->ob_digit + size_a;
+
+ SIGCHECK({
+ Py_DECREF(z);
+ return NULL;
+ });
+
+ carry = *pz + f * f;
+ *pz++ = (digit)(carry & PyLong_MASK);
+ carry >>= PyLong_SHIFT;
+ assert(carry <= PyLong_MASK);
+
+ /* Now f is added in twice in each column of the
+ * pyramid it appears. Same as adding f<<1 once.
+ */
+ f <<= 1;
+ while (pa < paend) {
+ carry += *pz + *pa++ * f;
+ *pz++ = (digit)(carry & PyLong_MASK);
+ carry >>= PyLong_SHIFT;
+ assert(carry <= (PyLong_MASK << 1));
+ }
+ if (carry) {
+ carry += *pz;
+ *pz++ = (digit)(carry & PyLong_MASK);
+ carry >>= PyLong_SHIFT;
+ }
+ if (carry)
+ *pz += (digit)(carry & PyLong_MASK);
+ assert((carry >> PyLong_SHIFT) == 0);
+ }
+ }
+ else { /* a is not the same as b -- gradeschool long mult */
+ for (i = 0; i < size_a; ++i) {
+ twodigits carry = 0;
+ twodigits f = a->ob_digit[i];
+ digit *pz = z->ob_digit + i;
+ digit *pb = b->ob_digit;
+ digit *pbend = b->ob_digit + size_b;
+
+ SIGCHECK({
+ Py_DECREF(z);
+ return NULL;
+ });
+
+ while (pb < pbend) {
+ carry += *pz + *pb++ * f;
+ *pz++ = (digit)(carry & PyLong_MASK);
+ carry >>= PyLong_SHIFT;
+ assert(carry <= PyLong_MASK);
+ }
+ if (carry)
+ *pz += (digit)(carry & PyLong_MASK);
+ assert((carry >> PyLong_SHIFT) == 0);
+ }
+ }
+ return long_normalize(z);
+}
+
+/* A helper for Karatsuba multiplication (k_mul).
+ Takes a long "n" and an integer "size" representing the place to
+ split, and sets low and high such that abs(n) == (high << size) + low,
+ viewing the shift as being by digits. The sign bit is ignored, and
+ the return values are >= 0.
+ Returns 0 on success, -1 on failure.
+*/
+static int
+kmul_split(PyLongObject *n,
+ Py_ssize_t size,
+ PyLongObject **high,
+ PyLongObject **low)
+{
+ PyLongObject *hi, *lo;
+ Py_ssize_t size_lo, size_hi;
+ const Py_ssize_t size_n = ABS(Py_SIZE(n));
+
+ size_lo = MIN(size_n, size);
+ size_hi = size_n - size_lo;
+
+ if ((hi = _PyLong_New(size_hi)) == NULL)
+ return -1;
+ if ((lo = _PyLong_New(size_lo)) == NULL) {
+ Py_DECREF(hi);
+ return -1;
+ }
+
+ memcpy(lo->ob_digit, n->ob_digit, size_lo * sizeof(digit));
+ memcpy(hi->ob_digit, n->ob_digit + size_lo, size_hi * sizeof(digit));
+
+ *high = long_normalize(hi);
+ *low = long_normalize(lo);
+ return 0;
+}
+
+static PyLongObject *k_lopsided_mul(PyLongObject *a, PyLongObject *b);
+
+/* Karatsuba multiplication. Ignores the input signs, and returns the
+ * absolute value of the product (or NULL if error).
+ * See Knuth Vol. 2 Chapter 4.3.3 (Pp. 294-295).
+ */
+static PyLongObject *
+k_mul(PyLongObject *a, PyLongObject *b)
+{
+ Py_ssize_t asize = ABS(Py_SIZE(a));
+ Py_ssize_t bsize = ABS(Py_SIZE(b));
+ PyLongObject *ah = NULL;
+ PyLongObject *al = NULL;
+ PyLongObject *bh = NULL;
+ PyLongObject *bl = NULL;
+ PyLongObject *ret = NULL;
+ PyLongObject *t1, *t2, *t3;
+ Py_ssize_t shift; /* the number of digits we split off */
+ Py_ssize_t i;
+
+ /* (ah*X+al)(bh*X+bl) = ah*bh*X*X + (ah*bl + al*bh)*X + al*bl
+ * Let k = (ah+al)*(bh+bl) = ah*bl + al*bh + ah*bh + al*bl
+ * Then the original product is
+ * ah*bh*X*X + (k - ah*bh - al*bl)*X + al*bl
+ * By picking X to be a power of 2, "*X" is just shifting, and it's
+ * been reduced to 3 multiplies on numbers half the size.
+ */
+
+ /* We want to split based on the larger number; fiddle so that b
+ * is largest.
+ */
+ if (asize > bsize) {
+ t1 = a;
+ a = b;
+ b = t1;
+
+ i = asize;
+ asize = bsize;
+ bsize = i;
+ }
+
+ /* Use gradeschool math when either number is too small. */
+ i = a == b ? KARATSUBA_SQUARE_CUTOFF : KARATSUBA_CUTOFF;
+ if (asize <= i) {
+ if (asize == 0)
+ return _PyLong_New(0);
+ else
+ return x_mul(a, b);
+ }
+
+ /* If a is small compared to b, splitting on b gives a degenerate
+ * case with ah==0, and Karatsuba may be (even much) less efficient
+ * than "grade school" then. However, we can still win, by viewing
+ * b as a string of "big digits", each of width a->ob_size. That
+ * leads to a sequence of balanced calls to k_mul.
+ */
+ if (2 * asize <= bsize)
+ return k_lopsided_mul(a, b);
+
+ /* Split a & b into hi & lo pieces. */
+ shift = bsize >> 1;
+ if (kmul_split(a, shift, &ah, &al) < 0) goto fail;
+ assert(Py_SIZE(ah) > 0); /* the split isn't degenerate */
+
+ if (a == b) {
+ bh = ah;
+ bl = al;
+ Py_INCREF(bh);
+ Py_INCREF(bl);
+ }
+ else if (kmul_split(b, shift, &bh, &bl) < 0) goto fail;
+
+ /* The plan:
+ * 1. Allocate result space (asize + bsize digits: that's always
+ * enough).
+ * 2. Compute ah*bh, and copy into result at 2*shift.
+ * 3. Compute al*bl, and copy into result at 0. Note that this
+ * can't overlap with #2.
+ * 4. Subtract al*bl from the result, starting at shift. This may
+ * underflow (borrow out of the high digit), but we don't care:
+ * we're effectively doing unsigned arithmetic mod
+ * PyLong_BASE**(sizea + sizeb), and so long as the *final* result fits,
+ * borrows and carries out of the high digit can be ignored.
+ * 5. Subtract ah*bh from the result, starting at shift.
+ * 6. Compute (ah+al)*(bh+bl), and add it into the result starting
+ * at shift.
+ */
+
+ /* 1. Allocate result space. */
+ ret = _PyLong_New(asize + bsize);
+ if (ret == NULL) goto fail;
+#ifdef Py_DEBUG
+ /* Fill with trash, to catch reference to uninitialized digits. */
+ memset(ret->ob_digit, 0xDF, Py_SIZE(ret) * sizeof(digit));
+#endif
+
+ /* 2. t1 <- ah*bh, and copy into high digits of result. */
+ if ((t1 = k_mul(ah, bh)) == NULL) goto fail;
+ assert(Py_SIZE(t1) >= 0);
+ assert(2*shift + Py_SIZE(t1) <= Py_SIZE(ret));
+ memcpy(ret->ob_digit + 2*shift, t1->ob_digit,
+ Py_SIZE(t1) * sizeof(digit));
+
+ /* Zero-out the digits higher than the ah*bh copy. */
+ i = Py_SIZE(ret) - 2*shift - Py_SIZE(t1);
+ if (i)
+ memset(ret->ob_digit + 2*shift + Py_SIZE(t1), 0,
+ i * sizeof(digit));
+
+ /* 3. t2 <- al*bl, and copy into the low digits. */
+ if ((t2 = k_mul(al, bl)) == NULL) {
+ Py_DECREF(t1);
+ goto fail;
+ }
+ assert(Py_SIZE(t2) >= 0);
+ assert(Py_SIZE(t2) <= 2*shift); /* no overlap with high digits */
+ memcpy(ret->ob_digit, t2->ob_digit, Py_SIZE(t2) * sizeof(digit));
+
+ /* Zero out remaining digits. */
+ i = 2*shift - Py_SIZE(t2); /* number of uninitialized digits */
+ if (i)
+ memset(ret->ob_digit + Py_SIZE(t2), 0, i * sizeof(digit));
+
+ /* 4 & 5. Subtract ah*bh (t1) and al*bl (t2). We do al*bl first
+ * because it's fresher in cache.
+ */
+ i = Py_SIZE(ret) - shift; /* # digits after shift */
+ (void)v_isub(ret->ob_digit + shift, i, t2->ob_digit, Py_SIZE(t2));
+ Py_DECREF(t2);
+
+ (void)v_isub(ret->ob_digit + shift, i, t1->ob_digit, Py_SIZE(t1));
+ Py_DECREF(t1);
+
+ /* 6. t3 <- (ah+al)(bh+bl), and add into result. */
+ if ((t1 = x_add(ah, al)) == NULL) goto fail;
+ Py_DECREF(ah);
+ Py_DECREF(al);
+ ah = al = NULL;
+
+ if (a == b) {
+ t2 = t1;
+ Py_INCREF(t2);
+ }
+ else if ((t2 = x_add(bh, bl)) == NULL) {
+ Py_DECREF(t1);
+ goto fail;
+ }
+ Py_DECREF(bh);
+ Py_DECREF(bl);
+ bh = bl = NULL;
+
+ t3 = k_mul(t1, t2);
+ Py_DECREF(t1);
+ Py_DECREF(t2);
+ if (t3 == NULL) goto fail;
+ assert(Py_SIZE(t3) >= 0);
+
+ /* Add t3. It's not obvious why we can't run out of room here.
+ * See the (*) comment after this function.
+ */
+ (void)v_iadd(ret->ob_digit + shift, i, t3->ob_digit, Py_SIZE(t3));
+ Py_DECREF(t3);
+
+ return long_normalize(ret);
+
+ fail:
+ Py_XDECREF(ret);
+ Py_XDECREF(ah);
+ Py_XDECREF(al);
+ Py_XDECREF(bh);
+ Py_XDECREF(bl);
+ return NULL;
+}
+
+/* (*) Why adding t3 can't "run out of room" above.
+
+Let f(x) mean the floor of x and c(x) mean the ceiling of x. Some facts
+to start with:
+
+1. For any integer i, i = c(i/2) + f(i/2). In particular,
+ bsize = c(bsize/2) + f(bsize/2).
+2. shift = f(bsize/2)
+3. asize <= bsize
+4. Since we call k_lopsided_mul if asize*2 <= bsize, asize*2 > bsize in this
+ routine, so asize > bsize/2 >= f(bsize/2) in this routine.
+
+We allocated asize + bsize result digits, and add t3 into them at an offset
+of shift. This leaves asize+bsize-shift allocated digit positions for t3
+to fit into, = (by #1 and #2) asize + f(bsize/2) + c(bsize/2) - f(bsize/2) =
+asize + c(bsize/2) available digit positions.
+
+bh has c(bsize/2) digits, and bl at most f(size/2) digits. So bh+hl has
+at most c(bsize/2) digits + 1 bit.
+
+If asize == bsize, ah has c(bsize/2) digits, else ah has at most f(bsize/2)
+digits, and al has at most f(bsize/2) digits in any case. So ah+al has at
+most (asize == bsize ? c(bsize/2) : f(bsize/2)) digits + 1 bit.
+
+The product (ah+al)*(bh+bl) therefore has at most
+
+ c(bsize/2) + (asize == bsize ? c(bsize/2) : f(bsize/2)) digits + 2 bits
+
+and we have asize + c(bsize/2) available digit positions. We need to show
+this is always enough. An instance of c(bsize/2) cancels out in both, so
+the question reduces to whether asize digits is enough to hold
+(asize == bsize ? c(bsize/2) : f(bsize/2)) digits + 2 bits. If asize < bsize,
+then we're asking whether asize digits >= f(bsize/2) digits + 2 bits. By #4,
+asize is at least f(bsize/2)+1 digits, so this in turn reduces to whether 1
+digit is enough to hold 2 bits. This is so since PyLong_SHIFT=15 >= 2. If
+asize == bsize, then we're asking whether bsize digits is enough to hold
+c(bsize/2) digits + 2 bits, or equivalently (by #1) whether f(bsize/2) digits
+is enough to hold 2 bits. This is so if bsize >= 2, which holds because
+bsize >= KARATSUBA_CUTOFF >= 2.
+
+Note that since there's always enough room for (ah+al)*(bh+bl), and that's
+clearly >= each of ah*bh and al*bl, there's always enough room to subtract
+ah*bh and al*bl too.
+*/
+
+/* b has at least twice the digits of a, and a is big enough that Karatsuba
+ * would pay off *if* the inputs had balanced sizes. View b as a sequence
+ * of slices, each with a->ob_size digits, and multiply the slices by a,
+ * one at a time. This gives k_mul balanced inputs to work with, and is
+ * also cache-friendly (we compute one double-width slice of the result
+ * at a time, then move on, never backtracking except for the helpful
+ * single-width slice overlap between successive partial sums).
+ */
+static PyLongObject *
+k_lopsided_mul(PyLongObject *a, PyLongObject *b)
+{
+ const Py_ssize_t asize = ABS(Py_SIZE(a));
+ Py_ssize_t bsize = ABS(Py_SIZE(b));
+ Py_ssize_t nbdone; /* # of b digits already multiplied */
+ PyLongObject *ret;
+ PyLongObject *bslice = NULL;
+
+ assert(asize > KARATSUBA_CUTOFF);
+ assert(2 * asize <= bsize);
+
+ /* Allocate result space, and zero it out. */
+ ret = _PyLong_New(asize + bsize);
+ if (ret == NULL)
+ return NULL;
+ memset(ret->ob_digit, 0, Py_SIZE(ret) * sizeof(digit));
+
+ /* Successive slices of b are copied into bslice. */
+ bslice = _PyLong_New(asize);
+ if (bslice == NULL)
+ goto fail;
+
+ nbdone = 0;
+ while (bsize > 0) {
+ PyLongObject *product;
+ const Py_ssize_t nbtouse = MIN(bsize, asize);
+
+ /* Multiply the next slice of b by a. */
+ memcpy(bslice->ob_digit, b->ob_digit + nbdone,
+ nbtouse * sizeof(digit));
+ Py_SIZE(bslice) = nbtouse;
+ product = k_mul(a, bslice);
+ if (product == NULL)
+ goto fail;
+
+ /* Add into result. */
+ (void)v_iadd(ret->ob_digit + nbdone, Py_SIZE(ret) - nbdone,
+ product->ob_digit, Py_SIZE(product));
+ Py_DECREF(product);
+
+ bsize -= nbtouse;
+ nbdone += nbtouse;
+ }
+
+ Py_DECREF(bslice);
+ return long_normalize(ret);
+
+ fail:
+ Py_DECREF(ret);
+ Py_XDECREF(bslice);
+ return NULL;
+}
+
+static PyObject *
+long_mul(PyLongObject *v, PyLongObject *w)
+{
+ PyLongObject *a, *b, *z;
+
+ if (!convert_binop((PyObject *)v, (PyObject *)w, &a, &b)) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+
+ z = k_mul(a, b);
+ /* Negate if exactly one of the inputs is negative. */
+ if (((a->ob_size ^ b->ob_size) < 0) && z)
+ z->ob_size = -(z->ob_size);
+ Py_DECREF(a);
+ Py_DECREF(b);
+ return (PyObject *)z;
+}
+
+/* The / and % operators are now defined in terms of divmod().
+ The expression a mod b has the value a - b*floor(a/b).
+ The long_divrem function gives the remainder after division of
+ |a| by |b|, with the sign of a. This is also expressed
+ as a - b*trunc(a/b), if trunc truncates towards zero.
+ Some examples:
+ a b a rem b a mod b
+ 13 10 3 3
+ -13 10 -3 7
+ 13 -10 3 -7
+ -13 -10 -3 -3
+ So, to get from rem to mod, we have to add b if a and b
+ have different signs. We then subtract one from the 'div'
+ part of the outcome to keep the invariant intact. */
+
+/* Compute
+ * *pdiv, *pmod = divmod(v, w)
+ * NULL can be passed for pdiv or pmod, in which case that part of
+ * the result is simply thrown away. The caller owns a reference to
+ * each of these it requests (does not pass NULL for).
+ */
+static int
+l_divmod(PyLongObject *v, PyLongObject *w,
+ PyLongObject **pdiv, PyLongObject **pmod)
+{
+ PyLongObject *div, *mod;
+
+ if (long_divrem(v, w, &div, &mod) < 0)
+ return -1;
+ if ((Py_SIZE(mod) < 0 && Py_SIZE(w) > 0) ||
+ (Py_SIZE(mod) > 0 && Py_SIZE(w) < 0)) {
+ PyLongObject *temp;
+ PyLongObject *one;
+ temp = (PyLongObject *) long_add(mod, w);
+ Py_DECREF(mod);
+ mod = temp;
+ if (mod == NULL) {
+ Py_DECREF(div);
+ return -1;
+ }
+ one = (PyLongObject *) PyLong_FromLong(1L);
+ if (one == NULL ||
+ (temp = (PyLongObject *) long_sub(div, one)) == NULL) {
+ Py_DECREF(mod);
+ Py_DECREF(div);
+ Py_XDECREF(one);
+ return -1;
+ }
+ Py_DECREF(one);
+ Py_DECREF(div);
+ div = temp;
+ }
+ if (pdiv != NULL)
+ *pdiv = div;
+ else
+ Py_DECREF(div);
+
+ if (pmod != NULL)
+ *pmod = mod;
+ else
+ Py_DECREF(mod);
+
+ return 0;
+}
+
+static PyObject *
+long_div(PyObject *v, PyObject *w)
+{
+ PyLongObject *a, *b, *div;
+
+ CONVERT_BINOP(v, w, &a, &b);
+ if (l_divmod(a, b, &div, NULL) < 0)
+ div = NULL;
+ Py_DECREF(a);
+ Py_DECREF(b);
+ return (PyObject *)div;
+}
+
+static PyObject *
+long_classic_div(PyObject *v, PyObject *w)
+{
+ PyLongObject *a, *b, *div;
+
+ CONVERT_BINOP(v, w, &a, &b);
+ if (Py_DivisionWarningFlag &&
+ PyErr_Warn(PyExc_DeprecationWarning, "classic long division") < 0)
+ div = NULL;
+ else if (l_divmod(a, b, &div, NULL) < 0)
+ div = NULL;
+ Py_DECREF(a);
+ Py_DECREF(b);
+ return (PyObject *)div;
+}
+
+/* PyLong/PyLong -> float, with correctly rounded result. */
+
+#define MANT_DIG_DIGITS (DBL_MANT_DIG / PyLong_SHIFT)
+#define MANT_DIG_BITS (DBL_MANT_DIG % PyLong_SHIFT)
+
+static PyObject *
+long_true_divide(PyObject *v, PyObject *w)
+{
+ PyLongObject *a, *b, *x;
+ Py_ssize_t a_size, b_size, shift, extra_bits, diff, x_size, x_bits;
+ digit mask, low;
+ int inexact, negate, a_is_small, b_is_small;
+ double dx, result;
+
+ CONVERT_BINOP(v, w, &a, &b);
+
+ /*
+ Method in a nutshell:
+
+ 0. reduce to case a, b > 0; filter out obvious underflow/overflow
+ 1. choose a suitable integer 'shift'
+ 2. use integer arithmetic to compute x = floor(2**-shift*a/b)
+ 3. adjust x for correct rounding
+ 4. convert x to a double dx with the same value
+ 5. return ldexp(dx, shift).
+
+ In more detail:
+
+ 0. For any a, a/0 raises ZeroDivisionError; for nonzero b, 0/b
+ returns either 0.0 or -0.0, depending on the sign of b. For a and
+ b both nonzero, ignore signs of a and b, and add the sign back in
+ at the end. Now write a_bits and b_bits for the bit lengths of a
+ and b respectively (that is, a_bits = 1 + floor(log_2(a)); likewise
+ for b). Then
+
+ 2**(a_bits - b_bits - 1) < a/b < 2**(a_bits - b_bits + 1).
+
+ So if a_bits - b_bits > DBL_MAX_EXP then a/b > 2**DBL_MAX_EXP and
+ so overflows. Similarly, if a_bits - b_bits < DBL_MIN_EXP -
+ DBL_MANT_DIG - 1 then a/b underflows to 0. With these cases out of
+ the way, we can assume that
+
+ DBL_MIN_EXP - DBL_MANT_DIG - 1 <= a_bits - b_bits <= DBL_MAX_EXP.
+
+ 1. The integer 'shift' is chosen so that x has the right number of
+ bits for a double, plus two or three extra bits that will be used
+ in the rounding decisions. Writing a_bits and b_bits for the
+ number of significant bits in a and b respectively, a
+ straightforward formula for shift is:
+
+ shift = a_bits - b_bits - DBL_MANT_DIG - 2
+
+ This is fine in the usual case, but if a/b is smaller than the
+ smallest normal float then it can lead to double rounding on an
+ IEEE 754 platform, giving incorrectly rounded results. So we
+ adjust the formula slightly. The actual formula used is:
+
+ shift = MAX(a_bits - b_bits, DBL_MIN_EXP) - DBL_MANT_DIG - 2
+
+ 2. The quantity x is computed by first shifting a (left -shift bits
+ if shift <= 0, right shift bits if shift > 0) and then dividing by
+ b. For both the shift and the division, we keep track of whether
+ the result is inexact, in a flag 'inexact'; this information is
+ needed at the rounding stage.
+
+ With the choice of shift above, together with our assumption that
+ a_bits - b_bits >= DBL_MIN_EXP - DBL_MANT_DIG - 1, it follows
+ that x >= 1.
+
+ 3. Now x * 2**shift <= a/b < (x+1) * 2**shift. We want to replace
+ this with an exactly representable float of the form
+
+ round(x/2**extra_bits) * 2**(extra_bits+shift).
+
+ For float representability, we need x/2**extra_bits <
+ 2**DBL_MANT_DIG and extra_bits + shift >= DBL_MIN_EXP -
+ DBL_MANT_DIG. This translates to the condition:
+
+ extra_bits >= MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG
+
+ To round, we just modify the bottom digit of x in-place; this can
+ end up giving a digit with value > PyLONG_MASK, but that's not a
+ problem since digits can hold values up to 2*PyLONG_MASK+1.
+
+ With the original choices for shift above, extra_bits will always
+ be 2 or 3. Then rounding under the round-half-to-even rule, we
+ round up iff the most significant of the extra bits is 1, and
+ either: (a) the computation of x in step 2 had an inexact result,
+ or (b) at least one other of the extra bits is 1, or (c) the least
+ significant bit of x (above those to be rounded) is 1.
+
+ 4. Conversion to a double is straightforward; all floating-point
+ operations involved in the conversion are exact, so there's no
+ danger of rounding errors.
+
+ 5. Use ldexp(x, shift) to compute x*2**shift, the final result.
+ The result will always be exactly representable as a double, except
+ in the case that it overflows. To avoid dependence on the exact
+ behaviour of ldexp on overflow, we check for overflow before
+ applying ldexp. The result of ldexp is adjusted for sign before
+ returning.
+ */
+
+ /* Reduce to case where a and b are both positive. */
+ a_size = ABS(Py_SIZE(a));
+ b_size = ABS(Py_SIZE(b));
+ negate = (Py_SIZE(a) < 0) ^ (Py_SIZE(b) < 0);
+ if (b_size == 0) {
+ PyErr_SetString(PyExc_ZeroDivisionError,
+ "division by zero");
+ goto error;
+ }
+ if (a_size == 0)
+ goto underflow_or_zero;
+
+ /* Fast path for a and b small (exactly representable in a double).
+ Relies on floating-point division being correctly rounded; results
+ may be subject to double rounding on x86 machines that operate with
+ the x87 FPU set to 64-bit precision. */
+ a_is_small = a_size <= MANT_DIG_DIGITS ||
+ (a_size == MANT_DIG_DIGITS+1 &&
+ a->ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0);
+ b_is_small = b_size <= MANT_DIG_DIGITS ||
+ (b_size == MANT_DIG_DIGITS+1 &&
+ b->ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0);
+ if (a_is_small && b_is_small) {
+ double da, db;
+ da = a->ob_digit[--a_size];
+ while (a_size > 0)
+ da = da * PyLong_BASE + a->ob_digit[--a_size];
+ db = b->ob_digit[--b_size];
+ while (b_size > 0)
+ db = db * PyLong_BASE + b->ob_digit[--b_size];
+ result = da / db;
+ goto success;
+ }
+
+ /* Catch obvious cases of underflow and overflow */
+ diff = a_size - b_size;
+ if (diff > PY_SSIZE_T_MAX/PyLong_SHIFT - 1)
+ /* Extreme overflow */
+ goto overflow;
+ else if (diff < 1 - PY_SSIZE_T_MAX/PyLong_SHIFT)
+ /* Extreme underflow */
+ goto underflow_or_zero;
+ /* Next line is now safe from overflowing a Py_ssize_t */
+ diff = diff * PyLong_SHIFT + bits_in_digit(a->ob_digit[a_size - 1]) -
+ bits_in_digit(b->ob_digit[b_size - 1]);
+ /* Now diff = a_bits - b_bits. */
+ if (diff > DBL_MAX_EXP)
+ goto overflow;
+ else if (diff < DBL_MIN_EXP - DBL_MANT_DIG - 1)
+ goto underflow_or_zero;
+
+ /* Choose value for shift; see comments for step 1 above. */
+ shift = MAX(diff, DBL_MIN_EXP) - DBL_MANT_DIG - 2;
+
+ inexact = 0;
+
+ /* x = abs(a * 2**-shift) */
+ if (shift <= 0) {
+ Py_ssize_t i, shift_digits = -shift / PyLong_SHIFT;
+ digit rem;
+ /* x = a << -shift */
+ if (a_size >= PY_SSIZE_T_MAX - 1 - shift_digits) {
+ /* In practice, it's probably impossible to end up
+ here. Both a and b would have to be enormous,
+ using close to SIZE_T_MAX bytes of memory each. */
+ PyErr_SetString(PyExc_OverflowError,
+ "intermediate overflow during division");
+ goto error;
+ }
+ x = _PyLong_New(a_size + shift_digits + 1);
+ if (x == NULL)
+ goto error;
+ for (i = 0; i < shift_digits; i++)
+ x->ob_digit[i] = 0;
+ rem = v_lshift(x->ob_digit + shift_digits, a->ob_digit,
+ a_size, -shift % PyLong_SHIFT);
+ x->ob_digit[a_size + shift_digits] = rem;
+ }
+ else {
+ Py_ssize_t shift_digits = shift / PyLong_SHIFT;
+ digit rem;
+ /* x = a >> shift */
+ assert(a_size >= shift_digits);
+ x = _PyLong_New(a_size - shift_digits);
+ if (x == NULL)
+ goto error;
+ rem = v_rshift(x->ob_digit, a->ob_digit + shift_digits,
+ a_size - shift_digits, shift % PyLong_SHIFT);
+ /* set inexact if any of the bits shifted out is nonzero */
+ if (rem)
+ inexact = 1;
+ while (!inexact && shift_digits > 0)
+ if (a->ob_digit[--shift_digits])
+ inexact = 1;
+ }
+ long_normalize(x);
+ x_size = Py_SIZE(x);
+
+ /* x //= b. If the remainder is nonzero, set inexact. We own the only
+ reference to x, so it's safe to modify it in-place. */
+ if (b_size == 1) {
+ digit rem = inplace_divrem1(x->ob_digit, x->ob_digit, x_size,
+ b->ob_digit[0]);
+ long_normalize(x);
+ if (rem)
+ inexact = 1;
+ }
+ else {
+ PyLongObject *div, *rem;
+ div = x_divrem(x, b, &rem);
+ Py_DECREF(x);
+ x = div;
+ if (x == NULL)
+ goto error;
+ if (Py_SIZE(rem))
+ inexact = 1;
+ Py_DECREF(rem);
+ }
+ x_size = ABS(Py_SIZE(x));
+ assert(x_size > 0); /* result of division is never zero */
+ x_bits = (x_size-1)*PyLong_SHIFT+bits_in_digit(x->ob_digit[x_size-1]);
+
+ /* The number of extra bits that have to be rounded away. */
+ extra_bits = MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG;
+ assert(extra_bits == 2 || extra_bits == 3);
+
+ /* Round by directly modifying the low digit of x. */
+ mask = (digit)1 << (extra_bits - 1);
+ low = x->ob_digit[0] | inexact;
+ if (low & mask && low & (3*mask-1))
+ low += mask;
+ x->ob_digit[0] = low & ~(mask-1U);
+
+ /* Convert x to a double dx; the conversion is exact. */
+ dx = x->ob_digit[--x_size];
+ while (x_size > 0)
+ dx = dx * PyLong_BASE + x->ob_digit[--x_size];
+ Py_DECREF(x);
+
+ /* Check whether ldexp result will overflow a double. */
+ if (shift + x_bits >= DBL_MAX_EXP &&
+ (shift + x_bits > DBL_MAX_EXP || dx == ldexp(1.0, (int)x_bits)))
+ goto overflow;
+ result = ldexp(dx, (int)shift);
+
+ success:
+ Py_DECREF(a);
+ Py_DECREF(b);
+ return PyFloat_FromDouble(negate ? -result : result);
+
+ underflow_or_zero:
+ Py_DECREF(a);
+ Py_DECREF(b);
+ return PyFloat_FromDouble(negate ? -0.0 : 0.0);
+
+ overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "integer division result too large for a float");
+ error:
+ Py_DECREF(a);
+ Py_DECREF(b);
+ return NULL;
+}
+
+static PyObject *
+long_mod(PyObject *v, PyObject *w)
+{
+ PyLongObject *a, *b, *mod;
+
+ CONVERT_BINOP(v, w, &a, &b);
+
+ if (l_divmod(a, b, NULL, &mod) < 0)
+ mod = NULL;
+ Py_DECREF(a);
+ Py_DECREF(b);
+ return (PyObject *)mod;
+}
+
+static PyObject *
+long_divmod(PyObject *v, PyObject *w)
+{
+ PyLongObject *a, *b, *div, *mod;
+ PyObject *z;
+
+ CONVERT_BINOP(v, w, &a, &b);
+
+ if (l_divmod(a, b, &div, &mod) < 0) {
+ Py_DECREF(a);
+ Py_DECREF(b);
+ return NULL;
+ }
+ z = PyTuple_New(2);
+ if (z != NULL) {
+ PyTuple_SetItem(z, 0, (PyObject *) div);
+ PyTuple_SetItem(z, 1, (PyObject *) mod);
+ }
+ else {
+ Py_DECREF(div);
+ Py_DECREF(mod);
+ }
+ Py_DECREF(a);
+ Py_DECREF(b);
+ return z;
+}
+
+/* pow(v, w, x) */
+static PyObject *
+long_pow(PyObject *v, PyObject *w, PyObject *x)
+{
+ PyLongObject *a, *b, *c; /* a,b,c = v,w,x */
+ int negativeOutput = 0; /* if x<0 return negative output */
+
+ PyLongObject *z = NULL; /* accumulated result */
+ Py_ssize_t i, j, k; /* counters */
+ PyLongObject *temp = NULL;
+
+ /* 5-ary values. If the exponent is large enough, table is
+ * precomputed so that table[i] == a**i % c for i in range(32).
+ */
+ PyLongObject *table[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+ /* a, b, c = v, w, x */
+ CONVERT_BINOP(v, w, &a, &b);
+ if (PyLong_Check(x)) {
+ c = (PyLongObject *)x;
+ Py_INCREF(x);
+ }
+ else if (PyInt_Check(x)) {
+ c = (PyLongObject *)PyLong_FromLong(PyInt_AS_LONG(x));
+ if (c == NULL)
+ goto Error;
+ }
+ else if (x == Py_None)
+ c = NULL;
+ else {
+ Py_DECREF(a);
+ Py_DECREF(b);
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+
+ if (Py_SIZE(b) < 0) { /* if exponent is negative */
+ if (c) {
+ PyErr_SetString(PyExc_TypeError, "pow() 2nd argument "
+ "cannot be negative when 3rd argument specified");
+ goto Error;
+ }
+ else {
+ /* else return a float. This works because we know
+ that this calls float_pow() which converts its
+ arguments to double. */
+ Py_DECREF(a);
+ Py_DECREF(b);
+ return PyFloat_Type.tp_as_number->nb_power(v, w, x);
+ }
+ }
+
+ if (c) {
+ /* if modulus == 0:
+ raise ValueError() */
+ if (Py_SIZE(c) == 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "pow() 3rd argument cannot be 0");
+ goto Error;
+ }
+
+ /* if modulus < 0:
+ negativeOutput = True
+ modulus = -modulus */
+ if (Py_SIZE(c) < 0) {
+ negativeOutput = 1;
+ temp = (PyLongObject *)_PyLong_Copy(c);
+ if (temp == NULL)
+ goto Error;
+ Py_DECREF(c);
+ c = temp;
+ temp = NULL;
+ c->ob_size = - c->ob_size;
+ }
+
+ /* if modulus == 1:
+ return 0 */
+ if ((Py_SIZE(c) == 1) && (c->ob_digit[0] == 1)) {
+ z = (PyLongObject *)PyLong_FromLong(0L);
+ goto Done;
+ }
+
+ /* Reduce base by modulus in some cases:
+ 1. If base < 0. Forcing the base non-negative makes things easier.
+ 2. If base is obviously larger than the modulus. The "small
+ exponent" case later can multiply directly by base repeatedly,
+ while the "large exponent" case multiplies directly by base 31
+ times. It can be unboundedly faster to multiply by
+ base % modulus instead.
+ We could _always_ do this reduction, but l_divmod() isn't cheap,
+ so we only do it when it buys something. */
+ if (Py_SIZE(a) < 0 || Py_SIZE(a) > Py_SIZE(c)) {
+ if (l_divmod(a, c, NULL, &temp) < 0)
+ goto Error;
+ Py_DECREF(a);
+ a = temp;
+ temp = NULL;
+ }
+ }
+
+ /* At this point a, b, and c are guaranteed non-negative UNLESS
+ c is NULL, in which case a may be negative. */
+
+ z = (PyLongObject *)PyLong_FromLong(1L);
+ if (z == NULL)
+ goto Error;
+
+ /* Perform a modular reduction, X = X % c, but leave X alone if c
+ * is NULL.
+ */
+#define REDUCE(X) \
+ do { \
+ if (c != NULL) { \
+ if (l_divmod(X, c, NULL, &temp) < 0) \
+ goto Error; \
+ Py_XDECREF(X); \
+ X = temp; \
+ temp = NULL; \
+ } \
+ } while(0)
+
+ /* Multiply two values, then reduce the result:
+ result = X*Y % c. If c is NULL, skip the mod. */
+#define MULT(X, Y, result) \
+ do { \
+ temp = (PyLongObject *)long_mul(X, Y); \
+ if (temp == NULL) \
+ goto Error; \
+ Py_XDECREF(result); \
+ result = temp; \
+ temp = NULL; \
+ REDUCE(result); \
+ } while(0)
+
+ if (Py_SIZE(b) <= FIVEARY_CUTOFF) {
+ /* Left-to-right binary exponentiation (HAC Algorithm 14.79) */
+ /* http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf */
+ for (i = Py_SIZE(b) - 1; i >= 0; --i) {
+ digit bi = b->ob_digit[i];
+
+ for (j = (digit)1 << (PyLong_SHIFT-1); j != 0; j >>= 1) {
+ MULT(z, z, z);
+ if (bi & j)
+ MULT(z, a, z);
+ }
+ }
+ }
+ else {
+ /* Left-to-right 5-ary exponentiation (HAC Algorithm 14.82) */
+ Py_INCREF(z); /* still holds 1L */
+ table[0] = z;
+ for (i = 1; i < 32; ++i)
+ MULT(table[i-1], a, table[i]);
+
+ for (i = Py_SIZE(b) - 1; i >= 0; --i) {
+ const digit bi = b->ob_digit[i];
+
+ for (j = PyLong_SHIFT - 5; j >= 0; j -= 5) {
+ const int index = (bi >> j) & 0x1f;
+ for (k = 0; k < 5; ++k)
+ MULT(z, z, z);
+ if (index)
+ MULT(z, table[index], z);
+ }
+ }
+ }
+
+ if (negativeOutput && (Py_SIZE(z) != 0)) {
+ temp = (PyLongObject *)long_sub(z, c);
+ if (temp == NULL)
+ goto Error;
+ Py_DECREF(z);
+ z = temp;
+ temp = NULL;
+ }
+ goto Done;
+
+ Error:
+ if (z != NULL) {
+ Py_DECREF(z);
+ z = NULL;
+ }
+ /* fall through */
+ Done:
+ if (Py_SIZE(b) > FIVEARY_CUTOFF) {
+ for (i = 0; i < 32; ++i)
+ Py_XDECREF(table[i]);
+ }
+ Py_DECREF(a);
+ Py_DECREF(b);
+ Py_XDECREF(c);
+ Py_XDECREF(temp);
+ return (PyObject *)z;
+}
+
+static PyObject *
+long_invert(PyLongObject *v)
+{
+ /* Implement ~x as -(x+1) */
+ PyLongObject *x;
+ PyLongObject *w;
+ w = (PyLongObject *)PyLong_FromLong(1L);
+ if (w == NULL)
+ return NULL;
+ x = (PyLongObject *) long_add(v, w);
+ Py_DECREF(w);
+ if (x == NULL)
+ return NULL;
+ Py_SIZE(x) = -(Py_SIZE(x));
+ return (PyObject *)x;
+}
+
+static PyObject *
+long_neg(PyLongObject *v)
+{
+ PyLongObject *z;
+ if (v->ob_size == 0 && PyLong_CheckExact(v)) {
+ /* -0 == 0 */
+ Py_INCREF(v);
+ return (PyObject *) v;
+ }
+ z = (PyLongObject *)_PyLong_Copy(v);
+ if (z != NULL)
+ z->ob_size = -(v->ob_size);
+ return (PyObject *)z;
+}
+
+static PyObject *
+long_abs(PyLongObject *v)
+{
+ if (v->ob_size < 0)
+ return long_neg(v);
+ else
+ return long_long((PyObject *)v);
+}
+
+static int
+long_nonzero(PyLongObject *v)
+{
+ return Py_SIZE(v) != 0;
+}
+
+static PyObject *
+long_rshift(PyLongObject *v, PyLongObject *w)
+{
+ PyLongObject *a, *b;
+ PyLongObject *z = NULL;
+ Py_ssize_t shiftby, newsize, wordshift, loshift, hishift, i, j;
+ digit lomask, himask;
+
+ CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);
+
+ if (Py_SIZE(a) < 0) {
+ /* Right shifting negative numbers is harder */
+ PyLongObject *a1, *a2;
+ a1 = (PyLongObject *) long_invert(a);
+ if (a1 == NULL)
+ goto rshift_error;
+ a2 = (PyLongObject *) long_rshift(a1, b);
+ Py_DECREF(a1);
+ if (a2 == NULL)
+ goto rshift_error;
+ z = (PyLongObject *) long_invert(a2);
+ Py_DECREF(a2);
+ }
+ else {
+ shiftby = PyLong_AsSsize_t((PyObject *)b);
+ if (shiftby == -1L && PyErr_Occurred())
+ goto rshift_error;
+ if (shiftby < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "negative shift count");
+ goto rshift_error;
+ }
+ wordshift = shiftby / PyLong_SHIFT;
+ newsize = ABS(Py_SIZE(a)) - wordshift;
+ if (newsize <= 0) {
+ z = _PyLong_New(0);
+ Py_DECREF(a);
+ Py_DECREF(b);
+ return (PyObject *)z;
+ }
+ loshift = shiftby % PyLong_SHIFT;
+ hishift = PyLong_SHIFT - loshift;
+ lomask = ((digit)1 << hishift) - 1;
+ himask = PyLong_MASK ^ lomask;
+ z = _PyLong_New(newsize);
+ if (z == NULL)
+ goto rshift_error;
+ if (Py_SIZE(a) < 0)
+ Py_SIZE(z) = -(Py_SIZE(z));
+ for (i = 0, j = wordshift; i < newsize; i++, j++) {
+ z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask;
+ if (i+1 < newsize)
+ z->ob_digit[i] |= (a->ob_digit[j+1] << hishift) & himask;
+ }
+ z = long_normalize(z);
+ }
+ rshift_error:
+ Py_DECREF(a);
+ Py_DECREF(b);
+ return (PyObject *) z;
+
+}
+
+static PyObject *
+long_lshift(PyObject *v, PyObject *w)
+{
+ /* This version due to Tim Peters */
+ PyLongObject *a, *b;
+ PyLongObject *z = NULL;
+ Py_ssize_t shiftby, oldsize, newsize, wordshift, remshift, i, j;
+ twodigits accum;
+
+ CONVERT_BINOP(v, w, &a, &b);
+
+ shiftby = PyLong_AsSsize_t((PyObject *)b);
+ if (shiftby == -1L && PyErr_Occurred())
+ goto lshift_error;
+ if (shiftby < 0) {
+ PyErr_SetString(PyExc_ValueError, "negative shift count");
+ goto lshift_error;
+ }
+ /* wordshift, remshift = divmod(shiftby, PyLong_SHIFT) */
+ wordshift = shiftby / PyLong_SHIFT;
+ remshift = shiftby - wordshift * PyLong_SHIFT;
+
+ oldsize = ABS(a->ob_size);
+ newsize = oldsize + wordshift;
+ if (remshift)
+ ++newsize;
+ z = _PyLong_New(newsize);
+ if (z == NULL)
+ goto lshift_error;
+ if (a->ob_size < 0)
+ z->ob_size = -(z->ob_size);
+ for (i = 0; i < wordshift; i++)
+ z->ob_digit[i] = 0;
+ accum = 0;
+ for (i = wordshift, j = 0; j < oldsize; i++, j++) {
+ accum |= (twodigits)a->ob_digit[j] << remshift;
+ z->ob_digit[i] = (digit)(accum & PyLong_MASK);
+ accum >>= PyLong_SHIFT;
+ }
+ if (remshift)
+ z->ob_digit[newsize-1] = (digit)accum;
+ else
+ assert(!accum);
+ z = long_normalize(z);
+ lshift_error:
+ Py_DECREF(a);
+ Py_DECREF(b);
+ return (PyObject *) z;
+}
+
+/* Compute two's complement of digit vector a[0:m], writing result to
+ z[0:m]. The digit vector a need not be normalized, but should not
+ be entirely zero. a and z may point to the same digit vector. */
+
+static void
+v_complement(digit *z, digit *a, Py_ssize_t m)
+{
+ Py_ssize_t i;
+ digit carry = 1;
+ for (i = 0; i < m; ++i) {
+ carry += a[i] ^ PyLong_MASK;
+ z[i] = carry & PyLong_MASK;
+ carry >>= PyLong_SHIFT;
+ }
+ assert(carry == 0);
+}
+
+/* Bitwise and/xor/or operations */
+
+static PyObject *
+long_bitwise(PyLongObject *a,
+ int op, /* '&', '|', '^' */
+ PyLongObject *b)
+{
+ int nega, negb, negz;
+ Py_ssize_t size_a, size_b, size_z, i;
+ PyLongObject *z;
+
+ /* Bitwise operations for negative numbers operate as though
+ on a two's complement representation. So convert arguments
+ from sign-magnitude to two's complement, and convert the
+ result back to sign-magnitude at the end. */
+
+ /* If a is negative, replace it by its two's complement. */
+ size_a = ABS(Py_SIZE(a));
+ nega = Py_SIZE(a) < 0;
+ if (nega) {
+ z = _PyLong_New(size_a);
+ if (z == NULL)
+ return NULL;
+ v_complement(z->ob_digit, a->ob_digit, size_a);
+ a = z;
+ }
+ else
+ /* Keep reference count consistent. */
+ Py_INCREF(a);
+
+ /* Same for b. */
+ size_b = ABS(Py_SIZE(b));
+ negb = Py_SIZE(b) < 0;
+ if (negb) {
+ z = _PyLong_New(size_b);
+ if (z == NULL) {
+ Py_DECREF(a);
+ return NULL;
+ }
+ v_complement(z->ob_digit, b->ob_digit, size_b);
+ b = z;
+ }
+ else
+ Py_INCREF(b);
+
+ /* Swap a and b if necessary to ensure size_a >= size_b. */
+ if (size_a < size_b) {
+ z = a; a = b; b = z;
+ size_z = size_a; size_a = size_b; size_b = size_z;
+ negz = nega; nega = negb; negb = negz;
+ }
+
+ /* JRH: The original logic here was to allocate the result value (z)
+ as the longer of the two operands. However, there are some cases
+ where the result is guaranteed to be shorter than that: AND of two
+ positives, OR of two negatives: use the shorter number. AND with
+ mixed signs: use the positive number. OR with mixed signs: use the
+ negative number.
+ */
+ switch (op) {
+ case '^':
+ negz = nega ^ negb;
+ size_z = size_a;
+ break;
+ case '&':
+ negz = nega & negb;
+ size_z = negb ? size_a : size_b;
+ break;
+ case '|':
+ negz = nega | negb;
+ size_z = negb ? size_b : size_a;
+ break;
+ default:
+ PyErr_BadArgument();
+ return NULL;
+ }
+
+ /* We allow an extra digit if z is negative, to make sure that
+ the final two's complement of z doesn't overflow. */
+ z = _PyLong_New(size_z + negz);
+ if (z == NULL) {
+ Py_DECREF(a);
+ Py_DECREF(b);
+ return NULL;
+ }
+
+ /* Compute digits for overlap of a and b. */
+ switch(op) {
+ case '&':
+ for (i = 0; i < size_b; ++i)
+ z->ob_digit[i] = a->ob_digit[i] & b->ob_digit[i];
+ break;
+ case '|':
+ for (i = 0; i < size_b; ++i)
+ z->ob_digit[i] = a->ob_digit[i] | b->ob_digit[i];
+ break;
+ case '^':
+ for (i = 0; i < size_b; ++i)
+ z->ob_digit[i] = a->ob_digit[i] ^ b->ob_digit[i];
+ break;
+ default:
+ PyErr_BadArgument();
+ return NULL;
+ }
+
+ /* Copy any remaining digits of a, inverting if necessary. */
+ if (op == '^' && negb)
+ for (; i < size_z; ++i)
+ z->ob_digit[i] = a->ob_digit[i] ^ PyLong_MASK;
+ else if (i < size_z)
+ memcpy(&z->ob_digit[i], &a->ob_digit[i],
+ (size_z-i)*sizeof(digit));
+
+ /* Complement result if negative. */
+ if (negz) {
+ Py_SIZE(z) = -(Py_SIZE(z));
+ z->ob_digit[size_z] = PyLong_MASK;
+ v_complement(z->ob_digit, z->ob_digit, size_z+1);
+ }
+
+ Py_DECREF(a);
+ Py_DECREF(b);
+ return (PyObject *)long_normalize(z);
+}
+
+static PyObject *
+long_and(PyObject *v, PyObject *w)
+{
+ PyLongObject *a, *b;
+ PyObject *c;
+ CONVERT_BINOP(v, w, &a, &b);
+ c = long_bitwise(a, '&', b);
+ Py_DECREF(a);
+ Py_DECREF(b);
+ return c;
+}
+
+static PyObject *
+long_xor(PyObject *v, PyObject *w)
+{
+ PyLongObject *a, *b;
+ PyObject *c;
+ CONVERT_BINOP(v, w, &a, &b);
+ c = long_bitwise(a, '^', b);
+ Py_DECREF(a);
+ Py_DECREF(b);
+ return c;
+}
+
+static PyObject *
+long_or(PyObject *v, PyObject *w)
+{
+ PyLongObject *a, *b;
+ PyObject *c;
+ CONVERT_BINOP(v, w, &a, &b);
+ c = long_bitwise(a, '|', b);
+ Py_DECREF(a);
+ Py_DECREF(b);
+ return c;
+}
+
+static int
+long_coerce(PyObject **pv, PyObject **pw)
+{
+ if (PyInt_Check(*pw)) {
+ *pw = PyLong_FromLong(PyInt_AS_LONG(*pw));
+ if (*pw == NULL)
+ return -1;
+ Py_INCREF(*pv);
+ return 0;
+ }
+ else if (PyLong_Check(*pw)) {
+ Py_INCREF(*pv);
+ Py_INCREF(*pw);
+ return 0;
+ }
+ return 1; /* Can't do it */
+}
+
+static PyObject *
+long_long(PyObject *v)
+{
+ if (PyLong_CheckExact(v))
+ Py_INCREF(v);
+ else
+ v = _PyLong_Copy((PyLongObject *)v);
+ return v;
+}
+
+static PyObject *
+long_int(PyObject *v)
+{
+ long x;
+ x = PyLong_AsLong(v);
+ if (PyErr_Occurred()) {
+ if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
+ PyErr_Clear();
+ if (PyLong_CheckExact(v)) {
+ Py_INCREF(v);
+ return v;
+ }
+ else
+ return _PyLong_Copy((PyLongObject *)v);
+ }
+ else
+ return NULL;
+ }
+ return PyInt_FromLong(x);
+}
+
+static PyObject *
+long_float(PyObject *v)
+{
+ double result;
+ result = PyLong_AsDouble(v);
+ if (result == -1.0 && PyErr_Occurred())
+ return NULL;
+ return PyFloat_FromDouble(result);
+}
+
+static PyObject *
+long_oct(PyObject *v)
+{
+ return _PyLong_Format(v, 8, 1, 0);
+}
+
+static PyObject *
+long_hex(PyObject *v)
+{
+ return _PyLong_Format(v, 16, 1, 0);
+}
+
+static PyObject *
+long_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
+
+static PyObject *
+long_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *x = NULL;
+ int base = -909; /* unlikely! */
+ static char *kwlist[] = {"x", "base", 0};
+
+ if (type != &PyLong_Type)
+ return long_subtype_new(type, args, kwds); /* Wimp out */
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:long", kwlist,
+ &x, &base))
+ return NULL;
+ if (x == NULL) {
+ if (base != -909) {
+ PyErr_SetString(PyExc_TypeError,
+ "long() missing string argument");
+ return NULL;
+ }
+ return PyLong_FromLong(0L);
+ }
+ if (base == -909)
+ return PyNumber_Long(x);
+ else if (PyString_Check(x)) {
+ /* Since PyLong_FromString doesn't have a length parameter,
+ * check here for possible NULs in the string. */
+ char *string = PyString_AS_STRING(x);
+ if (strlen(string) != (size_t)PyString_Size(x)) {
+ /* create a repr() of the input string,
+ * just like PyLong_FromString does. */
+ PyObject *srepr;
+ srepr = PyObject_Repr(x);
+ if (srepr == NULL)
+ return NULL;
+ PyErr_Format(PyExc_ValueError,
+ "invalid literal for long() with base %d: %s",
+ base, PyString_AS_STRING(srepr));
+ Py_DECREF(srepr);
+ return NULL;
+ }
+ return PyLong_FromString(PyString_AS_STRING(x), NULL, base);
+ }
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_Check(x))
+ return PyLong_FromUnicode(PyUnicode_AS_UNICODE(x),
+ PyUnicode_GET_SIZE(x),
+ base);
+#endif
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "long() can't convert non-string with explicit base");
+ return NULL;
+ }
+}
+
+/* Wimpy, slow approach to tp_new calls for subtypes of long:
+ first create a regular long from whatever arguments we got,
+ then allocate a subtype instance and initialize it from
+ the regular long. The regular long is then thrown away.
+*/
+static PyObject *
+long_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyLongObject *tmp, *newobj;
+ Py_ssize_t i, n;
+
+ assert(PyType_IsSubtype(type, &PyLong_Type));
+ tmp = (PyLongObject *)long_new(&PyLong_Type, args, kwds);
+ if (tmp == NULL)
+ return NULL;
+ assert(PyLong_CheckExact(tmp));
+ n = Py_SIZE(tmp);
+ if (n < 0)
+ n = -n;
+ newobj = (PyLongObject *)type->tp_alloc(type, n);
+ if (newobj == NULL) {
+ Py_DECREF(tmp);
+ return NULL;
+ }
+ assert(PyLong_Check(newobj));
+ Py_SIZE(newobj) = Py_SIZE(tmp);
+ for (i = 0; i < n; i++)
+ newobj->ob_digit[i] = tmp->ob_digit[i];
+ Py_DECREF(tmp);
+ return (PyObject *)newobj;
+}
+
+static PyObject *
+long_getnewargs(PyLongObject *v)
+{
+ return Py_BuildValue("(N)", _PyLong_Copy(v));
+}
+
+static PyObject *
+long_get0(PyLongObject *v, void *context) {
+ return PyLong_FromLong(0L);
+}
+
+static PyObject *
+long_get1(PyLongObject *v, void *context) {
+ return PyLong_FromLong(1L);
+}
+
+static PyObject *
+long__format__(PyObject *self, PyObject *args)
+{
+ PyObject *format_spec;
+
+ if (!PyArg_ParseTuple(args, "O:__format__", &format_spec))
+ return NULL;
+ if (PyBytes_Check(format_spec))
+ return _PyLong_FormatAdvanced(self,
+ PyBytes_AS_STRING(format_spec),
+ PyBytes_GET_SIZE(format_spec));
+ if (PyUnicode_Check(format_spec)) {
+ /* Convert format_spec to a str */
+ PyObject *result;
+ PyObject *str_spec = PyObject_Str(format_spec);
+
+ if (str_spec == NULL)
+ return NULL;
+
+ result = _PyLong_FormatAdvanced(self,
+ PyBytes_AS_STRING(str_spec),
+ PyBytes_GET_SIZE(str_spec));
+
+ Py_DECREF(str_spec);
+ return result;
+ }
+ PyErr_SetString(PyExc_TypeError, "__format__ requires str or unicode");
+ return NULL;
+}
+
+static PyObject *
+long_sizeof(PyLongObject *v)
+{
+ Py_ssize_t res;
+
+ res = v->ob_type->tp_basicsize + ABS(Py_SIZE(v))*sizeof(digit);
+ return PyInt_FromSsize_t(res);
+}
+
+static PyObject *
+long_bit_length(PyLongObject *v)
+{
+ PyLongObject *result, *x, *y;
+ Py_ssize_t ndigits, msd_bits = 0;
+ digit msd;
+
+ assert(v != NULL);
+ assert(PyLong_Check(v));
+
+ ndigits = ABS(Py_SIZE(v));
+ if (ndigits == 0)
+ return PyInt_FromLong(0);
+
+ msd = v->ob_digit[ndigits-1];
+ while (msd >= 32) {
+ msd_bits += 6;
+ msd >>= 6;
+ }
+ msd_bits += (long)(BitLengthTable[msd]);
+
+ if (ndigits <= PY_SSIZE_T_MAX/PyLong_SHIFT)
+ return PyInt_FromSsize_t((ndigits-1)*PyLong_SHIFT + msd_bits);
+
+ /* expression above may overflow; use Python integers instead */
+ result = (PyLongObject *)PyLong_FromSsize_t(ndigits - 1);
+ if (result == NULL)
+ return NULL;
+ x = (PyLongObject *)PyLong_FromLong(PyLong_SHIFT);
+ if (x == NULL)
+ goto error;
+ y = (PyLongObject *)long_mul(result, x);
+ Py_DECREF(x);
+ if (y == NULL)
+ goto error;
+ Py_DECREF(result);
+ result = y;
+
+ x = (PyLongObject *)PyLong_FromLong((long)msd_bits);
+ if (x == NULL)
+ goto error;
+ y = (PyLongObject *)long_add(result, x);
+ Py_DECREF(x);
+ if (y == NULL)
+ goto error;
+ Py_DECREF(result);
+ result = y;
+
+ return (PyObject *)result;
+
+ error:
+ Py_DECREF(result);
+ return NULL;
+}
+
+PyDoc_STRVAR(long_bit_length_doc,
+"long.bit_length() -> int or long\n\
+\n\
+Number of bits necessary to represent self in binary.\n\
+>>> bin(37L)\n\
+'0b100101'\n\
+>>> (37L).bit_length()\n\
+6");
+
+#if 0
+static PyObject *
+long_is_finite(PyObject *v)
+{
+ Py_RETURN_TRUE;
+}
+#endif
+
+static PyMethodDef long_methods[] = {
+ {"conjugate", (PyCFunction)long_long, METH_NOARGS,
+ "Returns self, the complex conjugate of any long."},
+ {"bit_length", (PyCFunction)long_bit_length, METH_NOARGS,
+ long_bit_length_doc},
+#if 0
+ {"is_finite", (PyCFunction)long_is_finite, METH_NOARGS,
+ "Returns always True."},
+#endif
+ {"__trunc__", (PyCFunction)long_long, METH_NOARGS,
+ "Truncating an Integral returns itself."},
+ {"__getnewargs__", (PyCFunction)long_getnewargs, METH_NOARGS},
+ {"__format__", (PyCFunction)long__format__, METH_VARARGS},
+ {"__sizeof__", (PyCFunction)long_sizeof, METH_NOARGS,
+ "Returns size in memory, in bytes"},
+ {NULL, NULL} /* sentinel */
+};
+
+static PyGetSetDef long_getset[] = {
+ {"real",
+ (getter)long_long, (setter)NULL,
+ "the real part of a complex number",
+ NULL},
+ {"imag",
+ (getter)long_get0, (setter)NULL,
+ "the imaginary part of a complex number",
+ NULL},
+ {"numerator",
+ (getter)long_long, (setter)NULL,
+ "the numerator of a rational number in lowest terms",
+ NULL},
+ {"denominator",
+ (getter)long_get1, (setter)NULL,
+ "the denominator of a rational number in lowest terms",
+ NULL},
+ {NULL} /* Sentinel */
+};
+
+PyDoc_STRVAR(long_doc,
+"long(x=0) -> long\n\
+long(x, base=10) -> long\n\
+\n\
+Convert a number or string to a long integer, or return 0L if no arguments\n\
+are given. If x is floating point, the conversion truncates towards zero.\n\
+\n\
+If x is not a number or if base is given, then x must be a string or\n\
+Unicode object representing an integer literal in the given base. The\n\
+literal can be preceded by '+' or '-' and be surrounded by whitespace.\n\
+The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to\n\
+interpret the base from the string as an integer literal.\n\
+>>> int('0b100', base=0)\n\
+4L");
+
+static PyNumberMethods long_as_number = {
+ (binaryfunc)long_add, /*nb_add*/
+ (binaryfunc)long_sub, /*nb_subtract*/
+ (binaryfunc)long_mul, /*nb_multiply*/
+ long_classic_div, /*nb_divide*/
+ long_mod, /*nb_remainder*/
+ long_divmod, /*nb_divmod*/
+ long_pow, /*nb_power*/
+ (unaryfunc)long_neg, /*nb_negative*/
+ (unaryfunc)long_long, /*tp_positive*/
+ (unaryfunc)long_abs, /*tp_absolute*/
+ (inquiry)long_nonzero, /*tp_nonzero*/
+ (unaryfunc)long_invert, /*nb_invert*/
+ long_lshift, /*nb_lshift*/
+ (binaryfunc)long_rshift, /*nb_rshift*/
+ long_and, /*nb_and*/
+ long_xor, /*nb_xor*/
+ long_or, /*nb_or*/
+ long_coerce, /*nb_coerce*/
+ long_int, /*nb_int*/
+ long_long, /*nb_long*/
+ long_float, /*nb_float*/
+ long_oct, /*nb_oct*/
+ long_hex, /*nb_hex*/
+ 0, /* nb_inplace_add */
+ 0, /* nb_inplace_subtract */
+ 0, /* nb_inplace_multiply */
+ 0, /* nb_inplace_divide */
+ 0, /* nb_inplace_remainder */
+ 0, /* nb_inplace_power */
+ 0, /* nb_inplace_lshift */
+ 0, /* nb_inplace_rshift */
+ 0, /* nb_inplace_and */
+ 0, /* nb_inplace_xor */
+ 0, /* nb_inplace_or */
+ long_div, /* nb_floor_divide */
+ long_true_divide, /* nb_true_divide */
+ 0, /* nb_inplace_floor_divide */
+ 0, /* nb_inplace_true_divide */
+ long_long, /* nb_index */
+};
+
+PyTypeObject PyLong_Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /* ob_size */
+ "long", /* tp_name */
+ offsetof(PyLongObject, ob_digit), /* tp_basicsize */
+ sizeof(digit), /* tp_itemsize */
+ long_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ (cmpfunc)long_compare, /* tp_compare */
+ long_repr, /* tp_repr */
+ &long_as_number, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)long_hash, /* tp_hash */
+ 0, /* tp_call */
+ long_str, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
+ Py_TPFLAGS_BASETYPE | Py_TPFLAGS_LONG_SUBCLASS, /* tp_flags */
+ long_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ long_methods, /* tp_methods */
+ 0, /* tp_members */
+ long_getset, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ long_new, /* tp_new */
+ PyObject_Del, /* tp_free */
+};
+
+static PyTypeObject Long_InfoType;
+
+PyDoc_STRVAR(long_info__doc__,
+"sys.long_info\n\
+\n\
+A struct sequence that holds information about Python's\n\
+internal representation of integers. The attributes are read only.");
+
+static PyStructSequence_Field long_info_fields[] = {
+ {"bits_per_digit", "size of a digit in bits"},
+ {"sizeof_digit", "size in bytes of the C type used to represent a digit"},
+ {NULL, NULL}
+};
+
+static PyStructSequence_Desc long_info_desc = {
+ "sys.long_info", /* name */
+ long_info__doc__, /* doc */
+ long_info_fields, /* fields */
+ 2 /* number of fields */
+};
+
+PyObject *
+PyLong_GetInfo(void)
+{
+ PyObject* long_info;
+ int field = 0;
+ long_info = PyStructSequence_New(&Long_InfoType);
+ if (long_info == NULL)
+ return NULL;
+ PyStructSequence_SET_ITEM(long_info, field++,
+ PyInt_FromLong(PyLong_SHIFT));
+ PyStructSequence_SET_ITEM(long_info, field++,
+ PyInt_FromLong(sizeof(digit)));
+ if (PyErr_Occurred()) {
+ Py_CLEAR(long_info);
+ return NULL;
+ }
+ return long_info;
+}
+
+int
+_PyLong_Init(void)
+{
+ /* initialize long_info */
+ if (Long_InfoType.tp_name == 0)
+ PyStructSequence_InitType(&Long_InfoType, &long_info_desc);
+ return 1;
+}
diff --git a/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Objects/stringlib/localeutil.h b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Objects/stringlib/localeutil.h new file mode 100644 index 0000000000..3ab7f55962 --- /dev/null +++ b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Objects/stringlib/localeutil.h @@ -0,0 +1,212 @@ +/* stringlib: locale related helpers implementation */
+
+#ifndef STRINGLIB_LOCALEUTIL_H
+#define STRINGLIB_LOCALEUTIL_H
+
+#include <locale.h>
+
+#define MAX(x, y) ((x) < (y) ? (y) : (x))
+#define MIN(x, y) ((x) < (y) ? (x) : (y))
+
+typedef struct {
+ const char *grouping;
+ char previous;
+ Py_ssize_t i; /* Where we're currently pointing in grouping. */
+} GroupGenerator;
+
+static void
+_GroupGenerator_init(GroupGenerator *self, const char *grouping)
+{
+ self->grouping = grouping;
+ self->i = 0;
+ self->previous = 0;
+}
+
+/* Returns the next grouping, or 0 to signify end. */
+static Py_ssize_t
+_GroupGenerator_next(GroupGenerator *self)
+{
+ /* Note that we don't really do much error checking here. If a
+ grouping string contains just CHAR_MAX, for example, then just
+ terminate the generator. That shouldn't happen, but at least we
+ fail gracefully. */
+ switch (self->grouping[self->i]) {
+ case 0:
+ return self->previous;
+ case CHAR_MAX:
+ /* Stop the generator. */
+ return 0;
+ default: {
+ char ch = self->grouping[self->i];
+ self->previous = ch;
+ self->i++;
+ return (Py_ssize_t)ch;
+ }
+ }
+}
+
+/* Fill in some digits, leading zeros, and thousands separator. All
+ are optional, depending on when we're called. */
+static void
+fill(STRINGLIB_CHAR **digits_end, STRINGLIB_CHAR **buffer_end,
+ Py_ssize_t n_chars, Py_ssize_t n_zeros, const char* thousands_sep,
+ Py_ssize_t thousands_sep_len)
+{
+#if STRINGLIB_IS_UNICODE
+ Py_ssize_t i;
+#endif
+
+ if (thousands_sep) {
+ *buffer_end -= thousands_sep_len;
+
+ /* Copy the thousands_sep chars into the buffer. */
+#if STRINGLIB_IS_UNICODE
+ /* Convert from the char's of the thousands_sep from
+ the locale into unicode. */
+ for (i = 0; i < thousands_sep_len; ++i)
+ (*buffer_end)[i] = thousands_sep[i];
+#else
+ /* No conversion, just memcpy the thousands_sep. */
+ memcpy(*buffer_end, thousands_sep, thousands_sep_len);
+#endif
+ }
+
+ *buffer_end -= n_chars;
+ *digits_end -= n_chars;
+ memcpy(*buffer_end, *digits_end, n_chars * sizeof(STRINGLIB_CHAR));
+
+ *buffer_end -= n_zeros;
+ STRINGLIB_FILL(*buffer_end, '0', n_zeros);
+}
+
+/**
+ * _Py_InsertThousandsGrouping:
+ * @buffer: A pointer to the start of a string.
+ * @n_buffer: Number of characters in @buffer.
+ * @digits: A pointer to the digits we're reading from. If count
+ * is non-NULL, this is unused.
+ * @n_digits: The number of digits in the string, in which we want
+ * to put the grouping chars.
+ * @min_width: The minimum width of the digits in the output string.
+ * Output will be zero-padded on the left to fill.
+ * @grouping: see definition in localeconv().
+ * @thousands_sep: see definition in localeconv().
+ *
+ * There are 2 modes: counting and filling. If @buffer is NULL,
+ * we are in counting mode, else filling mode.
+ * If counting, the required buffer size is returned.
+ * If filling, we know the buffer will be large enough, so we don't
+ * need to pass in the buffer size.
+ * Inserts thousand grouping characters (as defined by grouping and
+ * thousands_sep) into the string between buffer and buffer+n_digits.
+ *
+ * Return value: 0 on error, else 1. Note that no error can occur if
+ * count is non-NULL.
+ *
+ * This name won't be used, the includer of this file should define
+ * it to be the actual function name, based on unicode or string.
+ *
+ * As closely as possible, this code mimics the logic in decimal.py's
+ _insert_thousands_sep().
+ **/
+Py_ssize_t
+_Py_InsertThousandsGrouping(STRINGLIB_CHAR *buffer,
+ Py_ssize_t n_buffer,
+ STRINGLIB_CHAR *digits,
+ Py_ssize_t n_digits,
+ Py_ssize_t min_width,
+ const char *grouping,
+ const char *thousands_sep)
+{
+ Py_ssize_t count = 0;
+ Py_ssize_t n_zeros;
+ int loop_broken = 0;
+ int use_separator = 0; /* First time through, don't append the
+ separator. They only go between
+ groups. */
+ STRINGLIB_CHAR *buffer_end = NULL;
+ STRINGLIB_CHAR *digits_end = NULL;
+ Py_ssize_t l;
+ Py_ssize_t n_chars;
+ Py_ssize_t thousands_sep_len = strlen(thousands_sep);
+ Py_ssize_t remaining = n_digits; /* Number of chars remaining to
+ be looked at */
+ /* A generator that returns all of the grouping widths, until it
+ returns 0. */
+ GroupGenerator groupgen;
+ _GroupGenerator_init(&groupgen, grouping);
+
+ if (buffer) {
+ buffer_end = buffer + n_buffer;
+ digits_end = digits + n_digits;
+ }
+
+ while ((l = _GroupGenerator_next(&groupgen)) > 0) {
+ l = MIN(l, MAX(MAX(remaining, min_width), 1));
+ n_zeros = MAX(0, l - remaining);
+ n_chars = MAX(0, MIN(remaining, l));
+
+ /* Use n_zero zero's and n_chars chars */
+
+ /* Count only, don't do anything. */
+ count += (use_separator ? thousands_sep_len : 0) + n_zeros + n_chars;
+
+ if (buffer) {
+ /* Copy into the output buffer. */
+ fill(&digits_end, &buffer_end, n_chars, n_zeros,
+ use_separator ? thousands_sep : NULL, thousands_sep_len);
+ }
+
+ /* Use a separator next time. */
+ use_separator = 1;
+
+ remaining -= n_chars;
+ min_width -= l;
+
+ if (remaining <= 0 && min_width <= 0) {
+ loop_broken = 1;
+ break;
+ }
+ min_width -= thousands_sep_len;
+ }
+ if (!loop_broken) {
+ /* We left the loop without using a break statement. */
+
+ l = MAX(MAX(remaining, min_width), 1);
+ n_zeros = MAX(0, l - remaining);
+ n_chars = MAX(0, MIN(remaining, l));
+
+ /* Use n_zero zero's and n_chars chars */
+ count += (use_separator ? thousands_sep_len : 0) + n_zeros + n_chars;
+ if (buffer) {
+ /* Copy into the output buffer. */
+ fill(&digits_end, &buffer_end, n_chars, n_zeros,
+ use_separator ? thousands_sep : NULL, thousands_sep_len);
+ }
+ }
+ return count;
+}
+
+/**
+ * _Py_InsertThousandsGroupingLocale:
+ * @buffer: A pointer to the start of a string.
+ * @n_digits: The number of digits in the string, in which we want
+ * to put the grouping chars.
+ *
+ * Reads thee current locale and calls _Py_InsertThousandsGrouping().
+ **/
+Py_ssize_t
+_Py_InsertThousandsGroupingLocale(STRINGLIB_CHAR *buffer,
+ Py_ssize_t n_buffer,
+ STRINGLIB_CHAR *digits,
+ Py_ssize_t n_digits,
+ Py_ssize_t min_width)
+{
+ struct lconv *locale_data = localeconv();
+ const char *grouping = locale_data->grouping;
+ const char *thousands_sep = locale_data->thousands_sep;
+
+ return _Py_InsertThousandsGrouping(buffer, n_buffer, digits, n_digits,
+ min_width, grouping, thousands_sep);
+}
+#endif /* STRINGLIB_LOCALEUTIL_H */
diff --git a/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Python/getcopyright.c b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Python/getcopyright.c new file mode 100644 index 0000000000..314c5728bc --- /dev/null +++ b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Python/getcopyright.c @@ -0,0 +1,23 @@ +/* Return the copyright string. This is updated manually. */
+
+#include "Python.h"
+
+static char cprt[] =
+"\
+Copyright (c) 2001-2015 Python Software Foundation.\n\
+All Rights Reserved.\n\
+\n\
+Copyright (c) 2000 BeOpen.com.\n\
+All Rights Reserved.\n\
+\n\
+Copyright (c) 1995-2001 Corporation for National Research Initiatives.\n\
+All Rights Reserved.\n\
+\n\
+Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam.\n\
+All Rights Reserved.";
+
+const char *
+Py_GetCopyright(void)
+{
+ return cprt;
+}
diff --git a/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Python/marshal.c b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Python/marshal.c new file mode 100644 index 0000000000..290be0db8e --- /dev/null +++ b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Python/marshal.c @@ -0,0 +1,1412 @@ +
+/* Write Python objects to files and read them back.
+ This is intended for writing and reading compiled Python code only;
+ a true persistent storage facility would be much harder, since
+ it would have to take circular links and sharing into account. */
+
+#define PY_SSIZE_T_CLEAN
+
+#include "Python.h"
+#include "longintrepr.h"
+#include "code.h"
+#include "marshal.h"
+
+#define ABS(x) ((x) < 0 ? -(x) : (x))
+
+/* High water mark to determine when the marshalled object is dangerously deep
+ * and risks coring the interpreter. When the object stack gets this deep,
+ * raise an exception instead of continuing.
+ */
+#define MAX_MARSHAL_STACK_DEPTH 2000
+
+#define TYPE_NULL '0'
+#define TYPE_NONE 'N'
+#define TYPE_FALSE 'F'
+#define TYPE_TRUE 'T'
+#define TYPE_STOPITER 'S'
+#define TYPE_ELLIPSIS '.'
+#define TYPE_INT 'i'
+#define TYPE_INT64 'I'
+#define TYPE_FLOAT 'f'
+#define TYPE_BINARY_FLOAT 'g'
+#define TYPE_COMPLEX 'x'
+#define TYPE_BINARY_COMPLEX 'y'
+#define TYPE_LONG 'l'
+#define TYPE_STRING 's'
+#define TYPE_INTERNED 't'
+#define TYPE_STRINGREF 'R'
+#define TYPE_TUPLE '('
+#define TYPE_LIST '['
+#define TYPE_DICT '{'
+#define TYPE_CODE 'c'
+#define TYPE_UNICODE 'u'
+#define TYPE_UNKNOWN '?'
+#define TYPE_SET '<'
+#define TYPE_FROZENSET '>'
+
+#define WFERR_OK 0
+#define WFERR_UNMARSHALLABLE 1
+#define WFERR_NESTEDTOODEEP 2
+#define WFERR_NOMEMORY 3
+
+typedef struct {
+ FILE *fp;
+ int error; /* see WFERR_* values */
+ int depth;
+ /* If fp == NULL, the following are valid: */
+ PyObject *str;
+ char *ptr;
+ char *end;
+ PyObject *strings; /* dict on marshal, list on unmarshal */
+ int version;
+} WFILE;
+
+#define w_byte(c, p) if (((p)->fp)) putc((c), (p)->fp); \
+ else if ((p)->ptr != (p)->end) *(p)->ptr++ = (c); \
+ else w_more(c, p)
+
+static void
+w_more(int c, WFILE *p)
+{
+ Py_ssize_t size, newsize;
+ if (p->str == NULL)
+ return; /* An error already occurred */
+ size = PyString_Size(p->str);
+ newsize = size + size + 1024;
+ if (newsize > 32*1024*1024) {
+ newsize = size + (size >> 3); /* 12.5% overallocation */
+ }
+ if (_PyString_Resize(&p->str, newsize) != 0) {
+ p->ptr = p->end = NULL;
+ }
+ else {
+ p->ptr = PyString_AS_STRING((PyStringObject *)p->str) + size;
+ p->end =
+ PyString_AS_STRING((PyStringObject *)p->str) + newsize;
+ *p->ptr++ = Py_SAFE_DOWNCAST(c, int, char);
+ }
+}
+
+static void
+w_string(const char *s, Py_ssize_t n, WFILE *p)
+{
+ if (p->fp != NULL) {
+ fwrite(s, 1, n, p->fp);
+ }
+ else {
+ while (--n >= 0) {
+ w_byte(*s, p);
+ s++;
+ }
+ }
+}
+
+static void
+w_short(int x, WFILE *p)
+{
+ w_byte((char)( x & 0xff), p);
+ w_byte((char)((x>> 8) & 0xff), p);
+}
+
+static void
+w_long(long x, WFILE *p)
+{
+ w_byte((char)( x & 0xff), p);
+ w_byte((char)((x>> 8) & 0xff), p);
+ w_byte((char)((x>>16) & 0xff), p);
+ w_byte((char)((x>>24) & 0xff), p);
+}
+
+#if SIZEOF_LONG > 4
+static void
+w_long64(long x, WFILE *p)
+{
+ w_long(x, p);
+ w_long(x>>32, p);
+}
+#endif
+
+#define SIZE32_MAX 0x7FFFFFFF
+
+#if SIZEOF_SIZE_T > 4
+# define W_SIZE(n, p) do { \
+ if ((n) > SIZE32_MAX) { \
+ (p)->depth--; \
+ (p)->error = WFERR_UNMARSHALLABLE; \
+ return; \
+ } \
+ w_long((long)(n), p); \
+ } while(0)
+#else
+# define W_SIZE w_long
+#endif
+
+static void
+w_pstring(const char *s, Py_ssize_t n, WFILE *p)
+{
+ W_SIZE(n, p);
+ w_string(s, n, p);
+}
+
+/* We assume that Python longs are stored internally in base some power of
+ 2**15; for the sake of portability we'll always read and write them in base
+ exactly 2**15. */
+
+#define PyLong_MARSHAL_SHIFT 15
+#define PyLong_MARSHAL_BASE ((short)1 << PyLong_MARSHAL_SHIFT)
+#define PyLong_MARSHAL_MASK (PyLong_MARSHAL_BASE - 1)
+#if PyLong_SHIFT % PyLong_MARSHAL_SHIFT != 0
+#error "PyLong_SHIFT must be a multiple of PyLong_MARSHAL_SHIFT"
+#endif
+#define PyLong_MARSHAL_RATIO (PyLong_SHIFT / PyLong_MARSHAL_SHIFT)
+
+static void
+w_PyLong(const PyLongObject *ob, WFILE *p)
+{
+ Py_ssize_t i, j, n, l;
+ digit d;
+
+ w_byte(TYPE_LONG, p);
+ if (Py_SIZE(ob) == 0) {
+ w_long((long)0, p);
+ return;
+ }
+
+ /* set l to number of base PyLong_MARSHAL_BASE digits */
+ n = ABS(Py_SIZE(ob));
+ l = (n-1) * PyLong_MARSHAL_RATIO;
+ d = ob->ob_digit[n-1];
+ assert(d != 0); /* a PyLong is always normalized */
+ do {
+ d >>= PyLong_MARSHAL_SHIFT;
+ l++;
+ } while (d != 0);
+ if (l > SIZE32_MAX) {
+ p->depth--;
+ p->error = WFERR_UNMARSHALLABLE;
+ return;
+ }
+ w_long((long)(Py_SIZE(ob) > 0 ? l : -l), p);
+
+ for (i=0; i < n-1; i++) {
+ d = ob->ob_digit[i];
+ for (j=0; j < PyLong_MARSHAL_RATIO; j++) {
+ w_short(d & PyLong_MARSHAL_MASK, p);
+ d >>= PyLong_MARSHAL_SHIFT;
+ }
+ assert (d == 0);
+ }
+ d = ob->ob_digit[n-1];
+ do {
+ w_short(d & PyLong_MARSHAL_MASK, p);
+ d >>= PyLong_MARSHAL_SHIFT;
+ } while (d != 0);
+}
+
+static void
+w_object(PyObject *v, WFILE *p)
+{
+ Py_ssize_t i, n;
+
+ p->depth++;
+
+ if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
+ p->error = WFERR_NESTEDTOODEEP;
+ }
+ else if (v == NULL) {
+ w_byte(TYPE_NULL, p);
+ }
+ else if (v == Py_None) {
+ w_byte(TYPE_NONE, p);
+ }
+ else if (v == PyExc_StopIteration) {
+ w_byte(TYPE_STOPITER, p);
+ }
+ else if (v == Py_Ellipsis) {
+ w_byte(TYPE_ELLIPSIS, p);
+ }
+ else if (v == Py_False) {
+ w_byte(TYPE_FALSE, p);
+ }
+ else if (v == Py_True) {
+ w_byte(TYPE_TRUE, p);
+ }
+ else if (PyInt_CheckExact(v)) {
+ long x = PyInt_AS_LONG((PyIntObject *)v);
+#if SIZEOF_LONG > 4
+ long y = Py_ARITHMETIC_RIGHT_SHIFT(long, x, 31);
+ if (y && y != -1) {
+ w_byte(TYPE_INT64, p);
+ w_long64(x, p);
+ }
+ else
+#endif
+ {
+ w_byte(TYPE_INT, p);
+ w_long(x, p);
+ }
+ }
+ else if (PyLong_CheckExact(v)) {
+ PyLongObject *ob = (PyLongObject *)v;
+ w_PyLong(ob, p);
+ }
+ else if (PyFloat_CheckExact(v)) {
+ if (p->version > 1) {
+ unsigned char buf[8];
+ if (_PyFloat_Pack8(PyFloat_AsDouble(v),
+ buf, 1) < 0) {
+ p->error = WFERR_UNMARSHALLABLE;
+ return;
+ }
+ w_byte(TYPE_BINARY_FLOAT, p);
+ w_string((char*)buf, 8, p);
+ }
+ else {
+ char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v),
+ 'g', 17, 0, NULL);
+ if (!buf) {
+ p->error = WFERR_NOMEMORY;
+ return;
+ }
+ n = strlen(buf);
+ w_byte(TYPE_FLOAT, p);
+ w_byte((int)n, p);
+ w_string(buf, n, p);
+ PyMem_Free(buf);
+ }
+ }
+#ifndef WITHOUT_COMPLEX
+ else if (PyComplex_CheckExact(v)) {
+ if (p->version > 1) {
+ unsigned char buf[8];
+ if (_PyFloat_Pack8(PyComplex_RealAsDouble(v),
+ buf, 1) < 0) {
+ p->error = WFERR_UNMARSHALLABLE;
+ return;
+ }
+ w_byte(TYPE_BINARY_COMPLEX, p);
+ w_string((char*)buf, 8, p);
+ if (_PyFloat_Pack8(PyComplex_ImagAsDouble(v),
+ buf, 1) < 0) {
+ p->error = WFERR_UNMARSHALLABLE;
+ return;
+ }
+ w_string((char*)buf, 8, p);
+ }
+ else {
+ char *buf;
+ w_byte(TYPE_COMPLEX, p);
+ buf = PyOS_double_to_string(PyComplex_RealAsDouble(v),
+ 'g', 17, 0, NULL);
+ if (!buf) {
+ p->error = WFERR_NOMEMORY;
+ return;
+ }
+ n = strlen(buf);
+ w_byte((int)n, p);
+ w_string(buf, n, p);
+ PyMem_Free(buf);
+ buf = PyOS_double_to_string(PyComplex_ImagAsDouble(v),
+ 'g', 17, 0, NULL);
+ if (!buf) {
+ p->error = WFERR_NOMEMORY;
+ return;
+ }
+ n = strlen(buf);
+ w_byte((int)n, p);
+ w_string(buf, n, p);
+ PyMem_Free(buf);
+ }
+ }
+#endif
+ else if (PyString_CheckExact(v)) {
+ if (p->strings && PyString_CHECK_INTERNED(v)) {
+ PyObject *o = PyDict_GetItem(p->strings, v);
+ if (o) {
+ long w = PyInt_AsLong(o);
+ w_byte(TYPE_STRINGREF, p);
+ w_long(w, p);
+ goto exit;
+ }
+ else {
+ int ok;
+ o = PyInt_FromSsize_t(PyDict_Size(p->strings));
+ ok = o &&
+ PyDict_SetItem(p->strings, v, o) >= 0;
+ Py_XDECREF(o);
+ if (!ok) {
+ p->depth--;
+ p->error = WFERR_UNMARSHALLABLE;
+ return;
+ }
+ w_byte(TYPE_INTERNED, p);
+ }
+ }
+ else {
+ w_byte(TYPE_STRING, p);
+ }
+ w_pstring(PyBytes_AS_STRING(v), PyString_GET_SIZE(v), p);
+ }
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_CheckExact(v)) {
+ PyObject *utf8;
+ utf8 = PyUnicode_AsUTF8String(v);
+ if (utf8 == NULL) {
+ p->depth--;
+ p->error = WFERR_UNMARSHALLABLE;
+ return;
+ }
+ w_byte(TYPE_UNICODE, p);
+ w_pstring(PyString_AS_STRING(utf8), PyString_GET_SIZE(utf8), p);
+ Py_DECREF(utf8);
+ }
+#endif
+ else if (PyTuple_CheckExact(v)) {
+ w_byte(TYPE_TUPLE, p);
+ n = PyTuple_Size(v);
+ W_SIZE(n, p);
+ for (i = 0; i < n; i++) {
+ w_object(PyTuple_GET_ITEM(v, i), p);
+ }
+ }
+ else if (PyList_CheckExact(v)) {
+ w_byte(TYPE_LIST, p);
+ n = PyList_GET_SIZE(v);
+ W_SIZE(n, p);
+ for (i = 0; i < n; i++) {
+ w_object(PyList_GET_ITEM(v, i), p);
+ }
+ }
+ else if (PyDict_CheckExact(v)) {
+ Py_ssize_t pos;
+ PyObject *key, *value;
+ w_byte(TYPE_DICT, p);
+ /* This one is NULL object terminated! */
+ pos = 0;
+ while (PyDict_Next(v, &pos, &key, &value)) {
+ w_object(key, p);
+ w_object(value, p);
+ }
+ w_object((PyObject *)NULL, p);
+ }
+ else if (PyAnySet_CheckExact(v)) {
+ PyObject *value, *it;
+
+ if (PyObject_TypeCheck(v, &PySet_Type))
+ w_byte(TYPE_SET, p);
+ else
+ w_byte(TYPE_FROZENSET, p);
+ n = PyObject_Size(v);
+ if (n == -1) {
+ p->depth--;
+ p->error = WFERR_UNMARSHALLABLE;
+ return;
+ }
+ W_SIZE(n, p);
+ it = PyObject_GetIter(v);
+ if (it == NULL) {
+ p->depth--;
+ p->error = WFERR_UNMARSHALLABLE;
+ return;
+ }
+ while ((value = PyIter_Next(it)) != NULL) {
+ w_object(value, p);
+ Py_DECREF(value);
+ }
+ Py_DECREF(it);
+ if (PyErr_Occurred()) {
+ p->depth--;
+ p->error = WFERR_UNMARSHALLABLE;
+ return;
+ }
+ }
+ else if (PyCode_Check(v)) {
+ PyCodeObject *co = (PyCodeObject *)v;
+ w_byte(TYPE_CODE, p);
+ w_long(co->co_argcount, p);
+ w_long(co->co_nlocals, p);
+ w_long(co->co_stacksize, p);
+ w_long(co->co_flags, p);
+ w_object(co->co_code, p);
+ w_object(co->co_consts, p);
+ w_object(co->co_names, p);
+ w_object(co->co_varnames, p);
+ w_object(co->co_freevars, p);
+ w_object(co->co_cellvars, p);
+ w_object(co->co_filename, p);
+ w_object(co->co_name, p);
+ w_long(co->co_firstlineno, p);
+ w_object(co->co_lnotab, p);
+ }
+ else if (PyObject_CheckReadBuffer(v)) {
+ /* Write unknown buffer-style objects as a string */
+ char *s;
+ PyBufferProcs *pb = v->ob_type->tp_as_buffer;
+ w_byte(TYPE_STRING, p);
+ n = (*pb->bf_getreadbuffer)(v, 0, (void **)&s);
+ w_pstring(s, n, p);
+ }
+ else {
+ w_byte(TYPE_UNKNOWN, p);
+ p->error = WFERR_UNMARSHALLABLE;
+ }
+ exit:
+ p->depth--;
+}
+
+/* version currently has no effect for writing longs. */
+void
+PyMarshal_WriteLongToFile(long x, FILE *fp, int version)
+{
+ WFILE wf;
+ wf.fp = fp;
+ wf.error = WFERR_OK;
+ wf.depth = 0;
+ wf.strings = NULL;
+ wf.version = version;
+ w_long(x, &wf);
+}
+
+void
+PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version)
+{
+ WFILE wf;
+ wf.fp = fp;
+ wf.error = WFERR_OK;
+ wf.depth = 0;
+ wf.strings = (version > 0) ? PyDict_New() : NULL;
+ wf.version = version;
+ w_object(x, &wf);
+ Py_XDECREF(wf.strings);
+}
+
+typedef WFILE RFILE; /* Same struct with different invariants */
+
+#define rs_byte(p) (((p)->ptr < (p)->end) ? (unsigned char)*(p)->ptr++ : EOF)
+
+#define r_byte(p) ((p)->fp ? getc((p)->fp) : rs_byte(p))
+
+static Py_ssize_t
+r_string(char *s, Py_ssize_t n, RFILE *p)
+{
+ if (p->fp != NULL)
+ /* The result fits into int because it must be <=n. */
+ return fread(s, 1, n, p->fp);
+ if (p->end - p->ptr < n)
+ n = p->end - p->ptr;
+ memcpy(s, p->ptr, n);
+ p->ptr += n;
+ return n;
+}
+
+static int
+r_short(RFILE *p)
+{
+ register short x;
+ x = r_byte(p);
+ x |= r_byte(p) << 8;
+ /* Sign-extension, in case short greater than 16 bits */
+ x |= -(x & 0x8000);
+ return x;
+}
+
+static long
+r_long(RFILE *p)
+{
+ register long x;
+ register FILE *fp = p->fp;
+ if (fp) {
+ x = getc(fp);
+ x |= (long)getc(fp) << 8;
+ x |= (long)getc(fp) << 16;
+ x |= (long)getc(fp) << 24;
+ }
+ else {
+ x = rs_byte(p);
+ x |= (long)rs_byte(p) << 8;
+ x |= (long)rs_byte(p) << 16;
+ x |= (long)rs_byte(p) << 24;
+ }
+#if SIZEOF_LONG > 4
+ /* Sign extension for 64-bit machines */
+ x |= -(x & 0x80000000L);
+#endif
+ return x;
+}
+
+/* r_long64 deals with the TYPE_INT64 code. On a machine with
+ sizeof(long) > 4, it returns a Python int object, else a Python long
+ object. Note that w_long64 writes out TYPE_INT if 32 bits is enough,
+ so there's no inefficiency here in returning a PyLong on 32-bit boxes
+ for everything written via TYPE_INT64 (i.e., if an int is written via
+ TYPE_INT64, it *needs* more than 32 bits).
+*/
+static PyObject *
+r_long64(RFILE *p)
+{
+ long lo4 = r_long(p);
+ long hi4 = r_long(p);
+#if SIZEOF_LONG > 4
+ long x = (hi4 << 32) | (lo4 & 0xFFFFFFFFL);
+ return PyInt_FromLong(x);
+#else
+ unsigned char buf[8];
+ int one = 1;
+ int is_little_endian = (int)*(char*)&one;
+ if (is_little_endian) {
+ memcpy(buf, &lo4, 4);
+ memcpy(buf+4, &hi4, 4);
+ }
+ else {
+ memcpy(buf, &hi4, 4);
+ memcpy(buf+4, &lo4, 4);
+ }
+ return _PyLong_FromByteArray(buf, 8, is_little_endian, 1);
+#endif
+}
+
+static PyObject *
+r_PyLong(RFILE *p)
+{
+ PyLongObject *ob;
+ long n, size, i;
+ int j, md, shorts_in_top_digit;
+ digit d;
+
+ n = r_long(p);
+ if (n == 0)
+ return (PyObject *)_PyLong_New(0);
+ if (n < -SIZE32_MAX || n > SIZE32_MAX) {
+ PyErr_SetString(PyExc_ValueError,
+ "bad marshal data (long size out of range)");
+ return NULL;
+ }
+
+ size = 1 + (ABS(n) - 1) / PyLong_MARSHAL_RATIO;
+ shorts_in_top_digit = 1 + (ABS(n) - 1) % PyLong_MARSHAL_RATIO;
+ ob = _PyLong_New(size);
+ if (ob == NULL)
+ return NULL;
+ Py_SIZE(ob) = n > 0 ? size : -size;
+
+ for (i = 0; i < size-1; i++) {
+ d = 0;
+ for (j=0; j < PyLong_MARSHAL_RATIO; j++) {
+ md = r_short(p);
+ if (md < 0 || md > PyLong_MARSHAL_BASE)
+ goto bad_digit;
+ d += (digit)md << j*PyLong_MARSHAL_SHIFT;
+ }
+ ob->ob_digit[i] = d;
+ }
+ d = 0;
+ for (j=0; j < shorts_in_top_digit; j++) {
+ md = r_short(p);
+ if (md < 0 || md > PyLong_MARSHAL_BASE)
+ goto bad_digit;
+ /* topmost marshal digit should be nonzero */
+ if (md == 0 && j == shorts_in_top_digit - 1) {
+ Py_DECREF(ob);
+ PyErr_SetString(PyExc_ValueError,
+ "bad marshal data (unnormalized long data)");
+ return NULL;
+ }
+ d += (digit)md << j*PyLong_MARSHAL_SHIFT;
+ }
+ /* top digit should be nonzero, else the resulting PyLong won't be
+ normalized */
+ ob->ob_digit[size-1] = d;
+ return (PyObject *)ob;
+ bad_digit:
+ Py_DECREF(ob);
+ PyErr_SetString(PyExc_ValueError,
+ "bad marshal data (digit out of range in long)");
+ return NULL;
+}
+
+
+static PyObject *
+r_object(RFILE *p)
+{
+ /* NULL is a valid return value, it does not necessarily means that
+ an exception is set. */
+ PyObject *v, *v2;
+ long i, n;
+ int type = r_byte(p);
+ PyObject *retval;
+
+ p->depth++;
+
+ if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
+ p->depth--;
+ PyErr_SetString(PyExc_ValueError, "recursion limit exceeded");
+ return NULL;
+ }
+
+ switch (type) {
+
+ case EOF:
+ PyErr_SetString(PyExc_EOFError,
+ "EOF read where object expected");
+ retval = NULL;
+ break;
+
+ case TYPE_NULL:
+ retval = NULL;
+ break;
+
+ case TYPE_NONE:
+ Py_INCREF(Py_None);
+ retval = Py_None;
+ break;
+
+ case TYPE_STOPITER:
+ Py_INCREF(PyExc_StopIteration);
+ retval = PyExc_StopIteration;
+ break;
+
+ case TYPE_ELLIPSIS:
+ Py_INCREF(Py_Ellipsis);
+ retval = Py_Ellipsis;
+ break;
+
+ case TYPE_FALSE:
+ Py_INCREF(Py_False);
+ retval = Py_False;
+ break;
+
+ case TYPE_TRUE:
+ Py_INCREF(Py_True);
+ retval = Py_True;
+ break;
+
+ case TYPE_INT:
+ retval = PyInt_FromLong(r_long(p));
+ break;
+
+ case TYPE_INT64:
+ retval = r_long64(p);
+ break;
+
+ case TYPE_LONG:
+ retval = r_PyLong(p);
+ break;
+
+ case TYPE_FLOAT:
+ {
+ char buf[256];
+ double dx;
+ n = r_byte(p);
+ if (n == EOF || r_string(buf, n, p) != n) {
+ PyErr_SetString(PyExc_EOFError,
+ "EOF read where object expected");
+ retval = NULL;
+ break;
+ }
+ buf[n] = '\0';
+ dx = PyOS_string_to_double(buf, NULL, NULL);
+ if (dx == -1.0 && PyErr_Occurred()) {
+ retval = NULL;
+ break;
+ }
+ retval = PyFloat_FromDouble(dx);
+ break;
+ }
+
+ case TYPE_BINARY_FLOAT:
+ {
+ unsigned char buf[8];
+ double x;
+ if (r_string((char*)buf, 8, p) != 8) {
+ PyErr_SetString(PyExc_EOFError,
+ "EOF read where object expected");
+ retval = NULL;
+ break;
+ }
+ x = _PyFloat_Unpack8(buf, 1);
+ if (x == -1.0 && PyErr_Occurred()) {
+ retval = NULL;
+ break;
+ }
+ retval = PyFloat_FromDouble(x);
+ break;
+ }
+
+#ifndef WITHOUT_COMPLEX
+ case TYPE_COMPLEX:
+ {
+ char buf[256];
+ Py_complex c;
+ n = r_byte(p);
+ if (n == EOF || r_string(buf, n, p) != n) {
+ PyErr_SetString(PyExc_EOFError,
+ "EOF read where object expected");
+ retval = NULL;
+ break;
+ }
+ buf[n] = '\0';
+ c.real = PyOS_string_to_double(buf, NULL, NULL);
+ if (c.real == -1.0 && PyErr_Occurred()) {
+ retval = NULL;
+ break;
+ }
+ n = r_byte(p);
+ if (n == EOF || r_string(buf, n, p) != n) {
+ PyErr_SetString(PyExc_EOFError,
+ "EOF read where object expected");
+ retval = NULL;
+ break;
+ }
+ buf[n] = '\0';
+ c.imag = PyOS_string_to_double(buf, NULL, NULL);
+ if (c.imag == -1.0 && PyErr_Occurred()) {
+ retval = NULL;
+ break;
+ }
+ retval = PyComplex_FromCComplex(c);
+ break;
+ }
+
+ case TYPE_BINARY_COMPLEX:
+ {
+ unsigned char buf[8];
+ Py_complex c;
+ if (r_string((char*)buf, 8, p) != 8) {
+ PyErr_SetString(PyExc_EOFError,
+ "EOF read where object expected");
+ retval = NULL;
+ break;
+ }
+ c.real = _PyFloat_Unpack8(buf, 1);
+ if (c.real == -1.0 && PyErr_Occurred()) {
+ retval = NULL;
+ break;
+ }
+ if (r_string((char*)buf, 8, p) != 8) {
+ PyErr_SetString(PyExc_EOFError,
+ "EOF read where object expected");
+ retval = NULL;
+ break;
+ }
+ c.imag = _PyFloat_Unpack8(buf, 1);
+ if (c.imag == -1.0 && PyErr_Occurred()) {
+ retval = NULL;
+ break;
+ }
+ retval = PyComplex_FromCComplex(c);
+ break;
+ }
+#endif
+
+ case TYPE_INTERNED:
+ case TYPE_STRING:
+ n = r_long(p);
+ if (n < 0 || n > SIZE32_MAX) {
+ PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)");
+ retval = NULL;
+ break;
+ }
+ v = PyString_FromStringAndSize((char *)NULL, n);
+ if (v == NULL) {
+ retval = NULL;
+ break;
+ }
+ if (r_string(PyString_AS_STRING(v), n, p) != n) {
+ Py_DECREF(v);
+ PyErr_SetString(PyExc_EOFError,
+ "EOF read where object expected");
+ retval = NULL;
+ break;
+ }
+ if (type == TYPE_INTERNED) {
+ PyString_InternInPlace(&v);
+ if (PyList_Append(p->strings, v) < 0) {
+ retval = NULL;
+ break;
+ }
+ }
+ retval = v;
+ break;
+
+ case TYPE_STRINGREF:
+ n = r_long(p);
+ if (n < 0 || n >= PyList_GET_SIZE(p->strings)) {
+ PyErr_SetString(PyExc_ValueError, "bad marshal data (string ref out of range)");
+ retval = NULL;
+ break;
+ }
+ v = PyList_GET_ITEM(p->strings, n);
+ Py_INCREF(v);
+ retval = v;
+ break;
+
+#ifdef Py_USING_UNICODE
+ case TYPE_UNICODE:
+ {
+ char *buffer;
+
+ n = r_long(p);
+ if (n < 0 || n > SIZE32_MAX) {
+ PyErr_SetString(PyExc_ValueError, "bad marshal data (unicode size out of range)");
+ retval = NULL;
+ break;
+ }
+ buffer = PyMem_NEW(char, n);
+ if (buffer == NULL) {
+ retval = PyErr_NoMemory();
+ break;
+ }
+ if (r_string(buffer, n, p) != n) {
+ PyMem_DEL(buffer);
+ PyErr_SetString(PyExc_EOFError,
+ "EOF read where object expected");
+ retval = NULL;
+ break;
+ }
+ v = PyUnicode_DecodeUTF8(buffer, n, NULL);
+ PyMem_DEL(buffer);
+ retval = v;
+ break;
+ }
+#endif
+
+ case TYPE_TUPLE:
+ n = r_long(p);
+ if (n < 0 || n > SIZE32_MAX) {
+ PyErr_SetString(PyExc_ValueError, "bad marshal data (tuple size out of range)");
+ retval = NULL;
+ break;
+ }
+ v = PyTuple_New(n);
+ if (v == NULL) {
+ retval = NULL;
+ break;
+ }
+ for (i = 0; i < n; i++) {
+ v2 = r_object(p);
+ if ( v2 == NULL ) {
+ if (!PyErr_Occurred())
+ PyErr_SetString(PyExc_TypeError,
+ "NULL object in marshal data for tuple");
+ Py_DECREF(v);
+ v = NULL;
+ break;
+ }
+ PyTuple_SET_ITEM(v, i, v2);
+ }
+ retval = v;
+ break;
+
+ case TYPE_LIST:
+ n = r_long(p);
+ if (n < 0 || n > SIZE32_MAX) {
+ PyErr_SetString(PyExc_ValueError, "bad marshal data (list size out of range)");
+ retval = NULL;
+ break;
+ }
+ v = PyList_New(n);
+ if (v == NULL) {
+ retval = NULL;
+ break;
+ }
+ for (i = 0; i < n; i++) {
+ v2 = r_object(p);
+ if ( v2 == NULL ) {
+ if (!PyErr_Occurred())
+ PyErr_SetString(PyExc_TypeError,
+ "NULL object in marshal data for list");
+ Py_DECREF(v);
+ v = NULL;
+ break;
+ }
+ PyList_SET_ITEM(v, i, v2);
+ }
+ retval = v;
+ break;
+
+ case TYPE_DICT:
+ v = PyDict_New();
+ if (v == NULL) {
+ retval = NULL;
+ break;
+ }
+ for (;;) {
+ PyObject *key, *val;
+ key = r_object(p);
+ if (key == NULL)
+ break;
+ val = r_object(p);
+ if (val != NULL)
+ PyDict_SetItem(v, key, val);
+ Py_DECREF(key);
+ Py_XDECREF(val);
+ }
+ if (PyErr_Occurred()) {
+ Py_DECREF(v);
+ v = NULL;
+ }
+ retval = v;
+ break;
+
+ case TYPE_SET:
+ case TYPE_FROZENSET:
+ n = r_long(p);
+ if (n < 0 || n > SIZE32_MAX) {
+ PyErr_SetString(PyExc_ValueError, "bad marshal data (set size out of range)");
+ retval = NULL;
+ break;
+ }
+ v = (type == TYPE_SET) ? PySet_New(NULL) : PyFrozenSet_New(NULL);
+ if (v == NULL) {
+ retval = NULL;
+ break;
+ }
+ for (i = 0; i < n; i++) {
+ v2 = r_object(p);
+ if ( v2 == NULL ) {
+ if (!PyErr_Occurred())
+ PyErr_SetString(PyExc_TypeError,
+ "NULL object in marshal data for set");
+ Py_DECREF(v);
+ v = NULL;
+ break;
+ }
+ if (PySet_Add(v, v2) == -1) {
+ Py_DECREF(v);
+ Py_DECREF(v2);
+ v = NULL;
+ break;
+ }
+ Py_DECREF(v2);
+ }
+ retval = v;
+ break;
+
+ case TYPE_CODE:
+ if (PyEval_GetRestricted()) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "cannot unmarshal code objects in "
+ "restricted execution mode");
+ retval = NULL;
+ break;
+ }
+ else {
+ int argcount;
+ int nlocals;
+ int stacksize;
+ int flags;
+ PyObject *code = NULL;
+ PyObject *consts = NULL;
+ PyObject *names = NULL;
+ PyObject *varnames = NULL;
+ PyObject *freevars = NULL;
+ PyObject *cellvars = NULL;
+ PyObject *filename = NULL;
+ PyObject *name = NULL;
+ int firstlineno;
+ PyObject *lnotab = NULL;
+
+ v = NULL;
+
+ /* XXX ignore long->int overflows for now */
+ argcount = (int)r_long(p);
+ nlocals = (int)r_long(p);
+ stacksize = (int)r_long(p);
+ flags = (int)r_long(p);
+ code = r_object(p);
+ if (code == NULL)
+ goto code_error;
+ consts = r_object(p);
+ if (consts == NULL)
+ goto code_error;
+ names = r_object(p);
+ if (names == NULL)
+ goto code_error;
+ varnames = r_object(p);
+ if (varnames == NULL)
+ goto code_error;
+ freevars = r_object(p);
+ if (freevars == NULL)
+ goto code_error;
+ cellvars = r_object(p);
+ if (cellvars == NULL)
+ goto code_error;
+ filename = r_object(p);
+ if (filename == NULL)
+ goto code_error;
+ name = r_object(p);
+ if (name == NULL)
+ goto code_error;
+ firstlineno = (int)r_long(p);
+ lnotab = r_object(p);
+ if (lnotab == NULL)
+ goto code_error;
+
+ v = (PyObject *) PyCode_New(
+ argcount, nlocals, stacksize, flags,
+ code, consts, names, varnames,
+ freevars, cellvars, filename, name,
+ firstlineno, lnotab);
+
+ code_error:
+ Py_XDECREF(code);
+ Py_XDECREF(consts);
+ Py_XDECREF(names);
+ Py_XDECREF(varnames);
+ Py_XDECREF(freevars);
+ Py_XDECREF(cellvars);
+ Py_XDECREF(filename);
+ Py_XDECREF(name);
+ Py_XDECREF(lnotab);
+
+ }
+ retval = v;
+ break;
+
+ default:
+ /* Bogus data got written, which isn't ideal.
+ This will let you keep working and recover. */
+ PyErr_SetString(PyExc_ValueError, "bad marshal data (unknown type code)");
+ retval = NULL;
+ break;
+
+ }
+ p->depth--;
+ return retval;
+}
+
+static PyObject *
+read_object(RFILE *p)
+{
+ PyObject *v;
+ if (PyErr_Occurred()) {
+ fprintf(stderr, "XXX readobject called with exception set\n");
+ return NULL;
+ }
+ v = r_object(p);
+ if (v == NULL && !PyErr_Occurred())
+ PyErr_SetString(PyExc_TypeError, "NULL object in marshal data for object");
+ return v;
+}
+
+int
+PyMarshal_ReadShortFromFile(FILE *fp)
+{
+ RFILE rf;
+ assert(fp);
+ rf.fp = fp;
+ rf.strings = NULL;
+ rf.end = rf.ptr = NULL;
+ return r_short(&rf);
+}
+
+long
+PyMarshal_ReadLongFromFile(FILE *fp)
+{
+ RFILE rf;
+ rf.fp = fp;
+ rf.strings = NULL;
+ rf.ptr = rf.end = NULL;
+ return r_long(&rf);
+}
+
+#ifdef HAVE_FSTAT
+/* Return size of file in bytes; < 0 if unknown. */
+static off_t
+getfilesize(FILE *fp)
+{
+ struct stat st;
+ if (fstat(fileno(fp), &st) != 0)
+ return -1;
+ else
+ return st.st_size;
+}
+#endif
+
+/* If we can get the size of the file up-front, and it's reasonably small,
+ * read it in one gulp and delegate to ...FromString() instead. Much quicker
+ * than reading a byte at a time from file; speeds .pyc imports.
+ * CAUTION: since this may read the entire remainder of the file, don't
+ * call it unless you know you're done with the file.
+ */
+PyObject *
+PyMarshal_ReadLastObjectFromFile(FILE *fp)
+{
+/* REASONABLE_FILE_LIMIT is by defn something big enough for Tkinter.pyc. */
+#define REASONABLE_FILE_LIMIT (1L << 18)
+#ifdef HAVE_FSTAT
+ off_t filesize;
+ filesize = getfilesize(fp);
+ if (filesize > 0 && filesize <= REASONABLE_FILE_LIMIT) {
+ char* pBuf = (char *)PyMem_MALLOC(filesize);
+ if (pBuf != NULL) {
+ size_t n = fread(pBuf, 1, (size_t)filesize, fp);
+ PyObject* v = PyMarshal_ReadObjectFromString(pBuf, n);
+ PyMem_FREE(pBuf);
+ return v;
+ }
+
+ }
+#endif
+ /* We don't have fstat, or we do but the file is larger than
+ * REASONABLE_FILE_LIMIT or malloc failed -- read a byte at a time.
+ */
+ return PyMarshal_ReadObjectFromFile(fp);
+
+#undef REASONABLE_FILE_LIMIT
+}
+
+PyObject *
+PyMarshal_ReadObjectFromFile(FILE *fp)
+{
+ RFILE rf;
+ PyObject *result;
+ rf.fp = fp;
+ rf.strings = PyList_New(0);
+ rf.depth = 0;
+ rf.ptr = rf.end = NULL;
+ result = r_object(&rf);
+ Py_DECREF(rf.strings);
+ return result;
+}
+
+PyObject *
+PyMarshal_ReadObjectFromString(char *str, Py_ssize_t len)
+{
+ RFILE rf;
+ PyObject *result;
+ rf.fp = NULL;
+ rf.ptr = str;
+ rf.end = str + len;
+ rf.strings = PyList_New(0);
+ rf.depth = 0;
+ result = r_object(&rf);
+ Py_DECREF(rf.strings);
+ return result;
+}
+
+static void
+set_error(int error)
+{
+ switch (error) {
+ case WFERR_NOMEMORY:
+ PyErr_NoMemory();
+ break;
+ case WFERR_UNMARSHALLABLE:
+ PyErr_SetString(PyExc_ValueError, "unmarshallable object");
+ break;
+ case WFERR_NESTEDTOODEEP:
+ default:
+ PyErr_SetString(PyExc_ValueError,
+ "object too deeply nested to marshal");
+ break;
+ }
+}
+
+PyObject *
+PyMarshal_WriteObjectToString(PyObject *x, int version)
+{
+ WFILE wf;
+ wf.fp = NULL;
+ wf.str = PyString_FromStringAndSize((char *)NULL, 50);
+ if (wf.str == NULL)
+ return NULL;
+ wf.ptr = PyString_AS_STRING((PyStringObject *)wf.str);
+ wf.end = wf.ptr + PyString_Size(wf.str);
+ wf.error = WFERR_OK;
+ wf.depth = 0;
+ wf.version = version;
+ wf.strings = (version > 0) ? PyDict_New() : NULL;
+ w_object(x, &wf);
+ Py_XDECREF(wf.strings);
+ if (wf.str != NULL) {
+ char *base = PyString_AS_STRING((PyStringObject *)wf.str);
+ if (wf.ptr - base > PY_SSIZE_T_MAX) {
+ Py_DECREF(wf.str);
+ PyErr_SetString(PyExc_OverflowError,
+ "too much marshall data for a string");
+ return NULL;
+ }
+ if (_PyString_Resize(&wf.str, (Py_ssize_t)(wf.ptr - base)))
+ return NULL;
+ }
+ if (wf.error != WFERR_OK) {
+ Py_XDECREF(wf.str);
+ set_error(wf.error);
+ return NULL;
+ }
+ return wf.str;
+}
+
+/* And an interface for Python programs... */
+
+static PyObject *
+marshal_dump(PyObject *self, PyObject *args)
+{
+ WFILE wf;
+ PyObject *x;
+ PyObject *f;
+ int version = Py_MARSHAL_VERSION;
+ if (!PyArg_ParseTuple(args, "OO|i:dump", &x, &f, &version))
+ return NULL;
+ if (!PyFile_Check(f)) {
+ PyErr_SetString(PyExc_TypeError,
+ "marshal.dump() 2nd arg must be file");
+ return NULL;
+ }
+ wf.fp = PyFile_AsFile(f);
+ wf.str = NULL;
+ wf.ptr = wf.end = NULL;
+ wf.error = WFERR_OK;
+ wf.depth = 0;
+ wf.strings = (version > 0) ? PyDict_New() : 0;
+ wf.version = version;
+ w_object(x, &wf);
+ Py_XDECREF(wf.strings);
+ if (wf.error != WFERR_OK) {
+ set_error(wf.error);
+ return NULL;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+PyDoc_STRVAR(dump_doc,
+"dump(value, file[, version])\n\
+\n\
+Write the value on the open file. The value must be a supported type.\n\
+The file must be an open file object such as sys.stdout or returned by\n\
+open() or os.popen(). It must be opened in binary mode ('wb' or 'w+b').\n\
+\n\
+If the value has (or contains an object that has) an unsupported type, a\n\
+ValueError exception is raised — but garbage data will also be written\n\
+to the file. The object will not be properly read back by load()\n\
+\n\
+New in version 2.4: The version argument indicates the data format that\n\
+dump should use.");
+
+static PyObject *
+marshal_load(PyObject *self, PyObject *f)
+{
+ RFILE rf;
+ PyObject *result;
+ if (!PyFile_Check(f)) {
+ PyErr_SetString(PyExc_TypeError,
+ "marshal.load() arg must be file");
+ return NULL;
+ }
+ rf.fp = PyFile_AsFile(f);
+ rf.strings = PyList_New(0);
+ rf.depth = 0;
+ result = read_object(&rf);
+ Py_DECREF(rf.strings);
+ return result;
+}
+
+PyDoc_STRVAR(load_doc,
+"load(file)\n\
+\n\
+Read one value from the open file and return it. If no valid value is\n\
+read (e.g. because the data has a different Python version’s\n\
+incompatible marshal format), raise EOFError, ValueError or TypeError.\n\
+The file must be an open file object opened in binary mode ('rb' or\n\
+'r+b').\n\
+\n\
+Note: If an object containing an unsupported type was marshalled with\n\
+dump(), load() will substitute None for the unmarshallable type.");
+
+
+static PyObject *
+marshal_dumps(PyObject *self, PyObject *args)
+{
+ PyObject *x;
+ int version = Py_MARSHAL_VERSION;
+ if (!PyArg_ParseTuple(args, "O|i:dumps", &x, &version))
+ return NULL;
+ return PyMarshal_WriteObjectToString(x, version);
+}
+
+PyDoc_STRVAR(dumps_doc,
+"dumps(value[, version])\n\
+\n\
+Return the string that would be written to a file by dump(value, file).\n\
+The value must be a supported type. Raise a ValueError exception if\n\
+value has (or contains an object that has) an unsupported type.\n\
+\n\
+New in version 2.4: The version argument indicates the data format that\n\
+dumps should use.");
+
+
+static PyObject *
+marshal_loads(PyObject *self, PyObject *args)
+{
+ RFILE rf;
+ char *s;
+ Py_ssize_t n;
+ PyObject* result;
+ if (!PyArg_ParseTuple(args, "s#:loads", &s, &n))
+ return NULL;
+ rf.fp = NULL;
+ rf.ptr = s;
+ rf.end = s + n;
+ rf.strings = PyList_New(0);
+ rf.depth = 0;
+ result = read_object(&rf);
+ Py_DECREF(rf.strings);
+ return result;
+}
+
+PyDoc_STRVAR(loads_doc,
+"loads(string)\n\
+\n\
+Convert the string to a value. If no valid value is found, raise\n\
+EOFError, ValueError or TypeError. Extra characters in the string are\n\
+ignored.");
+
+static PyMethodDef marshal_methods[] = {
+ {"dump", marshal_dump, METH_VARARGS, dump_doc},
+ {"load", marshal_load, METH_O, load_doc},
+ {"dumps", marshal_dumps, METH_VARARGS, dumps_doc},
+ {"loads", marshal_loads, METH_VARARGS, loads_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+PyDoc_STRVAR(marshal_doc,
+"This module contains functions that can read and write Python values in\n\
+a binary format. The format is specific to Python, but independent of\n\
+machine architecture issues.\n\
+\n\
+Not all Python object types are supported; in general, only objects\n\
+whose value is independent from a particular invocation of Python can be\n\
+written and read by this module. The following types are supported:\n\
+None, integers, long integers, floating point numbers, strings, Unicode\n\
+objects, tuples, lists, sets, dictionaries, and code objects, where it\n\
+should be understood that tuples, lists and dictionaries are only\n\
+supported as long as the values contained therein are themselves\n\
+supported; and recursive lists and dictionaries should not be written\n\
+(they will cause infinite loops).\n\
+\n\
+Variables:\n\
+\n\
+version -- indicates the format that the module uses. Version 0 is the\n\
+ historical format, version 1 (added in Python 2.4) shares interned\n\
+ strings and version 2 (added in Python 2.5) uses a binary format for\n\
+ floating point numbers. (New in version 2.4)\n\
+\n\
+Functions:\n\
+\n\
+dump() -- write value to a file\n\
+load() -- read value from a file\n\
+dumps() -- write value to a string\n\
+loads() -- read value from a string");
+
+
+PyMODINIT_FUNC
+PyMarshal_Init(void)
+{
+ PyObject *mod = Py_InitModule3("marshal", marshal_methods,
+ marshal_doc);
+ if (mod == NULL)
+ return;
+ PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION);
+}
diff --git a/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Python/random.c b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Python/random.c new file mode 100644 index 0000000000..14d81a91a7 --- /dev/null +++ b/AppPkg/Applications/Python/Python-2.7.10/PyMod-2.7.10/Python/random.c @@ -0,0 +1,420 @@ +#include "Python.h"
+#ifdef MS_WINDOWS
+#include <windows.h>
+#else
+#include <fcntl.h>
+#endif
+
+#ifdef Py_DEBUG
+int _Py_HashSecret_Initialized = 0;
+#else
+static int _Py_HashSecret_Initialized = 0;
+#endif
+
+#ifdef MS_WINDOWS
+typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
+ LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
+ DWORD dwFlags );
+typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
+ BYTE *pbBuffer );
+
+static CRYPTGENRANDOM pCryptGenRandom = NULL;
+/* This handle is never explicitly released. Instead, the operating
+ system will release it when the process terminates. */
+static HCRYPTPROV hCryptProv = 0;
+
+static int
+win32_urandom_init(int raise)
+{
+ HINSTANCE hAdvAPI32 = NULL;
+ CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
+
+ /* Obtain handle to the DLL containing CryptoAPI. This should not fail. */
+ hAdvAPI32 = GetModuleHandle("advapi32.dll");
+ if(hAdvAPI32 == NULL)
+ goto error;
+
+ /* Obtain pointers to the CryptoAPI functions. This will fail on some early
+ versions of Win95. */
+ pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
+ hAdvAPI32, "CryptAcquireContextA");
+ if (pCryptAcquireContext == NULL)
+ goto error;
+
+ pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(hAdvAPI32,
+ "CryptGenRandom");
+ if (pCryptGenRandom == NULL)
+ goto error;
+
+ /* Acquire context */
+ if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
+ PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
+ goto error;
+
+ return 0;
+
+error:
+ if (raise)
+ PyErr_SetFromWindowsErr(0);
+ else
+ Py_FatalError("Failed to initialize Windows random API (CryptoGen)");
+ return -1;
+}
+
+/* Fill buffer with size pseudo-random bytes generated by the Windows CryptoGen
+ API. Return 0 on success, or -1 on error. */
+static int
+win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise)
+{
+ Py_ssize_t chunk;
+
+ if (hCryptProv == 0)
+ {
+ if (win32_urandom_init(raise) == -1)
+ return -1;
+ }
+
+ while (size > 0)
+ {
+ chunk = size > INT_MAX ? INT_MAX : size;
+ if (!pCryptGenRandom(hCryptProv, chunk, buffer))
+ {
+ /* CryptGenRandom() failed */
+ if (raise)
+ PyErr_SetFromWindowsErr(0);
+ else
+ Py_FatalError("Failed to initialized the randomized hash "
+ "secret using CryptoGen)");
+ return -1;
+ }
+ buffer += chunk;
+ size -= chunk;
+ }
+ return 0;
+}
+
+#elif HAVE_GETENTROPY
+/* Fill buffer with size pseudo-random bytes generated by getentropy().
+ Return 0 on success, or raise an exception and return -1 on error.
+ If fatal is nonzero, call Py_FatalError() instead of raising an exception
+ on error. */
+static int
+py_getentropy(unsigned char *buffer, Py_ssize_t size, int fatal)
+{
+ while (size > 0) {
+ Py_ssize_t len = size < 256 ? size : 256;
+ int res;
+
+ if (!fatal) {
+ Py_BEGIN_ALLOW_THREADS
+ res = getentropy(buffer, len);
+ Py_END_ALLOW_THREADS
+
+ if (res < 0) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ return -1;
+ }
+ }
+ else {
+ res = getentropy(buffer, len);
+ if (res < 0)
+ Py_FatalError("getentropy() failed");
+ }
+
+ buffer += len;
+ size -= len;
+ }
+ return 0;
+}
+#endif
+
+#ifdef __VMS
+/* Use openssl random routine */
+#include <openssl/rand.h>
+static int
+vms_urandom(unsigned char *buffer, Py_ssize_t size, int raise)
+{
+ if (RAND_pseudo_bytes(buffer, size) < 0) {
+ if (raise) {
+ PyErr_Format(PyExc_ValueError,
+ "RAND_pseudo_bytes");
+ } else {
+ Py_FatalError("Failed to initialize the randomized hash "
+ "secret using RAND_pseudo_bytes");
+ }
+ return -1;
+ }
+ return 0;
+}
+#endif /* __VMS */
+
+
+#if !defined(MS_WINDOWS) && !defined(__VMS)
+
+static struct {
+ int fd;
+ dev_t st_dev;
+ ino_t st_ino;
+} urandom_cache = { -1 };
+
+/* Read size bytes from /dev/urandom into buffer.
+ Call Py_FatalError() on error. */
+static void
+dev_urandom_noraise(unsigned char *buffer, Py_ssize_t size)
+{
+ int fd;
+ Py_ssize_t n;
+
+ assert (0 < size);
+
+ fd = open("/dev/urandom", O_RDONLY);
+ if (fd < 0)
+ Py_FatalError("Failed to open /dev/urandom");
+
+ while (0 < size)
+ {
+ do {
+ n = read(fd, buffer, (size_t)size);
+ } while (n < 0 && errno == EINTR);
+ if (n <= 0)
+ {
+ /* stop on error or if read(size) returned 0 */
+ Py_FatalError("Failed to read bytes from /dev/urandom");
+ break;
+ }
+ buffer += n;
+ size -= (Py_ssize_t)n;
+ }
+ close(fd);
+}
+
+/* Read size bytes from /dev/urandom into buffer.
+ Return 0 on success, raise an exception and return -1 on error. */
+static int
+dev_urandom_python(char *buffer, Py_ssize_t size)
+{
+ int fd;
+ Py_ssize_t n;
+ struct stat st;
+ int attr;
+
+ if (size <= 0)
+ return 0;
+
+ if (urandom_cache.fd >= 0) {
+ /* Does the fd point to the same thing as before? (issue #21207) */
+ if (fstat(urandom_cache.fd, &st)
+ || st.st_dev != urandom_cache.st_dev
+ || st.st_ino != urandom_cache.st_ino) {
+ /* Something changed: forget the cached fd (but don't close it,
+ since it probably points to something important for some
+ third-party code). */
+ urandom_cache.fd = -1;
+ }
+ }
+ if (urandom_cache.fd >= 0)
+ fd = urandom_cache.fd;
+ else {
+ Py_BEGIN_ALLOW_THREADS
+ fd = open("/dev/urandom", O_RDONLY);
+ Py_END_ALLOW_THREADS
+ if (fd < 0)
+ {
+ if (errno == ENOENT || errno == ENXIO ||
+ errno == ENODEV || errno == EACCES)
+ PyErr_SetString(PyExc_NotImplementedError,
+ "/dev/urandom (or equivalent) not found");
+ else
+ PyErr_SetFromErrno(PyExc_OSError);
+ return -1;
+ }
+
+ /* try to make the file descriptor non-inheritable, ignore errors */
+ attr = fcntl(fd, F_GETFD);
+ if (attr >= 0) {
+ attr |= FD_CLOEXEC;
+ (void)fcntl(fd, F_SETFD, attr);
+ }
+
+ if (urandom_cache.fd >= 0) {
+ /* urandom_fd was initialized by another thread while we were
+ not holding the GIL, keep it. */
+ close(fd);
+ fd = urandom_cache.fd;
+ }
+ else {
+ if (fstat(fd, &st)) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ close(fd);
+ return -1;
+ }
+ else {
+ urandom_cache.fd = fd;
+ urandom_cache.st_dev = st.st_dev;
+ urandom_cache.st_ino = st.st_ino;
+ }
+ }
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ do {
+ do {
+ n = read(fd, buffer, (size_t)size);
+ } while (n < 0 && errno == EINTR);
+ if (n <= 0)
+ break;
+ buffer += n;
+ size -= (Py_ssize_t)n;
+ } while (0 < size);
+ Py_END_ALLOW_THREADS
+
+ if (n <= 0)
+ {
+ /* stop on error or if read(size) returned 0 */
+ if (n < 0)
+ PyErr_SetFromErrno(PyExc_OSError);
+ else
+ PyErr_Format(PyExc_RuntimeError,
+ "Failed to read %zi bytes from /dev/urandom",
+ size);
+ return -1;
+ }
+ return 0;
+}
+
+static void
+dev_urandom_close(void)
+{
+ if (urandom_cache.fd >= 0) {
+ close(urandom_cache.fd);
+ urandom_cache.fd = -1;
+ }
+}
+
+
+#endif /* !defined(MS_WINDOWS) && !defined(__VMS) */
+
+/* Fill buffer with pseudo-random bytes generated by a linear congruent
+ generator (LCG):
+
+ x(n+1) = (x(n) * 214013 + 2531011) % 2^32
+
+ Use bits 23..16 of x(n) to generate a byte. */
+static void
+lcg_urandom(unsigned int x0, unsigned char *buffer, size_t size)
+{
+ size_t index;
+ unsigned int x;
+
+ x = x0;
+ for (index=0; index < size; index++) {
+ x *= 214013;
+ x += 2531011;
+ /* modulo 2 ^ (8 * sizeof(int)) */
+ buffer[index] = (x >> 16) & 0xff;
+ }
+}
+
+/* Fill buffer with size pseudo-random bytes from the operating system random
+ number generator (RNG). It is suitable for most cryptographic purposes
+ except long living private keys for asymmetric encryption.
+
+ Return 0 on success, raise an exception and return -1 on error. */
+int
+_PyOS_URandom(void *buffer, Py_ssize_t size)
+{
+ if (size < 0) {
+ PyErr_Format(PyExc_ValueError,
+ "negative argument not allowed");
+ return -1;
+ }
+ if (size == 0)
+ return 0;
+
+#ifdef MS_WINDOWS
+ return win32_urandom((unsigned char *)buffer, size, 1);
+#elif HAVE_GETENTROPY
+ return py_getentropy(buffer, size, 0);
+#else
+# ifdef __VMS
+ return vms_urandom((unsigned char *)buffer, size, 1);
+# else
+ return dev_urandom_python((char*)buffer, size);
+# endif
+#endif
+}
+
+void
+_PyRandom_Init(void)
+{
+ char *env;
+ void *secret = &_Py_HashSecret;
+ Py_ssize_t secret_size = sizeof(_Py_HashSecret_t);
+
+ if (_Py_HashSecret_Initialized)
+ return;
+ _Py_HashSecret_Initialized = 1;
+
+ /*
+ By default, hash randomization is disabled, and only
+ enabled if PYTHONHASHSEED is set to non-empty or if
+ "-R" is provided at the command line:
+ */
+ if (!Py_HashRandomizationFlag) {
+ /* Disable the randomized hash: */
+ memset(secret, 0, secret_size);
+ return;
+ }
+
+ /*
+ Hash randomization is enabled. Generate a per-process secret,
+ using PYTHONHASHSEED if provided.
+ */
+
+ env = Py_GETENV("PYTHONHASHSEED");
+ if (env && *env != '\0' && strcmp(env, "random") != 0) {
+ char *endptr = env;
+ unsigned long seed;
+ seed = strtoul(env, &endptr, 10);
+ if (*endptr != '\0'
+ || seed > 4294967295UL
+ || (errno == ERANGE && seed == ULONG_MAX))
+ {
+ Py_FatalError("PYTHONHASHSEED must be \"random\" or an integer "
+ "in range [0; 4294967295]");
+ }
+ if (seed == 0) {
+ /* disable the randomized hash */
+ memset(secret, 0, secret_size);
+ }
+ else {
+ lcg_urandom(seed, (unsigned char*)secret, secret_size);
+ }
+ }
+ else {
+#ifdef MS_WINDOWS
+ (void)win32_urandom((unsigned char *)secret, secret_size, 0);
+#elif __VMS
+ vms_urandom((unsigned char *)secret, secret_size, 0);
+#elif HAVE_GETENTROPY
+ (void)py_getentropy(secret, secret_size, 1);
+#else
+ dev_urandom_noraise(secret, secret_size);
+#endif
+ }
+}
+
+void
+_PyRandom_Fini(void)
+{
+#ifdef MS_WINDOWS
+ if (hCryptProv) {
+ CryptReleaseContext(hCryptProv, 0);
+ hCryptProv = 0;
+ }
+#elif HAVE_GETENTROPY
+ /* nothing to clean */
+#else
+ dev_urandom_close();
+#endif
+}
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Python2710.inf b/AppPkg/Applications/Python/Python-2.7.10/Python2710.inf new file mode 100644 index 0000000000..94c735d013 --- /dev/null +++ b/AppPkg/Applications/Python/Python-2.7.10/Python2710.inf @@ -0,0 +1,255 @@ +## @file
+# PythonCore.inf
+#
+# Copyright (c) 2015, Daryl McDaniel. All rights reserved.<BR>
+# Copyright (c) 2011-2012, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010016
+ BASE_NAME = Python
+ FILE_GUID = ca5627c4-51ba-4dcb-ac62-c076ebd37ddb
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 0.8
+ ENTRY_POINT = ShellCEntryLib
+
+ DEFINE PYTHON_VERSION = 2.7.2
+
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF
+#
+
+[Packages]
+ StdLib/StdLib.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ UefiLib
+ DebugLib
+ LibC
+ LibString
+ LibStdio
+ LibGdtoa
+ LibMath
+ LibWchar
+ LibGen
+ LibNetUtil
+ DevMedia
+ #
+ # Comment out the following two library classes if socket support is
+ # NOT being built in to Python.
+ #BsdSocketLib
+ #EfiSocketLib
+
+[FixedPcd]
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0F
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000040
+
+[Sources]
+#EFI -- EFI specific code
+ Efi/config.c
+ Efi/edk2module.c
+ Efi/getpath.c
+
+#Parser
+ Python-$(PYTHON_VERSION)/Parser/acceler.c
+ Python-$(PYTHON_VERSION)/Parser/bitset.c
+ Python-$(PYTHON_VERSION)/Parser/firstsets.c
+ Python-$(PYTHON_VERSION)/Parser/grammar.c
+ Python-$(PYTHON_VERSION)/Parser/grammar1.c
+ Python-$(PYTHON_VERSION)/Parser/listnode.c
+ Python-$(PYTHON_VERSION)/Parser/metagrammar.c
+ Python-$(PYTHON_VERSION)/Parser/myreadline.c
+ Python-$(PYTHON_VERSION)/Parser/node.c
+ Python-$(PYTHON_VERSION)/Parser/parser.c
+ Python-$(PYTHON_VERSION)/Parser/parsetok.c
+ Python-$(PYTHON_VERSION)/Parser/tokenizer.c
+
+#Python
+ PyMod-$(PYTHON_VERSION)/Python/getcopyright.c
+ PyMod-$(PYTHON_VERSION)/Python/marshal.c
+ PyMod-$(PYTHON_VERSION)/Python/import.c
+
+ Python-$(PYTHON_VERSION)/Python/_warnings.c
+ Python-$(PYTHON_VERSION)/Python/Python-ast.c
+ Python-$(PYTHON_VERSION)/Python/asdl.c
+ Python-$(PYTHON_VERSION)/Python/ast.c
+ Python-$(PYTHON_VERSION)/Python/bltinmodule.c
+ Python-$(PYTHON_VERSION)/Python/ceval.c
+ Python-$(PYTHON_VERSION)/Python/codecs.c
+ Python-$(PYTHON_VERSION)/Python/compile.c
+ Python-$(PYTHON_VERSION)/Python/dtoa.c
+ Python-$(PYTHON_VERSION)/Python/dynload_stub.c
+ Python-$(PYTHON_VERSION)/Python/errors.c
+ Python-$(PYTHON_VERSION)/Python/formatter_string.c
+ Python-$(PYTHON_VERSION)/Python/formatter_unicode.c
+ Python-$(PYTHON_VERSION)/Python/frozen.c
+ Python-$(PYTHON_VERSION)/Python/future.c
+ Python-$(PYTHON_VERSION)/Python/getargs.c
+ Python-$(PYTHON_VERSION)/Python/getcompiler.c
+ Python-$(PYTHON_VERSION)/Python/getopt.c
+ Python-$(PYTHON_VERSION)/Python/getplatform.c
+ Python-$(PYTHON_VERSION)/Python/getversion.c
+ Python-$(PYTHON_VERSION)/Python/graminit.c
+ Python-$(PYTHON_VERSION)/Python/importdl.c
+ Python-$(PYTHON_VERSION)/Python/modsupport.c
+ Python-$(PYTHON_VERSION)/Python/mysnprintf.c
+ Python-$(PYTHON_VERSION)/Python/mystrtoul.c
+ Python-$(PYTHON_VERSION)/Python/peephole.c
+ Python-$(PYTHON_VERSION)/Python/pyarena.c
+ Python-$(PYTHON_VERSION)/Python/pyctype.c
+ Python-$(PYTHON_VERSION)/Python/pyfpe.c
+ Python-$(PYTHON_VERSION)/Python/pymath.c
+ Python-$(PYTHON_VERSION)/Python/pystate.c
+ Python-$(PYTHON_VERSION)/Python/pystrcmp.c
+ Python-$(PYTHON_VERSION)/Python/pystrtod.c
+ Python-$(PYTHON_VERSION)/Python/pythonrun.c
+ Python-$(PYTHON_VERSION)/Python/structmember.c
+ Python-$(PYTHON_VERSION)/Python/symtable.c
+ Python-$(PYTHON_VERSION)/Python/sysmodule.c
+ Python-$(PYTHON_VERSION)/Python/traceback.c
+
+#Objects
+ PyMod-$(PYTHON_VERSION)/Objects/longobject.c
+
+ Python-$(PYTHON_VERSION)/Objects/abstract.c
+ Python-$(PYTHON_VERSION)/Objects/boolobject.c
+ Python-$(PYTHON_VERSION)/Objects/bufferobject.c
+ Python-$(PYTHON_VERSION)/Objects/bytearrayobject.c
+ Python-$(PYTHON_VERSION)/Objects/bytes_methods.c
+ Python-$(PYTHON_VERSION)/Objects/capsule.c
+ Python-$(PYTHON_VERSION)/Objects/cellobject.c
+ Python-$(PYTHON_VERSION)/Objects/classobject.c
+ Python-$(PYTHON_VERSION)/Objects/cobject.c
+ Python-$(PYTHON_VERSION)/Objects/codeobject.c
+ Python-$(PYTHON_VERSION)/Objects/complexobject.c
+ Python-$(PYTHON_VERSION)/Objects/descrobject.c
+ Python-$(PYTHON_VERSION)/Objects/dictobject.c
+ Python-$(PYTHON_VERSION)/Objects/enumobject.c
+ Python-$(PYTHON_VERSION)/Objects/exceptions.c
+ Python-$(PYTHON_VERSION)/Objects/fileobject.c
+ Python-$(PYTHON_VERSION)/Objects/floatobject.c
+ Python-$(PYTHON_VERSION)/Objects/frameobject.c
+ Python-$(PYTHON_VERSION)/Objects/funcobject.c
+ Python-$(PYTHON_VERSION)/Objects/genobject.c
+ Python-$(PYTHON_VERSION)/Objects/intobject.c
+ Python-$(PYTHON_VERSION)/Objects/iterobject.c
+ Python-$(PYTHON_VERSION)/Objects/listobject.c
+ Python-$(PYTHON_VERSION)/Objects/memoryobject.c
+ Python-$(PYTHON_VERSION)/Objects/methodobject.c
+ Python-$(PYTHON_VERSION)/Objects/moduleobject.c
+ Python-$(PYTHON_VERSION)/Objects/object.c
+ Python-$(PYTHON_VERSION)/Objects/obmalloc.c
+ Python-$(PYTHON_VERSION)/Objects/rangeobject.c
+ Python-$(PYTHON_VERSION)/Objects/setobject.c
+ Python-$(PYTHON_VERSION)/Objects/sliceobject.c
+ Python-$(PYTHON_VERSION)/Objects/stringobject.c
+ Python-$(PYTHON_VERSION)/Objects/structseq.c
+ Python-$(PYTHON_VERSION)/Objects/tupleobject.c
+ Python-$(PYTHON_VERSION)/Objects/typeobject.c
+ Python-$(PYTHON_VERSION)/Objects/unicodectype.c
+ Python-$(PYTHON_VERSION)/Objects/unicodeobject.c
+ Python-$(PYTHON_VERSION)/Objects/weakrefobject.c
+
+#Modules -- See Efi/config.c
+ # Mandatory Modules -- These must always be built in.
+ PyMod-$(PYTHON_VERSION)/Modules/errnomodule.c
+ Python-$(PYTHON_VERSION)/Modules/_functoolsmodule.c
+ Python-$(PYTHON_VERSION)/Modules/gcmodule.c
+ Python-$(PYTHON_VERSION)/Modules/getbuildinfo.c
+ PyMod-$(PYTHON_VERSION)/Modules/main.c
+ Python-$(PYTHON_VERSION)/Modules/python.c
+
+ # Optional Modules -- See Python/Efi/config.c
+ PyMod-$(PYTHON_VERSION)/Modules/_sre.c #
+ PyMod-$(PYTHON_VERSION)/Modules/selectmodule.c #
+ #
+ Python-$(PYTHON_VERSION)/Modules/_bisectmodule.c #
+ Python-$(PYTHON_VERSION)/Modules/_codecsmodule.c #
+ Python-$(PYTHON_VERSION)/Modules/_collectionsmodule.c #
+ Python-$(PYTHON_VERSION)/Modules/_csv.c #
+ Python-$(PYTHON_VERSION)/Modules/_heapqmodule.c #
+ Python-$(PYTHON_VERSION)/Modules/_json.c #
+ Python-$(PYTHON_VERSION)/Modules/_localemodule.c #
+ Python-$(PYTHON_VERSION)/Modules/_math.c #
+ Python-$(PYTHON_VERSION)/Modules/_randommodule.c #
+ Python-$(PYTHON_VERSION)/Modules/_struct.c #
+ Python-$(PYTHON_VERSION)/Modules/_weakref.c #
+ Python-$(PYTHON_VERSION)/Modules/arraymodule.c #
+ Python-$(PYTHON_VERSION)/Modules/binascii.c #
+ Python-$(PYTHON_VERSION)/Modules/cmathmodule.c #
+ Python-$(PYTHON_VERSION)/Modules/cPickle.c #
+ Python-$(PYTHON_VERSION)/Modules/cStringIO.c #
+ Python-$(PYTHON_VERSION)/Modules/datetimemodule.c #
+ Python-$(PYTHON_VERSION)/Modules/future_builtins.c #
+ Python-$(PYTHON_VERSION)/Modules/itertoolsmodule.c #
+ Python-$(PYTHON_VERSION)/Modules/mathmodule.c #
+ Python-$(PYTHON_VERSION)/Modules/md5.c #
+ Python-$(PYTHON_VERSION)/Modules/md5module.c #
+ Python-$(PYTHON_VERSION)/Modules/operator.c #
+ Python-$(PYTHON_VERSION)/Modules/parsermodule.c #
+ Python-$(PYTHON_VERSION)/Modules/sha256module.c #
+ Python-$(PYTHON_VERSION)/Modules/sha512module.c #
+ Python-$(PYTHON_VERSION)/Modules/shamodule.c #
+ Python-$(PYTHON_VERSION)/Modules/signalmodule.c #
+ Python-$(PYTHON_VERSION)/Modules/socketmodule.c #
+ Python-$(PYTHON_VERSION)/Modules/stropmodule.c #
+ Python-$(PYTHON_VERSION)/Modules/symtablemodule.c #
+ Python-$(PYTHON_VERSION)/Modules/timemodule.c #
+ Python-$(PYTHON_VERSION)/Modules/unicodedata.c #
+ Python-$(PYTHON_VERSION)/Modules/xxsubtype.c #
+ Python-$(PYTHON_VERSION)/Modules/zipimport.c #
+ Python-$(PYTHON_VERSION)/Modules/zlibmodule.c #
+
+#Modules/_io
+ Python-$(PYTHON_VERSION)/Modules/_io/_iomodule.c #
+ Python-$(PYTHON_VERSION)/Modules/_io/bufferedio.c #
+ Python-$(PYTHON_VERSION)/Modules/_io/bytesio.c #
+ Python-$(PYTHON_VERSION)/Modules/_io/fileio.c #
+ Python-$(PYTHON_VERSION)/Modules/_io/iobase.c #
+ Python-$(PYTHON_VERSION)/Modules/_io/stringio.c #
+ Python-$(PYTHON_VERSION)/Modules/_io/textio.c #
+
+#Modules/cjkcodecs
+ Python-$(PYTHON_VERSION)/Modules/cjkcodecs/multibytecodec.c #
+ Python-$(PYTHON_VERSION)/Modules/cjkcodecs/_codecs_cn.c #
+ Python-$(PYTHON_VERSION)/Modules/cjkcodecs/_codecs_hk.c #
+ Python-$(PYTHON_VERSION)/Modules/cjkcodecs/_codecs_iso2022.c #
+ Python-$(PYTHON_VERSION)/Modules/cjkcodecs/_codecs_jp.c #
+ Python-$(PYTHON_VERSION)/Modules/cjkcodecs/_codecs_kr.c #
+ Python-$(PYTHON_VERSION)/Modules/cjkcodecs/_codecs_tw.c #
+
+#Modules/expat
+ Python-$(PYTHON_VERSION)/Modules/pyexpat.c #
+ PyMod-$(PYTHON_VERSION)/Modules/expat/xmlparse.c #
+ Python-$(PYTHON_VERSION)/Modules/expat/xmlrole.c #
+ Python-$(PYTHON_VERSION)/Modules/expat/xmltok.c #
+
+#Modules/zlib
+ Python-$(PYTHON_VERSION)/Modules/zlib/adler32.c #
+ Python-$(PYTHON_VERSION)/Modules/zlib/compress.c #
+ Python-$(PYTHON_VERSION)/Modules/zlib/crc32.c #
+ Python-$(PYTHON_VERSION)/Modules/zlib/deflate.c #
+ Python-$(PYTHON_VERSION)/Modules/zlib/gzio.c #
+ Python-$(PYTHON_VERSION)/Modules/zlib/infback.c #
+ Python-$(PYTHON_VERSION)/Modules/zlib/inffast.c #
+ Python-$(PYTHON_VERSION)/Modules/zlib/inflate.c #
+ Python-$(PYTHON_VERSION)/Modules/zlib/inftrees.c #
+ Python-$(PYTHON_VERSION)/Modules/zlib/trees.c #
+ Python-$(PYTHON_VERSION)/Modules/zlib/uncompr.c #
+ Python-$(PYTHON_VERSION)/Modules/zlib/zutil.c #
+
+[BuildOptions]
+ MSFT:*_*_IA32_CC_FLAGS = /Oi- /wd4018 /wd4054 /wd4055 /wd4101 /wd4131 /wd4152 /wd4204 /wd4210 /wd4244 /wd4267 /wd4305 /wd4310 /wd4389 /wd4701 /wd4702 /wd4706 /I$(WORKSPACE)\AppPkg\Applications\Python\Ia32 /I$(WORKSPACE)\AppPkg\Applications\Python\Efi /I$(WORKSPACE)\AppPkg\Applications\Python\Python-$(PYTHON_VERSION)\Include /DHAVE_MEMMOVE /DUSE_PYEXPAT_CAPI /DXML_STATIC
+ MSFT:*_*_X64_CC_FLAGS = /Oi- /wd4018 /wd4054 /wd4055 /wd4101 /wd4131 /wd4152 /wd4204 /wd4210 /wd4244 /wd4267 /wd4305 /wd4310 /wd4389 /wd4701 /wd4702 /wd4706 /I$(WORKSPACE)\AppPkg\Applications\Python\X64 /I$(WORKSPACE)\AppPkg\Applications\Python\Efi /I$(WORKSPACE)\AppPkg\Applications\Python\Python-$(PYTHON_VERSION)\Include /DHAVE_MEMMOVE /DUSE_PYEXPAT_CAPI /DXML_STATIC
+ GCC:*_*_IA32_CC_FLAGS = -fno-builtin -Wno-format -I$(WORKSPACE)/AppPkg/Applications/Python/Ia32 -I$(WORKSPACE)/AppPkg/Applications/Python/Python-$(PYTHON_VERSION)/Include -DHAVE_MEMMOVE -DUSE_PYEXPAT_CAPI -DXML_STATIC
+ GCC:*_*_X64_CC_FLAGS = -Wno-format -I$(WORKSPACE)/AppPkg/Applications/Python/X64 -I$(WORKSPACE)/AppPkg/Applications/Python/Python-$(PYTHON_VERSION)/Include -DHAVE_MEMMOVE -DUSE_PYEXPAT_CAPI -DXML_STATIC
+ GCC:*_*_IPF_SYMRENAME_FLAGS = --redefine-syms=$(WORKSPACE)/StdLib/GccSymRename.txt
diff --git a/AppPkg/Applications/Python/Python-2.7.10/X64/pyconfig.h b/AppPkg/Applications/Python/Python-2.7.10/X64/pyconfig.h new file mode 100644 index 0000000000..d0b6df9bdc --- /dev/null +++ b/AppPkg/Applications/Python/Python-2.7.10/X64/pyconfig.h @@ -0,0 +1,1266 @@ +/** @file
+ Manually generated Python Configuration file for EDK II.
+
+ Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#ifndef Py_PYCONFIG_H
+#define Py_PYCONFIG_H
+
+#include <Uefi.h>
+
+#define PLATFORM "uefi"
+
+/* Define if building universal (internal helper macro) */
+#undef AC_APPLE_UNIVERSAL_BUILD
+
+/* Define for AIX if your compiler is a genuine IBM xlC/xlC_r and you want
+ support for AIX C++ shared extension modules. */
+#undef AIX_GENUINE_CPLUSPLUS
+
+/* Define this if you have AtheOS threads. */
+#undef ATHEOS_THREADS
+
+/* Define this if you have BeOS threads. */
+#undef BEOS_THREADS
+
+/* Define if you have the Mach cthreads package */
+#undef C_THREADS
+
+/* Define if C doubles are 64-bit IEEE 754 binary format, stored in ARM
+ mixed-endian order (byte order 45670123) */
+#undef DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754
+
+/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the most
+ significant byte first */
+#undef DOUBLE_IS_BIG_ENDIAN_IEEE754
+
+/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the
+ least significant byte first */
+#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754
+
+/* Define if --enable-ipv6 is specified */
+#undef ENABLE_IPV6
+
+/* Define if flock needs to be linked with bsd library. */
+#undef FLOCK_NEEDS_LIBBSD
+
+/* Define if getpgrp() must be called as getpgrp(0). */
+#undef GETPGRP_HAVE_ARG
+
+/* Define if gettimeofday() does not have second (timezone) argument This is
+ the case on Motorola V4 (R40V4.2) */
+#undef GETTIMEOFDAY_NO_TZ
+
+/* Define to 1 if you have the 'acosh' function. */
+#undef HAVE_ACOSH
+
+/* struct addrinfo (netdb.h) */
+#undef HAVE_ADDRINFO
+
+/* Define to 1 if you have the 'alarm' function. */
+#undef HAVE_ALARM
+
+/* Define this if your time.h defines altzone. */
+#undef HAVE_ALTZONE
+
+/* Define to 1 if you have the 'asinh' function. */
+#undef HAVE_ASINH
+
+/* Define to 1 if you have the <asm/types.h> header file. */
+#undef HAVE_ASM_TYPES_H
+
+/* Define to 1 if you have the 'atanh' function. */
+#undef HAVE_ATANH
+
+/* Define if GCC supports __attribute__((format(PyArg_ParseTuple, 2, 3))) */
+#undef HAVE_ATTRIBUTE_FORMAT_PARSETUPLE
+
+/* Define to 1 if you have the 'bind_textdomain_codeset' function. */
+#undef HAVE_BIND_TEXTDOMAIN_CODESET
+
+/* Define to 1 if you have the <bluetooth/bluetooth.h> header file. */
+#undef HAVE_BLUETOOTH_BLUETOOTH_H
+
+/* Define to 1 if you have the <bluetooth.h> header file. */
+#undef HAVE_BLUETOOTH_H
+
+/* Define if nice() returns success/failure instead of the new priority. */
+#undef HAVE_BROKEN_NICE
+
+/* Define if the system reports an invalid PIPE_BUF value. */
+#undef HAVE_BROKEN_PIPE_BUF
+
+/* Define if poll() sets errno on invalid file descriptors. */
+#undef HAVE_BROKEN_POLL
+
+/* Define if the Posix semaphores do not work on your system */
+#define HAVE_BROKEN_POSIX_SEMAPHORES 1
+
+/* Define if pthread_sigmask() does not work on your system. */
+#define HAVE_BROKEN_PTHREAD_SIGMASK 1
+
+/* define to 1 if your sem_getvalue is broken. */
+#define HAVE_BROKEN_SEM_GETVALUE 1
+
+/* Define this if you have the type _Bool. */
+#define HAVE_C99_BOOL 1
+
+/* Define to 1 if you have the 'chflags' function. */
+#undef HAVE_CHFLAGS
+
+/* Define to 1 if you have the 'chown' function. */
+#undef HAVE_CHOWN
+
+/* Define if you have the 'chroot' function. */
+#undef HAVE_CHROOT
+
+/* Define to 1 if you have the 'clock' function. */
+#define HAVE_CLOCK 1
+
+/* Define to 1 if you have the 'confstr' function. */
+#undef HAVE_CONFSTR
+
+/* Define to 1 if you have the <conio.h> header file. */
+#undef HAVE_CONIO_H
+
+/* Define to 1 if you have the 'copysign' function. */
+#undef HAVE_COPYSIGN
+
+/* Define to 1 if you have the 'ctermid' function. */
+#undef HAVE_CTERMID
+
+/* Define if you have the 'ctermid_r' function. */
+#undef HAVE_CTERMID_R
+
+/* Define to 1 if you have the <curses.h> header file. */
+#undef HAVE_CURSES_H
+
+/* Define if you have the 'is_term_resized' function. */
+#undef HAVE_CURSES_IS_TERM_RESIZED
+
+/* Define if you have the 'resizeterm' function. */
+#undef HAVE_CURSES_RESIZETERM
+
+/* Define if you have the 'resize_term' function. */
+#undef HAVE_CURSES_RESIZE_TERM
+
+/* Define to 1 if you have the declaration of 'isfinite', and to 0 if you
+ don't. */
+#define HAVE_DECL_ISFINITE 0
+
+/* Define to 1 if you have the declaration of 'isinf', and to 0 if you don't.
+ */
+#define HAVE_DECL_ISINF 1
+
+/* Define to 1 if you have the declaration of 'isnan', and to 0 if you don't.
+ */
+#define HAVE_DECL_ISNAN 1
+
+/* Define to 1 if you have the declaration of 'tzname', and to 0 if you don't.
+ */
+#define HAVE_DECL_TZNAME 0
+
+/* Define to 1 if you have the device macros. */
+#undef HAVE_DEVICE_MACROS
+
+/* Define if we have /dev/ptc. */
+#undef HAVE_DEV_PTC
+
+/* Define if we have /dev/ptmx. */
+#undef HAVE_DEV_PTMX
+
+/* Define to 1 if you have the <direct.h> header file. */
+#undef HAVE_DIRECT_H
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines 'DIR'.
+ */
+#define HAVE_DIRENT_H 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the 'dlopen' function. */
+#undef HAVE_DLOPEN
+
+/* Define to 1 if you have the 'dup2' function. */
+#define HAVE_DUP2 1
+
+/* Defined when any dynamic module loading is enabled. */
+#undef HAVE_DYNAMIC_LOADING
+
+/* Define if you have the 'epoll' functions. */
+#undef HAVE_EPOLL
+
+/* Define to 1 if you have the 'erf' function. */
+#undef HAVE_ERF
+
+/* Define to 1 if you have the 'erfc' function. */
+#undef HAVE_ERFC
+
+/* Define to 1 if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if you have the 'execv' function. */
+#undef HAVE_EXECV
+
+/* Define to 1 if you have the 'expm1' function. */
+#undef HAVE_EXPM1
+
+/* Define if you have the 'fchdir' function. */
+#undef HAVE_FCHDIR
+
+/* Define to 1 if you have the 'fchmod' function. */
+#undef HAVE_FCHMOD
+
+/* Define to 1 if you have the 'fchown' function. */
+#undef HAVE_FCHOWN
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define if you have the 'fdatasync' function. */
+#undef HAVE_FDATASYNC
+
+/* Define to 1 if you have the 'finite' function. */
+#define HAVE_FINITE 1
+
+/* Define to 1 if you have the 'flock' function. */
+#undef HAVE_FLOCK
+
+/* Define to 1 if you have the 'fork' function. */
+#undef HAVE_FORK
+
+/* Define to 1 if you have the 'forkpty' function. */
+#undef HAVE_FORKPTY
+
+/* Define to 1 if you have the 'fpathconf' function. */
+#undef HAVE_FPATHCONF
+
+/* Define to 1 if you have the 'fseek64' function. */
+#undef HAVE_FSEEK64
+
+/* Define to 1 if you have the 'fseeko' function. */
+#define HAVE_FSEEKO 1
+
+/* Define to 1 if you have the 'fstatvfs' function. */
+#undef HAVE_FSTATVFS
+
+/* Define if you have the 'fsync' function. */
+#undef HAVE_FSYNC
+
+/* Define to 1 if you have the 'ftell64' function. */
+#undef HAVE_FTELL64
+
+/* Define to 1 if you have the 'ftello' function. */
+#define HAVE_FTELLO 1
+
+/* Define to 1 if you have the 'ftime' function. */
+#undef HAVE_FTIME
+
+/* Define to 1 if you have the 'ftruncate' function. */
+#undef HAVE_FTRUNCATE
+
+/* Define to 1 if you have the 'gai_strerror' function. */
+#undef HAVE_GAI_STRERROR
+
+/* Define to 1 if you have the 'gamma' function. */
+#undef HAVE_GAMMA
+
+/* Define if we can use gcc inline assembler to get and set x87 control word
+*/
+#if defined(__GNUC__)
+ #define HAVE_GCC_ASM_FOR_X87 1
+#else
+ #undef HAVE_GCC_ASM_FOR_X87
+#endif
+
+/* Define if you have the getaddrinfo function. */
+#undef HAVE_GETADDRINFO
+
+/* Define to 1 if you have the 'getcwd' function. */
+#define HAVE_GETCWD 1
+
+/* Define this if you have flockfile(), getc_unlocked(), and funlockfile() */
+#undef HAVE_GETC_UNLOCKED
+
+/* Define to 1 if you have the 'getgroups' function. */
+#undef HAVE_GETGROUPS
+
+/* Define to 1 if you have the 'gethostbyname' function. */
+#undef HAVE_GETHOSTBYNAME
+
+/* Define this if you have some version of gethostbyname_r() */
+#undef HAVE_GETHOSTBYNAME_R
+
+/* Define this if you have the 3-arg version of gethostbyname_r(). */
+#undef HAVE_GETHOSTBYNAME_R_3_ARG
+
+/* Define this if you have the 5-arg version of gethostbyname_r(). */
+#undef HAVE_GETHOSTBYNAME_R_5_ARG
+
+/* Define this if you have the 6-arg version of gethostbyname_r(). */
+#undef HAVE_GETHOSTBYNAME_R_6_ARG
+
+/* Define to 1 if you have the 'getitimer' function. */
+#undef HAVE_GETITIMER
+
+/* Define to 1 if you have the 'getloadavg' function. */
+#undef HAVE_GETLOADAVG
+
+/* Define to 1 if you have the 'getlogin' function. */
+#undef HAVE_GETLOGIN
+
+/* Define to 1 if you have the 'getnameinfo' function. */
+#undef HAVE_GETNAMEINFO
+
+/* Define if you have the 'getpagesize' function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define to 1 if you have the 'getpeername' function. */
+#define HAVE_GETPEERNAME 1
+
+/* Define to 1 if you have the 'getpgid' function. */
+#undef HAVE_GETPGID
+
+/* Define to 1 if you have the 'getpgrp' function. */
+#undef HAVE_GETPGRP
+
+/* Define to 1 if you have the 'getpid' function. */
+#undef HAVE_GETPID
+
+/* Define to 1 if you have the 'getpriority' function. */
+#undef HAVE_GETPRIORITY
+
+/* Define to 1 if you have the 'getpwent' function. */
+#undef HAVE_GETPWENT
+
+/* Define to 1 if you have the 'getresgid' function. */
+#undef HAVE_GETRESGID
+
+/* Define to 1 if you have the 'getresuid' function. */
+#undef HAVE_GETRESUID
+
+/* Define to 1 if you have the 'getsid' function. */
+#undef HAVE_GETSID
+
+/* Define to 1 if you have the 'getspent' function. */
+#undef HAVE_GETSPENT
+
+/* Define to 1 if you have the 'getspnam' function. */
+#undef HAVE_GETSPNAM
+
+/* Define to 1 if you have the 'gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Define to 1 if you have the 'getwd' function. */
+#undef HAVE_GETWD
+
+/* Define to 1 if you have the <grp.h> header file. */
+#undef HAVE_GRP_H
+
+/* Define if you have the 'hstrerror' function. */
+#undef HAVE_HSTRERROR
+
+/* Define to 1 if you have the 'hypot' function. */
+#undef HAVE_HYPOT
+
+/* Define to 1 if you have the <ieeefp.h> header file. */
+#undef HAVE_IEEEFP_H
+
+/* Define if you have the 'inet_aton' function. */
+#define HAVE_INET_ATON 1
+
+/* Define if you have the 'inet_pton' function. */
+#define HAVE_INET_PTON 1
+
+/* Define to 1 if you have the 'initgroups' function. */
+#undef HAVE_INITGROUPS
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <io.h> header file. */
+#undef HAVE_IO_H
+
+/* Define to 1 if you have the 'kill' function. */
+#undef HAVE_KILL
+
+/* Define to 1 if you have the 'killpg' function. */
+#undef HAVE_KILLPG
+
+/* Define if you have the 'kqueue' functions. */
+#undef HAVE_KQUEUE
+
+/* Define to 1 if you have the <langinfo.h> header file. */
+#undef HAVE_LANGINFO_H /* non-functional in EFI. */
+
+/* Defined to enable large file support when an off_t is bigger than a long
+ and long long is available and at least as big as an off_t. You may need to
+ add some flags for configuration and compilation to enable this mode. (For
+ Solaris and Linux, the necessary defines are already defined.) */
+#undef HAVE_LARGEFILE_SUPPORT
+
+/* Define to 1 if you have the 'lchflags' function. */
+#undef HAVE_LCHFLAGS
+
+/* Define to 1 if you have the 'lchmod' function. */
+#undef HAVE_LCHMOD
+
+/* Define to 1 if you have the 'lchown' function. */
+#undef HAVE_LCHOWN
+
+/* Define to 1 if you have the 'lgamma' function. */
+#undef HAVE_LGAMMA
+
+/* Define to 1 if you have the 'dl' library (-ldl). */
+#undef HAVE_LIBDL
+
+/* Define to 1 if you have the 'dld' library (-ldld). */
+#undef HAVE_LIBDLD
+
+/* Define to 1 if you have the 'ieee' library (-lieee). */
+#undef HAVE_LIBIEEE
+
+/* Define to 1 if you have the <libintl.h> header file. */
+#undef HAVE_LIBINTL_H
+
+/* Define if you have the readline library (-lreadline). */
+#undef HAVE_LIBREADLINE
+
+/* Define to 1 if you have the 'resolv' library (-lresolv). */
+#undef HAVE_LIBRESOLV
+
+/* Define to 1 if you have the <libutil.h> header file. */
+#undef HAVE_LIBUTIL_H
+
+/* Define if you have the 'link' function. */
+#undef HAVE_LINK
+
+/* Define to 1 if you have the <linux/netlink.h> header file. */
+#undef HAVE_LINUX_NETLINK_H
+
+/* Define to 1 if you have the <linux/tipc.h> header file. */
+#undef HAVE_LINUX_TIPC_H
+
+/* Define to 1 if you have the 'log1p' function. */
+#undef HAVE_LOG1P
+
+/* Define this if you have the type long double. */
+#undef HAVE_LONG_DOUBLE
+
+/* Define this if you have the type long long. */
+#define HAVE_LONG_LONG 1
+
+/* Define to 1 if you have the 'lstat' function. */
+#define HAVE_LSTAT 1
+
+/* Define this if you have the makedev macro. */
+#undef HAVE_MAKEDEV
+
+/* Define to 1 if you have the 'memmove' function. */
+#define HAVE_MEMMOVE 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the 'mkfifo' function. */
+#undef HAVE_MKFIFO
+
+/* Define to 1 if you have the 'mknod' function. */
+#undef HAVE_MKNOD
+
+/* Define to 1 if you have the 'mktime' function. */
+#define HAVE_MKTIME 1
+
+/* Define to 1 if you have the 'mremap' function. */
+#undef HAVE_MREMAP
+
+/* Define to 1 if you have the <ncurses.h> header file. */
+#undef HAVE_NCURSES_H
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines 'DIR'. */
+#undef HAVE_NDIR_H
+
+/* Define to 1 if you have the <netpacket/packet.h> header file. */
+#undef HAVE_NETPACKET_PACKET_H
+
+/* Define to 1 if you have the 'nice' function. */
+#undef HAVE_NICE
+
+/* Define to 1 if you have the 'openpty' function. */
+#undef HAVE_OPENPTY
+
+/* Define if compiling using MacOS X 10.5 SDK or later. */
+#undef HAVE_OSX105_SDK
+
+/* Define to 1 if you have the 'pathconf' function. */
+#undef HAVE_PATHCONF
+
+/* Define to 1 if you have the 'pause' function. */
+#undef HAVE_PAUSE
+
+/* Define to 1 if you have the 'plock' function. */
+#undef HAVE_PLOCK
+
+/* Define to 1 if you have the 'poll' function. */
+#define HAVE_POLL 1
+
+/* Define to 1 if you have the <poll.h> header file. */
+#undef HAVE_POLL_H
+
+/* Define to 1 if you have the <process.h> header file. */
+#undef HAVE_PROCESS_H
+
+/* Define if your compiler supports function prototype */
+#define HAVE_PROTOTYPES 1
+
+/* Define if you have GNU PTH threads. */
+#undef HAVE_PTH
+
+/* Defined for Solaris 2.6 bug in pthread header. */
+#undef HAVE_PTHREAD_DESTRUCTOR
+
+/* Define to 1 if you have the <pthread.h> header file. */
+#undef HAVE_PTHREAD_H
+
+/* Define to 1 if you have the 'pthread_init' function. */
+#undef HAVE_PTHREAD_INIT
+
+/* Define to 1 if you have the 'pthread_sigmask' function. */
+#undef HAVE_PTHREAD_SIGMASK
+
+/* Define to 1 if you have the <pty.h> header file. */
+#undef HAVE_PTY_H
+
+/* Define to 1 if you have the 'putenv' function. */
+#undef HAVE_PUTENV
+
+/* Define to 1 if you have the 'readlink' function. */
+#undef HAVE_READLINK
+
+/* Define to 1 if you have the 'realpath' function. */
+#define HAVE_REALPATH 1
+
+/* Define if you have readline 2.1 */
+#undef HAVE_RL_CALLBACK
+
+/* Define if you can turn off readline's signal handling. */
+#undef HAVE_RL_CATCH_SIGNAL
+
+/* Define if you have readline 2.2 */
+#undef HAVE_RL_COMPLETION_APPEND_CHARACTER
+
+/* Define if you have readline 4.0 */
+#undef HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK
+
+/* Define if you have readline 4.2 */
+#undef HAVE_RL_COMPLETION_MATCHES
+
+/* Define if you have rl_completion_suppress_append */
+#undef HAVE_RL_COMPLETION_SUPPRESS_APPEND
+
+/* Define if you have readline 4.0 */
+#undef HAVE_RL_PRE_INPUT_HOOK
+
+/* Define to 1 if you have the 'round' function. */
+#undef HAVE_ROUND
+
+/* Define to 1 if you have the 'select' function. */
+#define HAVE_SELECT 1
+
+/* Define to 1 if you have the 'sem_getvalue' function. */
+#undef HAVE_SEM_GETVALUE
+
+/* Define to 1 if you have the 'sem_open' function. */
+#undef HAVE_SEM_OPEN
+
+/* Define to 1 if you have the 'sem_timedwait' function. */
+#undef HAVE_SEM_TIMEDWAIT
+
+/* Define to 1 if you have the 'sem_unlink' function. */
+#undef HAVE_SEM_UNLINK
+
+/* Define to 1 if you have the 'setegid' function. */
+#undef HAVE_SETEGID
+
+/* Define to 1 if you have the 'seteuid' function. */
+#undef HAVE_SETEUID
+
+/* Define to 1 if you have the 'setgid' function. */
+#undef HAVE_SETGID
+
+/* Define if you have the 'setgroups' function. */
+#undef HAVE_SETGROUPS
+
+/* Define to 1 if you have the 'setitimer' function. */
+#undef HAVE_SETITIMER
+
+/* Define to 1 if you have the 'setlocale' function. */
+#define HAVE_SETLOCALE 1
+
+/* Define to 1 if you have the 'setpgid' function. */
+#undef HAVE_SETPGID
+
+/* Define to 1 if you have the 'setpgrp' function. */
+#undef HAVE_SETPGRP
+
+/* Define to 1 if you have the 'setregid' function. */
+#undef HAVE_SETREGID
+
+/* Define to 1 if you have the 'setresgid' function. */
+#undef HAVE_SETRESGID
+
+/* Define to 1 if you have the 'setresuid' function. */
+#undef HAVE_SETRESUID
+
+/* Define to 1 if you have the 'setreuid' function. */
+#undef HAVE_SETREUID
+
+/* Define to 1 if you have the 'setsid' function. */
+#undef HAVE_SETSID
+
+/* Define to 1 if you have the 'setuid' function. */
+#undef HAVE_SETUID
+
+/* Define to 1 if you have the 'setvbuf' function. */
+#define HAVE_SETVBUF 1
+
+/* Define to 1 if you have the <shadow.h> header file. */
+#undef HAVE_SHADOW_H
+
+/* Define to 1 if you have the 'sigaction' function. */
+#undef HAVE_SIGACTION
+
+/* Define to 1 if you have the 'siginterrupt' function. */
+#undef HAVE_SIGINTERRUPT
+
+/* Define to 1 if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H 1
+
+/* Define to 1 if you have the 'sigrelse' function. */
+#undef HAVE_SIGRELSE
+
+/* Define to 1 if you have the 'snprintf' function. */
+#define HAVE_SNPRINTF 1
+
+/* Define if sockaddr has sa_len member */
+#undef HAVE_SOCKADDR_SA_LEN
+
+/* struct sockaddr_storage (sys/socket.h) */
+#undef HAVE_SOCKADDR_STORAGE
+
+/* Define if you have the 'socketpair' function. */
+#undef HAVE_SOCKETPAIR
+
+/* Define to 1 if you have the <spawn.h> header file. */
+#undef HAVE_SPAWN_H
+
+/* Define if your compiler provides ssize_t */
+#define HAVE_SSIZE_T 1
+
+/* Define to 1 if you have the 'statvfs' function. */
+#undef HAVE_STATVFS
+
+/* Define if you have struct stat.st_mtim.tv_nsec */
+#undef HAVE_STAT_TV_NSEC
+
+/* Define if you have struct stat.st_mtimensec */
+#undef HAVE_STAT_TV_NSEC2
+
+/* Define if your compiler supports variable length function prototypes (e.g.
+ void fprintf(FILE *, char *, ...);) *and* <stdarg.h> */
+#define HAVE_STDARG_PROTOTYPES 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the 'strdup' function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the 'strftime' function. */
+#define HAVE_STRFTIME 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <stropts.h> header file. */
+#undef HAVE_STROPTS_H
+
+/* Define to 1 if 'st_birthtime' is a member of 'struct stat'. */
+#define HAVE_STRUCT_STAT_ST_BIRTHTIME 1
+
+/* Define to 1 if 'st_blksize' is a member of 'struct stat'. */
+#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
+
+/* Define to 1 if 'st_blocks' is a member of 'struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_BLOCKS
+
+/* Define to 1 if 'st_flags' is a member of 'struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_FLAGS
+
+/* Define to 1 if 'st_gen' is a member of 'struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_GEN
+
+/* Define to 1 if 'st_rdev' is a member of 'struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_RDEV
+
+/* Define to 1 if 'tm_zone' is a member of 'struct tm'. */
+#undef HAVE_STRUCT_TM_TM_ZONE
+
+/* Define to 1 if your 'struct stat' has 'st_blocks'. Deprecated, use
+ 'HAVE_STRUCT_STAT_ST_BLOCKS' instead. */
+#undef HAVE_ST_BLOCKS
+
+/* Define if you have the 'symlink' function. */
+#undef HAVE_SYMLINK
+
+/* Define to 1 if you have the 'sysconf' function. */
+#undef HAVE_SYSCONF
+
+/* Define to 1 if you have the <sysexits.h> header file. */
+#undef HAVE_SYSEXITS_H
+
+/* Define to 1 if you have the <sys/audioio.h> header file. */
+#undef HAVE_SYS_AUDIOIO_H
+
+/* Define to 1 if you have the <sys/bsdtty.h> header file. */
+#undef HAVE_SYS_BSDTTY_H
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines 'DIR'.
+ */
+#undef HAVE_SYS_DIR_H
+
+/* Define to 1 if you have the <sys/epoll.h> header file. */
+#undef HAVE_SYS_EPOLL_H
+
+/* Define to 1 if you have the <sys/event.h> header file. */
+#undef HAVE_SYS_EVENT_H
+
+/* Define to 1 if you have the <sys/file.h> header file. */
+#undef HAVE_SYS_FILE_H
+
+/* Define to 1 if you have the <sys/loadavg.h> header file. */
+#undef HAVE_SYS_LOADAVG_H
+
+/* Define to 1 if you have the <sys/lock.h> header file. */
+#undef HAVE_SYS_LOCK_H
+
+/* Define to 1 if you have the <sys/mkdev.h> header file. */
+#undef HAVE_SYS_MKDEV_H
+
+/* Define to 1 if you have the <sys/modem.h> header file. */
+#undef HAVE_SYS_MODEM_H
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines 'DIR'.
+ */
+#undef HAVE_SYS_NDIR_H
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/poll.h> header file. */
+#define HAVE_SYS_POLL_H 1
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#define HAVE_SYS_RESOURCE_H 1
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#define HAVE_SYS_SELECT_H 1
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
+
+/* Define to 1 if you have the <sys/statvfs.h> header file. */
+#undef HAVE_SYS_STATVFS_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/termio.h> header file. */
+#undef HAVE_SYS_TERMIO_H
+
+/* Define to 1 if you have the <sys/times.h> header file. */
+#undef HAVE_SYS_TIMES_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/un.h> header file. */
+#undef HAVE_SYS_UN_H
+
+/* Define to 1 if you have the <sys/utsname.h> header file. */
+#undef HAVE_SYS_UTSNAME_H
+
+/* Define to 1 if you have the <sys/wait.h> header file. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define to 1 if you have the system() command. */
+#define HAVE_SYSTEM 1
+
+/* Define to 1 if you have the 'tcgetpgrp' function. */
+#undef HAVE_TCGETPGRP
+
+/* Define to 1 if you have the 'tcsetpgrp' function. */
+#undef HAVE_TCSETPGRP
+
+/* Define to 1 if you have the 'tempnam' function. */
+#define HAVE_TEMPNAM 1
+
+/* Define to 1 if you have the <termios.h> header file. */
+#undef HAVE_TERMIOS_H
+
+/* Define to 1 if you have the <term.h> header file. */
+#undef HAVE_TERM_H
+
+/* Define to 1 if you have the 'tgamma' function. */
+#undef HAVE_TGAMMA
+
+/* Define to 1 if you have the <thread.h> header file. */
+#undef HAVE_THREAD_H
+
+/* Define to 1 if you have the 'timegm' function. */
+#undef HAVE_TIMEGM
+
+/* Define to 1 if you have the 'times' function. */
+#undef HAVE_TIMES
+
+/* Define to 1 if you have the 'tmpfile' function. */
+#define HAVE_TMPFILE 1
+
+/* Define to 1 if you have the 'tmpnam' function. */
+#define HAVE_TMPNAM 1
+
+/* Define to 1 if you have the 'tmpnam_r' function. */
+#undef HAVE_TMPNAM_R
+
+/* Define to 1 if your 'struct tm' has 'tm_zone'. Deprecated, use
+ 'HAVE_STRUCT_TM_TM_ZONE' instead. */
+#undef HAVE_TM_ZONE
+
+/* Define to 1 if you have the 'truncate' function. */
+#undef HAVE_TRUNCATE
+
+/* Define to 1 if you don't have 'tm_zone' but do have the external array
+ 'tzname'. */
+#undef HAVE_TZNAME
+
+/* Define this if you have tcl and TCL_UTF_MAX==6 */
+#undef HAVE_UCS4_TCL
+
+/* Define to 1 if the system has the type 'uintptr_t'. */
+#define HAVE_UINTPTR_T 1
+
+/* Define to 1 if you have the 'uname' function. */
+#undef HAVE_UNAME
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the 'unsetenv' function. */
+#undef HAVE_UNSETENV
+
+/* Define if you have a useable wchar_t type defined in wchar.h; useable means
+ wchar_t must be an unsigned type with at least 16 bits. (see
+ Include/unicodeobject.h). */
+#define HAVE_USABLE_WCHAR_T 1
+
+/* Define to 1 if you have the <util.h> header file. */
+#undef HAVE_UTIL_H
+
+/* Define to 1 if you have the 'utimes' function. */
+#undef HAVE_UTIMES
+
+/* Define to 1 if you have the <utime.h> header file. */
+#define HAVE_UTIME_H 1
+
+/* Define to 1 if you have the 'wait3' function. */
+#undef HAVE_WAIT3
+
+/* Define to 1 if you have the 'wait4' function. */
+#undef HAVE_WAIT4
+
+/* Define to 1 if you have the 'waitpid' function. */
+#undef HAVE_WAITPID
+
+/* Define if the compiler provides a wchar.h header file. */
+#define HAVE_WCHAR_H 1
+
+/* Define to 1 if you have the 'wcscoll' function. */
+#define HAVE_WCSCOLL 1
+
+/* Define if tzset() actually switches the local timezone in a meaningful way.
+ */
+#undef HAVE_WORKING_TZSET
+
+/* Define if the zlib library has inflateCopy */
+#undef HAVE_ZLIB_COPY
+
+/* Define to 1 if you have the '_getpty' function. */
+#undef HAVE__GETPTY
+
+/* Define if you are using Mach cthreads directly under /include */
+#undef HURD_C_THREADS
+
+/* Define if you are using Mach cthreads under mach / */
+#undef MACH_C_THREADS
+
+/* Define to 1 if 'major', 'minor', and 'makedev' are declared in <mkdev.h>.
+ */
+#undef MAJOR_IN_MKDEV
+
+/* Define to 1 if 'major', 'minor', and 'makedev' are declared in
+ <sysmacros.h>. */
+#undef MAJOR_IN_SYSMACROS
+
+/* Define if mvwdelch in curses.h is an expression. */
+#undef MVWDELCH_IS_EXPRESSION
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "edk2-devel@lists.sourceforge.net"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "EDK II Python Package"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "EDK II Python Package V0.8"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "EADK_Python"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL "http://edk2.tianocore.org/toolkit/python"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "V0.8"
+
+/* Define if POSIX semaphores aren't enabled on your system */
+#define POSIX_SEMAPHORES_NOT_ENABLED 1
+
+/* Defined if PTHREAD_SCOPE_SYSTEM supported. */
+#undef PTHREAD_SYSTEM_SCHED_SUPPORTED
+
+/* Define as the preferred size in bits of long digits */
+#undef PYLONG_BITS_IN_DIGIT
+
+/* Define to printf format modifier for long long type */
+#define PY_FORMAT_LONG_LONG "ll"
+
+/* Define to printf format modifier for Py_ssize_t */
+#define PY_FORMAT_SIZE_T "z"
+
+/* Define as the integral type used for Unicode representation. */
+#define PY_UNICODE_TYPE wchar_t
+
+/* Define if you want to build an interpreter with many run-time checks. */
+#undef Py_DEBUG
+
+/* Defined if Python is built as a shared library. */
+#undef Py_ENABLE_SHARED
+
+/* Define as the size of the unicode type. */
+#define Py_UNICODE_SIZE 2
+
+/* Define if you want to have a Unicode type. */
+#define Py_USING_UNICODE
+
+/* assume C89 semantics that RETSIGTYPE is always void */
+#undef RETSIGTYPE
+
+/* Define if setpgrp() must be called as setpgrp(0, 0). */
+#undef SETPGRP_HAVE_ARG
+
+/* Define this to be extension of shared libraries (including the dot!). */
+#undef SHLIB_EXT
+
+/* Define if i>>j for signed int i does not extend the sign bit when i < 0 */
+#undef SIGNED_RIGHT_SHIFT_ZERO_FILLS
+
+/* The size of 'double', as computed by sizeof. */
+#define SIZEOF_DOUBLE 8
+
+/* The size of 'float', as computed by sizeof. */
+#define SIZEOF_FLOAT 4
+
+/* The size of 'fpos_t', as computed by sizeof. */
+#define SIZEOF_FPOS_T 8
+
+/* The size of 'int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* The size of 'long', as computed by sizeof. */
+#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */
+#define SIZEOF_LONG 4
+#else
+#define SIZEOF_LONG 8
+#endif
+
+/* The size of 'long double', as computed by sizeof. */
+#undef SIZEOF_LONG_DOUBLE
+
+/* The size of 'long long', as computed by sizeof. */
+#define SIZEOF_LONG_LONG 8
+
+/* The size of 'off_t', as computed by sizeof. */
+#define SIZEOF_OFF_T 8
+
+/* The size of 'pid_t', as computed by sizeof. */
+#define SIZEOF_PID_T 4
+
+/* The size of 'pthread_t', as computed by sizeof. */
+#undef SIZEOF_PTHREAD_T
+
+/* The size of 'short', as computed by sizeof. */
+#define SIZEOF_SHORT 2
+
+/* The size of 'size_t', as computed by sizeof. */
+#define SIZEOF_SIZE_T 8
+
+/* The size of 'time_t', as computed by sizeof. */
+#define SIZEOF_TIME_T 4
+
+/* The size of 'uintptr_t', as computed by sizeof. */
+#define SIZEOF_UINTPTR_T 8
+
+/* The size of 'void *', as computed by sizeof. */
+#define SIZEOF_VOID_P 8
+
+/* The size of 'wchar_t', as computed by sizeof. */
+#define SIZEOF_WCHAR_T 2
+
+/* The size of '_Bool', as computed by sizeof. */
+#define SIZEOF__BOOL 1
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define if you can safely include both <sys/select.h> and <sys/time.h>
+ (which you can't on SCO ODT 3.0). */
+#undef SYS_SELECT_WITH_SYS_TIME
+
+/* Define if tanh(-0.) is -0., or if platform doesn't have signed zeros */
+#undef TANH_PRESERVES_ZERO_SIGN
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Define to 1 if your <sys/time.h> declares 'struct tm'. */
+#undef TM_IN_SYS_TIME
+
+/* Enable extensions on AIX 3, Interix. */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif
+/* Enable threading extensions on Solaris. */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# undef _POSIX_PTHREAD_SEMANTICS
+#endif
+/* Enable extensions on HP NonStop. */
+#ifndef _TANDEM_SOURCE
+# undef _TANDEM_SOURCE
+#endif
+/* Enable general extensions on Solaris. */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+
+
+/* Define if you want to use MacPython modules on MacOSX in unix-Python. */
+#undef USE_TOOLBOX_OBJECT_GLUE
+
+/* Define if a va_list is an array of some kind */
+#undef VA_LIST_IS_ARRAY
+
+/* Define if you want SIGFPE handled (see Include/pyfpe.h). */
+#undef WANT_SIGFPE_HANDLER
+
+/* Define if you want wctype.h functions to be used instead of the one
+ supplied by Python itself. (see Include/unicodectype.h). */
+#define WANT_WCTYPE_FUNCTIONS 1
+
+/* Define if WINDOW in curses.h offers a field _flags. */
+#undef WINDOW_HAS_FLAGS
+
+/* Define if you want documentation strings in extension modules */
+#undef WITH_DOC_STRINGS
+
+/* Define if you want to use the new-style (Openstep, Rhapsody, MacOS) dynamic
+ linker (dyld) instead of the old-style (NextStep) dynamic linker (rld).
+ Dyld is necessary to support frameworks. */
+#undef WITH_DYLD
+
+/* Define to 1 if libintl is needed for locale functions. */
+#undef WITH_LIBINTL
+
+/* Define if you want to produce an OpenStep/Rhapsody framework (shared
+ library plus accessory files). */
+#undef WITH_NEXT_FRAMEWORK
+
+/* Define if you want to compile in Python-specific mallocs */
+#undef WITH_PYMALLOC
+
+/* Define if you want to compile in rudimentary thread support */
+#undef WITH_THREAD
+
+/* Define to profile with the Pentium timestamp counter */
+#undef WITH_TSC
+
+/* Define if you want pymalloc to be disabled when running under valgrind */
+#undef WITH_VALGRIND
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+# undef WORDS_BIGENDIAN
+# endif
+#endif
+
+/* Define if arithmetic is subject to x87-style double rounding issue */
+#undef X87_DOUBLE_ROUNDING
+
+/* Define on OpenBSD to activate all library features */
+#undef _BSD_SOURCE
+
+/* Define on Irix to enable u_int */
+#undef _BSD_TYPES
+
+/* Define on Darwin to activate all library features */
+#undef _DARWIN_C_SOURCE
+
+/* This must be set to 64 on some systems to enable large file support. */
+#undef _FILE_OFFSET_BITS
+
+/* Define on Linux to activate all library features */
+#undef _GNU_SOURCE
+
+/* This must be defined on some systems to enable large file support. */
+#undef _LARGEFILE_SOURCE
+
+/* Define to 1 if on MINIX. */
+#undef _MINIX
+
+/* Define on NetBSD to activate all library features */
+#ifndef _NETBSD_SOURCE
+ #define _NETBSD_SOURCE 1
+#endif
+
+/* Define _OSF_SOURCE to get the makedev macro. */
+#undef _OSF_SOURCE
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+ this defined. */
+#undef _POSIX_1_SOURCE
+
+/* Define to activate features from IEEE Stds 1003.1-2001 */
+#undef _POSIX_C_SOURCE
+
+/* Define to 1 if you need to in order for 'stat' and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Define if you have POSIX threads, and your system does not define that. */
+#undef _POSIX_THREADS
+
+/* Define to force use of thread-safe errno, h_errno, and other functions */
+#undef _REENTRANT
+
+/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
+ #define below would cause a syntax error. */
+#undef _UINT32_T
+
+/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
+ #define below would cause a syntax error. */
+#undef _UINT64_T
+
+/* Define to the level of X/Open that your system supports */
+#undef _XOPEN_SOURCE
+
+/* Define to activate Unix95-and-earlier features */
+#undef _XOPEN_SOURCE_EXTENDED
+
+/* Define on FreeBSD to activate all library features */
+#undef __BSD_VISIBLE
+
+/* Define to 1 if type 'char' is unsigned and you are not using gcc. */
+#ifndef __CHAR_UNSIGNED__
+# undef __CHAR_UNSIGNED__
+#endif
+
+/* Defined on Solaris to see additional function prototypes. */
+#undef __EXTENSIONS__
+
+/* Define to 'long' if <time.h> doesn't define. */
+//#undef clock_t
+
+/* Define to empty if 'const' does not conform to ANSI C. */
+//#undef const
+
+/* Define to 'int' if <sys/types.h> doesn't define. */
+//#undef gid_t
+
+/* Define to the type of a signed integer type of width exactly 32 bits if
+ such a type exists and the standard includes do not define it. */
+//#undef int32_t
+
+/* Define to the type of a signed integer type of width exactly 64 bits if
+ such a type exists and the standard includes do not define it. */
+//#undef int64_t
+
+/* Define to 'int' if <sys/types.h> does not define. */
+//#undef mode_t
+
+/* Define to 'long int' if <sys/types.h> does not define. */
+//#undef off_t
+
+/* Define to 'int' if <sys/types.h> does not define. */
+//#undef pid_t
+
+/* Define to empty if the keyword does not work. */
+//#undef signed
+
+/* Define to 'unsigned int' if <sys/types.h> does not define. */
+//#undef size_t
+
+/* Define to 'int' if <sys/socket.h> does not define. */
+//#undef socklen_t
+
+/* Define to 'int' if <sys/types.h> doesn't define. */
+//#undef uid_t
+
+/* Define to the type of an unsigned integer type of width exactly 32 bits if
+ such a type exists and the standard includes do not define it. */
+//#undef uint32_t
+
+/* Define to the type of an unsigned integer type of width exactly 64 bits if
+ such a type exists and the standard includes do not define it. */
+//#undef uint64_t
+
+/* Define to empty if the keyword does not work. */
+//#undef volatile
+
+#endif /*Py_PYCONFIG_H*/
|