--- /dev/null
+/** @file\r
+ Manually generated Python Configuration file for EDK II.\r
+\r
+ Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials are licensed and made available under\r
+ the terms and conditions of the BSD License that accompanies this distribution.\r
+ The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+**/\r
+#ifndef Py_PYCONFIG_H\r
+#define Py_PYCONFIG_H\r
+\r
+#include <Uefi.h>\r
+\r
+#define PLATFORM "uefi"\r
+\r
+/* Define if building universal (internal helper macro) */\r
+#undef AC_APPLE_UNIVERSAL_BUILD\r
+\r
+/* Define for AIX if your compiler is a genuine IBM xlC/xlC_r and you want\r
+ support for AIX C++ shared extension modules. */\r
+#undef AIX_GENUINE_CPLUSPLUS\r
+\r
+/* Define this if you have AtheOS threads. */\r
+#undef ATHEOS_THREADS\r
+\r
+/* Define this if you have BeOS threads. */\r
+#undef BEOS_THREADS\r
+\r
+/* Define if you have the Mach cthreads package */\r
+#undef C_THREADS\r
+\r
+/* Define if C doubles are 64-bit IEEE 754 binary format, stored in ARM\r
+ mixed-endian order (byte order 45670123) */\r
+#undef DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754\r
+\r
+/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the most\r
+ significant byte first */\r
+#undef DOUBLE_IS_BIG_ENDIAN_IEEE754\r
+\r
+/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the\r
+ least significant byte first */\r
+#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754\r
+\r
+/* Define if --enable-ipv6 is specified */\r
+#undef ENABLE_IPV6\r
+\r
+/* Define if flock needs to be linked with bsd library. */\r
+#undef FLOCK_NEEDS_LIBBSD\r
+\r
+/* Define if getpgrp() must be called as getpgrp(0). */\r
+#undef GETPGRP_HAVE_ARG\r
+\r
+/* Define if gettimeofday() does not have second (timezone) argument This is\r
+ the case on Motorola V4 (R40V4.2) */\r
+#undef GETTIMEOFDAY_NO_TZ\r
+\r
+/* Define to 1 if you have the 'acosh' function. */\r
+#undef HAVE_ACOSH\r
+\r
+/* struct addrinfo (netdb.h) */\r
+#undef HAVE_ADDRINFO\r
+\r
+/* Define to 1 if you have the 'alarm' function. */\r
+#undef HAVE_ALARM\r
+\r
+/* Define this if your time.h defines altzone. */\r
+#undef HAVE_ALTZONE\r
+\r
+/* Define to 1 if you have the 'asinh' function. */\r
+#undef HAVE_ASINH\r
+\r
+/* Define to 1 if you have the <asm/types.h> header file. */\r
+#undef HAVE_ASM_TYPES_H\r
+\r
+/* Define to 1 if you have the 'atanh' function. */\r
+#undef HAVE_ATANH\r
+\r
+/* Define if GCC supports __attribute__((format(PyArg_ParseTuple, 2, 3))) */\r
+#undef HAVE_ATTRIBUTE_FORMAT_PARSETUPLE\r
+\r
+/* Define to 1 if you have the 'bind_textdomain_codeset' function. */\r
+#undef HAVE_BIND_TEXTDOMAIN_CODESET\r
+\r
+/* Define to 1 if you have the <bluetooth/bluetooth.h> header file. */\r
+#undef HAVE_BLUETOOTH_BLUETOOTH_H\r
+\r
+/* Define to 1 if you have the <bluetooth.h> header file. */\r
+#undef HAVE_BLUETOOTH_H\r
+\r
+/* Define if nice() returns success/failure instead of the new priority. */\r
+#undef HAVE_BROKEN_NICE\r
+\r
+/* Define if the system reports an invalid PIPE_BUF value. */\r
+#undef HAVE_BROKEN_PIPE_BUF\r
+\r
+/* Define if poll() sets errno on invalid file descriptors. */\r
+#undef HAVE_BROKEN_POLL\r
+\r
+/* Define if the Posix semaphores do not work on your system */\r
+#define HAVE_BROKEN_POSIX_SEMAPHORES 1\r
+\r
+/* Define if pthread_sigmask() does not work on your system. */\r
+#define HAVE_BROKEN_PTHREAD_SIGMASK 1\r
+\r
+/* define to 1 if your sem_getvalue is broken. */\r
+#define HAVE_BROKEN_SEM_GETVALUE 1\r
+\r
+/* Define this if you have the type _Bool. */\r
+#define HAVE_C99_BOOL 1\r
+\r
+/* Define to 1 if you have the 'chflags' function. */\r
+#undef HAVE_CHFLAGS\r
+\r
+/* Define to 1 if you have the 'chown' function. */\r
+#undef HAVE_CHOWN\r
+\r
+/* Define if you have the 'chroot' function. */\r
+#undef HAVE_CHROOT\r
+\r
+/* Define to 1 if you have the 'clock' function. */\r
+#define HAVE_CLOCK 1\r
+\r
+/* Define to 1 if you have the 'confstr' function. */\r
+#undef HAVE_CONFSTR\r
+\r
+/* Define to 1 if you have the <conio.h> header file. */\r
+#undef HAVE_CONIO_H\r
+\r
+/* Define to 1 if you have the 'copysign' function. */\r
+#undef HAVE_COPYSIGN\r
+\r
+/* Define to 1 if you have the 'ctermid' function. */\r
+#undef HAVE_CTERMID\r
+\r
+/* Define if you have the 'ctermid_r' function. */\r
+#undef HAVE_CTERMID_R\r
+\r
+/* Define to 1 if you have the <curses.h> header file. */\r
+#undef HAVE_CURSES_H\r
+\r
+/* Define if you have the 'is_term_resized' function. */\r
+#undef HAVE_CURSES_IS_TERM_RESIZED\r
+\r
+/* Define if you have the 'resizeterm' function. */\r
+#undef HAVE_CURSES_RESIZETERM\r
+\r
+/* Define if you have the 'resize_term' function. */\r
+#undef HAVE_CURSES_RESIZE_TERM\r
+\r
+/* Define to 1 if you have the declaration of 'isfinite', and to 0 if you\r
+ don't. */\r
+#define HAVE_DECL_ISFINITE 0\r
+\r
+/* Define to 1 if you have the declaration of 'isinf', and to 0 if you don't.\r
+ */\r
+#define HAVE_DECL_ISINF 1\r
+\r
+/* Define to 1 if you have the declaration of 'isnan', and to 0 if you don't.\r
+ */\r
+#define HAVE_DECL_ISNAN 1\r
+\r
+/* Define to 1 if you have the declaration of 'tzname', and to 0 if you don't.\r
+ */\r
+#define HAVE_DECL_TZNAME 0\r
+\r
+/* Define to 1 if you have the device macros. */\r
+#undef HAVE_DEVICE_MACROS\r
+\r
+/* Define if we have /dev/ptc. */\r
+#undef HAVE_DEV_PTC\r
+\r
+/* Define if we have /dev/ptmx. */\r
+#undef HAVE_DEV_PTMX\r
+\r
+/* Define to 1 if you have the <direct.h> header file. */\r
+#undef HAVE_DIRECT_H\r
+\r
+/* Define to 1 if you have the <dirent.h> header file, and it defines 'DIR'.\r
+ */\r
+#define HAVE_DIRENT_H 1\r
+\r
+/* Define to 1 if you have the <dlfcn.h> header file. */\r
+#undef HAVE_DLFCN_H\r
+\r
+/* Define to 1 if you have the 'dlopen' function. */\r
+#undef HAVE_DLOPEN\r
+\r
+/* Define to 1 if you have the 'dup2' function. */\r
+#define HAVE_DUP2 1\r
+\r
+/* Defined when any dynamic module loading is enabled. */\r
+#undef HAVE_DYNAMIC_LOADING\r
+\r
+/* Define if you have the 'epoll' functions. */\r
+#undef HAVE_EPOLL\r
+\r
+/* Define to 1 if you have the 'erf' function. */\r
+#undef HAVE_ERF\r
+\r
+/* Define to 1 if you have the 'erfc' function. */\r
+#undef HAVE_ERFC\r
+\r
+/* Define to 1 if you have the <errno.h> header file. */\r
+#define HAVE_ERRNO_H 1\r
+\r
+/* Define to 1 if you have the 'execv' function. */\r
+#undef HAVE_EXECV\r
+\r
+/* Define to 1 if you have the 'expm1' function. */\r
+#undef HAVE_EXPM1\r
+\r
+/* Define if you have the 'fchdir' function. */\r
+#undef HAVE_FCHDIR\r
+\r
+/* Define to 1 if you have the 'fchmod' function. */\r
+#undef HAVE_FCHMOD\r
+\r
+/* Define to 1 if you have the 'fchown' function. */\r
+#undef HAVE_FCHOWN\r
+\r
+/* Define to 1 if you have the <fcntl.h> header file. */\r
+#define HAVE_FCNTL_H 1\r
+\r
+/* Define if you have the 'fdatasync' function. */\r
+#undef HAVE_FDATASYNC\r
+\r
+/* Define to 1 if you have the 'finite' function. */\r
+#define HAVE_FINITE 1\r
+\r
+/* Define to 1 if you have the 'flock' function. */\r
+#undef HAVE_FLOCK\r
+\r
+/* Define to 1 if you have the 'fork' function. */\r
+#undef HAVE_FORK\r
+\r
+/* Define to 1 if you have the 'forkpty' function. */\r
+#undef HAVE_FORKPTY\r
+\r
+/* Define to 1 if you have the 'fpathconf' function. */\r
+#undef HAVE_FPATHCONF\r
+\r
+/* Define to 1 if you have the 'fseek64' function. */\r
+#undef HAVE_FSEEK64\r
+\r
+/* Define to 1 if you have the 'fseeko' function. */\r
+#define HAVE_FSEEKO 1\r
+\r
+/* Define to 1 if you have the 'fstatvfs' function. */\r
+#undef HAVE_FSTATVFS\r
+\r
+/* Define if you have the 'fsync' function. */\r
+#undef HAVE_FSYNC\r
+\r
+/* Define to 1 if you have the 'ftell64' function. */\r
+#undef HAVE_FTELL64\r
+\r
+/* Define to 1 if you have the 'ftello' function. */\r
+#define HAVE_FTELLO 1\r
+\r
+/* Define to 1 if you have the 'ftime' function. */\r
+#undef HAVE_FTIME\r
+\r
+/* Define to 1 if you have the 'ftruncate' function. */\r
+#undef HAVE_FTRUNCATE\r
+\r
+/* Define to 1 if you have the 'gai_strerror' function. */\r
+#undef HAVE_GAI_STRERROR\r
+\r
+/* Define to 1 if you have the 'gamma' function. */\r
+#undef HAVE_GAMMA\r
+\r
+/* Define if we can use gcc inline assembler to get and set x87 control word\r
+*/\r
+#if defined(__GNUC__)\r
+ #define HAVE_GCC_ASM_FOR_X87 1\r
+#else\r
+ #undef HAVE_GCC_ASM_FOR_X87\r
+#endif\r
+\r
+/* Define if you have the getaddrinfo function. */\r
+#undef HAVE_GETADDRINFO\r
+\r
+/* Define to 1 if you have the 'getcwd' function. */\r
+#define HAVE_GETCWD 1\r
+\r
+/* Define this if you have flockfile(), getc_unlocked(), and funlockfile() */\r
+#undef HAVE_GETC_UNLOCKED\r
+\r
+/* Define to 1 if you have the 'getgroups' function. */\r
+#undef HAVE_GETGROUPS\r
+\r
+/* Define to 1 if you have the 'gethostbyname' function. */\r
+#undef HAVE_GETHOSTBYNAME\r
+\r
+/* Define this if you have some version of gethostbyname_r() */\r
+#undef HAVE_GETHOSTBYNAME_R\r
+\r
+/* Define this if you have the 3-arg version of gethostbyname_r(). */\r
+#undef HAVE_GETHOSTBYNAME_R_3_ARG\r
+\r
+/* Define this if you have the 5-arg version of gethostbyname_r(). */\r
+#undef HAVE_GETHOSTBYNAME_R_5_ARG\r
+\r
+/* Define this if you have the 6-arg version of gethostbyname_r(). */\r
+#undef HAVE_GETHOSTBYNAME_R_6_ARG\r
+\r
+/* Define to 1 if you have the 'getitimer' function. */\r
+#undef HAVE_GETITIMER\r
+\r
+/* Define to 1 if you have the 'getloadavg' function. */\r
+#undef HAVE_GETLOADAVG\r
+\r
+/* Define to 1 if you have the 'getlogin' function. */\r
+#undef HAVE_GETLOGIN\r
+\r
+/* Define to 1 if you have the 'getnameinfo' function. */\r
+#undef HAVE_GETNAMEINFO\r
+\r
+/* Define if you have the 'getpagesize' function. */\r
+#undef HAVE_GETPAGESIZE\r
+\r
+/* Define to 1 if you have the 'getpeername' function. */\r
+#define HAVE_GETPEERNAME 1\r
+\r
+/* Define to 1 if you have the 'getpgid' function. */\r
+#undef HAVE_GETPGID\r
+\r
+/* Define to 1 if you have the 'getpgrp' function. */\r
+#undef HAVE_GETPGRP\r
+\r
+/* Define to 1 if you have the 'getpid' function. */\r
+#undef HAVE_GETPID\r
+\r
+/* Define to 1 if you have the 'getpriority' function. */\r
+#undef HAVE_GETPRIORITY\r
+\r
+/* Define to 1 if you have the 'getpwent' function. */\r
+#undef HAVE_GETPWENT\r
+\r
+/* Define to 1 if you have the 'getresgid' function. */\r
+#undef HAVE_GETRESGID\r
+\r
+/* Define to 1 if you have the 'getresuid' function. */\r
+#undef HAVE_GETRESUID\r
+\r
+/* Define to 1 if you have the 'getsid' function. */\r
+#undef HAVE_GETSID\r
+\r
+/* Define to 1 if you have the 'getspent' function. */\r
+#undef HAVE_GETSPENT\r
+\r
+/* Define to 1 if you have the 'getspnam' function. */\r
+#undef HAVE_GETSPNAM\r
+\r
+/* Define to 1 if you have the 'gettimeofday' function. */\r
+#undef HAVE_GETTIMEOFDAY\r
+\r
+/* Define to 1 if you have the 'getwd' function. */\r
+#undef HAVE_GETWD\r
+\r
+/* Define to 1 if you have the <grp.h> header file. */\r
+#undef HAVE_GRP_H\r
+\r
+/* Define if you have the 'hstrerror' function. */\r
+#undef HAVE_HSTRERROR\r
+\r
+/* Define to 1 if you have the 'hypot' function. */\r
+#undef HAVE_HYPOT\r
+\r
+/* Define to 1 if you have the <ieeefp.h> header file. */\r
+#undef HAVE_IEEEFP_H\r
+\r
+/* Define if you have the 'inet_aton' function. */\r
+#define HAVE_INET_ATON 1\r
+\r
+/* Define if you have the 'inet_pton' function. */\r
+#define HAVE_INET_PTON 1\r
+\r
+/* Define to 1 if you have the 'initgroups' function. */\r
+#undef HAVE_INITGROUPS\r
+\r
+/* Define to 1 if you have the <inttypes.h> header file. */\r
+#define HAVE_INTTYPES_H 1\r
+\r
+/* Define to 1 if you have the <io.h> header file. */\r
+#undef HAVE_IO_H\r
+\r
+/* Define to 1 if you have the 'kill' function. */\r
+#undef HAVE_KILL\r
+\r
+/* Define to 1 if you have the 'killpg' function. */\r
+#undef HAVE_KILLPG\r
+\r
+/* Define if you have the 'kqueue' functions. */\r
+#undef HAVE_KQUEUE\r
+\r
+/* Define to 1 if you have the <langinfo.h> header file. */\r
+#undef HAVE_LANGINFO_H /* non-functional in EFI. */\r
+\r
+/* Defined to enable large file support when an off_t is bigger than a long\r
+ and long long is available and at least as big as an off_t. You may need to\r
+ add some flags for configuration and compilation to enable this mode. (For\r
+ Solaris and Linux, the necessary defines are already defined.) */\r
+#undef HAVE_LARGEFILE_SUPPORT\r
+\r
+/* Define to 1 if you have the 'lchflags' function. */\r
+#undef HAVE_LCHFLAGS\r
+\r
+/* Define to 1 if you have the 'lchmod' function. */\r
+#undef HAVE_LCHMOD\r
+\r
+/* Define to 1 if you have the 'lchown' function. */\r
+#undef HAVE_LCHOWN\r
+\r
+/* Define to 1 if you have the 'lgamma' function. */\r
+#undef HAVE_LGAMMA\r
+\r
+/* Define to 1 if you have the 'dl' library (-ldl). */\r
+#undef HAVE_LIBDL\r
+\r
+/* Define to 1 if you have the 'dld' library (-ldld). */\r
+#undef HAVE_LIBDLD\r
+\r
+/* Define to 1 if you have the 'ieee' library (-lieee). */\r
+#undef HAVE_LIBIEEE\r
+\r
+/* Define to 1 if you have the <libintl.h> header file. */\r
+#undef HAVE_LIBINTL_H\r
+\r
+/* Define if you have the readline library (-lreadline). */\r
+#undef HAVE_LIBREADLINE\r
+\r
+/* Define to 1 if you have the 'resolv' library (-lresolv). */\r
+#undef HAVE_LIBRESOLV\r
+\r
+/* Define to 1 if you have the <libutil.h> header file. */\r
+#undef HAVE_LIBUTIL_H\r
+\r
+/* Define if you have the 'link' function. */\r
+#undef HAVE_LINK\r
+\r
+/* Define to 1 if you have the <linux/netlink.h> header file. */\r
+#undef HAVE_LINUX_NETLINK_H\r
+\r
+/* Define to 1 if you have the <linux/tipc.h> header file. */\r
+#undef HAVE_LINUX_TIPC_H\r
+\r
+/* Define to 1 if you have the 'log1p' function. */\r
+#undef HAVE_LOG1P\r
+\r
+/* Define this if you have the type long double. */\r
+#undef HAVE_LONG_DOUBLE\r
+\r
+/* Define this if you have the type long long. */\r
+#define HAVE_LONG_LONG 1\r
+\r
+/* Define to 1 if you have the 'lstat' function. */\r
+#define HAVE_LSTAT 1\r
+\r
+/* Define this if you have the makedev macro. */\r
+#undef HAVE_MAKEDEV\r
+\r
+/* Define to 1 if you have the 'memmove' function. */\r
+#define HAVE_MEMMOVE 1\r
+\r
+/* Define to 1 if you have the <memory.h> header file. */\r
+#undef HAVE_MEMORY_H\r
+\r
+/* Define to 1 if you have the 'mkfifo' function. */\r
+#undef HAVE_MKFIFO\r
+\r
+/* Define to 1 if you have the 'mknod' function. */\r
+#undef HAVE_MKNOD\r
+\r
+/* Define to 1 if you have the 'mktime' function. */\r
+#define HAVE_MKTIME 1\r
+\r
+/* Define to 1 if you have the 'mremap' function. */\r
+#undef HAVE_MREMAP\r
+\r
+/* Define to 1 if you have the <ncurses.h> header file. */\r
+#undef HAVE_NCURSES_H\r
+\r
+/* Define to 1 if you have the <ndir.h> header file, and it defines 'DIR'. */\r
+#undef HAVE_NDIR_H\r
+\r
+/* Define to 1 if you have the <netpacket/packet.h> header file. */\r
+#undef HAVE_NETPACKET_PACKET_H\r
+\r
+/* Define to 1 if you have the 'nice' function. */\r
+#undef HAVE_NICE\r
+\r
+/* Define to 1 if you have the 'openpty' function. */\r
+#undef HAVE_OPENPTY\r
+\r
+/* Define if compiling using MacOS X 10.5 SDK or later. */\r
+#undef HAVE_OSX105_SDK\r
+\r
+/* Define to 1 if you have the 'pathconf' function. */\r
+#undef HAVE_PATHCONF\r
+\r
+/* Define to 1 if you have the 'pause' function. */\r
+#undef HAVE_PAUSE\r
+\r
+/* Define to 1 if you have the 'plock' function. */\r
+#undef HAVE_PLOCK\r
+\r
+/* Define to 1 if you have the 'poll' function. */\r
+#define HAVE_POLL 1\r
+\r
+/* Define to 1 if you have the <poll.h> header file. */\r
+#undef HAVE_POLL_H\r
+\r
+/* Define to 1 if you have the <process.h> header file. */\r
+#undef HAVE_PROCESS_H\r
+\r
+/* Define if your compiler supports function prototype */\r
+#define HAVE_PROTOTYPES 1\r
+\r
+/* Define if you have GNU PTH threads. */\r
+#undef HAVE_PTH\r
+\r
+/* Defined for Solaris 2.6 bug in pthread header. */\r
+#undef HAVE_PTHREAD_DESTRUCTOR\r
+\r
+/* Define to 1 if you have the <pthread.h> header file. */\r
+#undef HAVE_PTHREAD_H\r
+\r
+/* Define to 1 if you have the 'pthread_init' function. */\r
+#undef HAVE_PTHREAD_INIT\r
+\r
+/* Define to 1 if you have the 'pthread_sigmask' function. */\r
+#undef HAVE_PTHREAD_SIGMASK\r
+\r
+/* Define to 1 if you have the <pty.h> header file. */\r
+#undef HAVE_PTY_H\r
+\r
+/* Define to 1 if you have the 'putenv' function. */\r
+#undef HAVE_PUTENV\r
+\r
+/* Define to 1 if you have the 'readlink' function. */\r
+#undef HAVE_READLINK\r
+\r
+/* Define to 1 if you have the 'realpath' function. */\r
+#define HAVE_REALPATH 1\r
+\r
+/* Define if you have readline 2.1 */\r
+#undef HAVE_RL_CALLBACK\r
+\r
+/* Define if you can turn off readline's signal handling. */\r
+#undef HAVE_RL_CATCH_SIGNAL\r
+\r
+/* Define if you have readline 2.2 */\r
+#undef HAVE_RL_COMPLETION_APPEND_CHARACTER\r
+\r
+/* Define if you have readline 4.0 */\r
+#undef HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK\r
+\r
+/* Define if you have readline 4.2 */\r
+#undef HAVE_RL_COMPLETION_MATCHES\r
+\r
+/* Define if you have rl_completion_suppress_append */\r
+#undef HAVE_RL_COMPLETION_SUPPRESS_APPEND\r
+\r
+/* Define if you have readline 4.0 */\r
+#undef HAVE_RL_PRE_INPUT_HOOK\r
+\r
+/* Define to 1 if you have the 'round' function. */\r
+#undef HAVE_ROUND\r
+\r
+/* Define to 1 if you have the 'select' function. */\r
+#define HAVE_SELECT 1\r
+\r
+/* Define to 1 if you have the 'sem_getvalue' function. */\r
+#undef HAVE_SEM_GETVALUE\r
+\r
+/* Define to 1 if you have the 'sem_open' function. */\r
+#undef HAVE_SEM_OPEN\r
+\r
+/* Define to 1 if you have the 'sem_timedwait' function. */\r
+#undef HAVE_SEM_TIMEDWAIT\r
+\r
+/* Define to 1 if you have the 'sem_unlink' function. */\r
+#undef HAVE_SEM_UNLINK\r
+\r
+/* Define to 1 if you have the 'setegid' function. */\r
+#undef HAVE_SETEGID\r
+\r
+/* Define to 1 if you have the 'seteuid' function. */\r
+#undef HAVE_SETEUID\r
+\r
+/* Define to 1 if you have the 'setgid' function. */\r
+#undef HAVE_SETGID\r
+\r
+/* Define if you have the 'setgroups' function. */\r
+#undef HAVE_SETGROUPS\r
+\r
+/* Define to 1 if you have the 'setitimer' function. */\r
+#undef HAVE_SETITIMER\r
+\r
+/* Define to 1 if you have the 'setlocale' function. */\r
+#define HAVE_SETLOCALE 1\r
+\r
+/* Define to 1 if you have the 'setpgid' function. */\r
+#undef HAVE_SETPGID\r
+\r
+/* Define to 1 if you have the 'setpgrp' function. */\r
+#undef HAVE_SETPGRP\r
+\r
+/* Define to 1 if you have the 'setregid' function. */\r
+#undef HAVE_SETREGID\r
+\r
+/* Define to 1 if you have the 'setresgid' function. */\r
+#undef HAVE_SETRESGID\r
+\r
+/* Define to 1 if you have the 'setresuid' function. */\r
+#undef HAVE_SETRESUID\r
+\r
+/* Define to 1 if you have the 'setreuid' function. */\r
+#undef HAVE_SETREUID\r
+\r
+/* Define to 1 if you have the 'setsid' function. */\r
+#undef HAVE_SETSID\r
+\r
+/* Define to 1 if you have the 'setuid' function. */\r
+#undef HAVE_SETUID\r
+\r
+/* Define to 1 if you have the 'setvbuf' function. */\r
+#define HAVE_SETVBUF 1\r
+\r
+/* Define to 1 if you have the <shadow.h> header file. */\r
+#undef HAVE_SHADOW_H\r
+\r
+/* Define to 1 if you have the 'sigaction' function. */\r
+#undef HAVE_SIGACTION\r
+\r
+/* Define to 1 if you have the 'siginterrupt' function. */\r
+#undef HAVE_SIGINTERRUPT\r
+\r
+/* Define to 1 if you have the <signal.h> header file. */\r
+#define HAVE_SIGNAL_H 1\r
+\r
+/* Define to 1 if you have the 'sigrelse' function. */\r
+#undef HAVE_SIGRELSE\r
+\r
+/* Define to 1 if you have the 'snprintf' function. */\r
+#define HAVE_SNPRINTF 1\r
+\r
+/* Define if sockaddr has sa_len member */\r
+#undef HAVE_SOCKADDR_SA_LEN\r
+\r
+/* struct sockaddr_storage (sys/socket.h) */\r
+#undef HAVE_SOCKADDR_STORAGE\r
+\r
+/* Define if you have the 'socketpair' function. */\r
+#undef HAVE_SOCKETPAIR\r
+\r
+/* Define to 1 if you have the <spawn.h> header file. */\r
+#undef HAVE_SPAWN_H\r
+\r
+/* Define if your compiler provides ssize_t */\r
+#define HAVE_SSIZE_T 1\r
+\r
+/* Define to 1 if you have the 'statvfs' function. */\r
+#undef HAVE_STATVFS\r
+\r
+/* Define if you have struct stat.st_mtim.tv_nsec */\r
+#undef HAVE_STAT_TV_NSEC\r
+\r
+/* Define if you have struct stat.st_mtimensec */\r
+#undef HAVE_STAT_TV_NSEC2\r
+\r
+/* Define if your compiler supports variable length function prototypes (e.g.\r
+ void fprintf(FILE *, char *, ...);) *and* <stdarg.h> */\r
+#define HAVE_STDARG_PROTOTYPES 1\r
+\r
+/* Define to 1 if you have the <stdint.h> header file. */\r
+#define HAVE_STDINT_H 1\r
+\r
+/* Define to 1 if you have the <stdlib.h> header file. */\r
+#define HAVE_STDLIB_H 1\r
+\r
+/* Define to 1 if you have the 'strdup' function. */\r
+#define HAVE_STRDUP 1\r
+\r
+/* Define to 1 if you have the 'strftime' function. */\r
+#define HAVE_STRFTIME 1\r
+\r
+/* Define to 1 if you have the <strings.h> header file. */\r
+#undef HAVE_STRINGS_H\r
+\r
+/* Define to 1 if you have the <string.h> header file. */\r
+#define HAVE_STRING_H 1\r
+\r
+/* Define to 1 if you have the <stropts.h> header file. */\r
+#undef HAVE_STROPTS_H\r
+\r
+/* Define to 1 if 'st_birthtime' is a member of 'struct stat'. */\r
+#define HAVE_STRUCT_STAT_ST_BIRTHTIME 1\r
+\r
+/* Define to 1 if 'st_blksize' is a member of 'struct stat'. */\r
+#define HAVE_STRUCT_STAT_ST_BLKSIZE 1\r
+\r
+/* Define to 1 if 'st_blocks' is a member of 'struct stat'. */\r
+#undef HAVE_STRUCT_STAT_ST_BLOCKS\r
+\r
+/* Define to 1 if 'st_flags' is a member of 'struct stat'. */\r
+#undef HAVE_STRUCT_STAT_ST_FLAGS\r
+\r
+/* Define to 1 if 'st_gen' is a member of 'struct stat'. */\r
+#undef HAVE_STRUCT_STAT_ST_GEN\r
+\r
+/* Define to 1 if 'st_rdev' is a member of 'struct stat'. */\r
+#undef HAVE_STRUCT_STAT_ST_RDEV\r
+\r
+/* Define to 1 if 'tm_zone' is a member of 'struct tm'. */\r
+#undef HAVE_STRUCT_TM_TM_ZONE\r
+\r
+/* Define to 1 if your 'struct stat' has 'st_blocks'. Deprecated, use\r
+ 'HAVE_STRUCT_STAT_ST_BLOCKS' instead. */\r
+#undef HAVE_ST_BLOCKS\r
+\r
+/* Define if you have the 'symlink' function. */\r
+#undef HAVE_SYMLINK\r
+\r
+/* Define to 1 if you have the 'sysconf' function. */\r
+#undef HAVE_SYSCONF\r
+\r
+/* Define to 1 if you have the <sysexits.h> header file. */\r
+#undef HAVE_SYSEXITS_H\r
+\r
+/* Define to 1 if you have the <sys/audioio.h> header file. */\r
+#undef HAVE_SYS_AUDIOIO_H\r
+\r
+/* Define to 1 if you have the <sys/bsdtty.h> header file. */\r
+#undef HAVE_SYS_BSDTTY_H\r
+\r
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines 'DIR'.\r
+ */\r
+#undef HAVE_SYS_DIR_H\r
+\r
+/* Define to 1 if you have the <sys/epoll.h> header file. */\r
+#undef HAVE_SYS_EPOLL_H\r
+\r
+/* Define to 1 if you have the <sys/event.h> header file. */\r
+#undef HAVE_SYS_EVENT_H\r
+\r
+/* Define to 1 if you have the <sys/file.h> header file. */\r
+#undef HAVE_SYS_FILE_H\r
+\r
+/* Define to 1 if you have the <sys/loadavg.h> header file. */\r
+#undef HAVE_SYS_LOADAVG_H\r
+\r
+/* Define to 1 if you have the <sys/lock.h> header file. */\r
+#undef HAVE_SYS_LOCK_H\r
+\r
+/* Define to 1 if you have the <sys/mkdev.h> header file. */\r
+#undef HAVE_SYS_MKDEV_H\r
+\r
+/* Define to 1 if you have the <sys/modem.h> header file. */\r
+#undef HAVE_SYS_MODEM_H\r
+\r
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines 'DIR'.\r
+ */\r
+#undef HAVE_SYS_NDIR_H\r
+\r
+/* Define to 1 if you have the <sys/param.h> header file. */\r
+#define HAVE_SYS_PARAM_H 1\r
+\r
+/* Define to 1 if you have the <sys/poll.h> header file. */\r
+#define HAVE_SYS_POLL_H 1\r
+\r
+/* Define to 1 if you have the <sys/resource.h> header file. */\r
+#define HAVE_SYS_RESOURCE_H 1\r
+\r
+/* Define to 1 if you have the <sys/select.h> header file. */\r
+#define HAVE_SYS_SELECT_H 1\r
+\r
+/* Define to 1 if you have the <sys/socket.h> header file. */\r
+#define HAVE_SYS_SOCKET_H 1\r
+\r
+/* Define to 1 if you have the <sys/statvfs.h> header file. */\r
+#undef HAVE_SYS_STATVFS_H\r
+\r
+/* Define to 1 if you have the <sys/stat.h> header file. */\r
+#define HAVE_SYS_STAT_H 1\r
+\r
+/* Define to 1 if you have the <sys/termio.h> header file. */\r
+#undef HAVE_SYS_TERMIO_H\r
+\r
+/* Define to 1 if you have the <sys/times.h> header file. */\r
+#undef HAVE_SYS_TIMES_H\r
+\r
+/* Define to 1 if you have the <sys/time.h> header file. */\r
+#define HAVE_SYS_TIME_H 1\r
+\r
+/* Define to 1 if you have the <sys/types.h> header file. */\r
+#define HAVE_SYS_TYPES_H 1\r
+\r
+/* Define to 1 if you have the <sys/un.h> header file. */\r
+#undef HAVE_SYS_UN_H\r
+\r
+/* Define to 1 if you have the <sys/utsname.h> header file. */\r
+#undef HAVE_SYS_UTSNAME_H\r
+\r
+/* Define to 1 if you have the <sys/wait.h> header file. */\r
+#undef HAVE_SYS_WAIT_H\r
+\r
+/* Define to 1 if you have the system() command. */\r
+#define HAVE_SYSTEM 1\r
+\r
+/* Define to 1 if you have the 'tcgetpgrp' function. */\r
+#undef HAVE_TCGETPGRP\r
+\r
+/* Define to 1 if you have the 'tcsetpgrp' function. */\r
+#undef HAVE_TCSETPGRP\r
+\r
+/* Define to 1 if you have the 'tempnam' function. */\r
+#define HAVE_TEMPNAM 1\r
+\r
+/* Define to 1 if you have the <termios.h> header file. */\r
+#undef HAVE_TERMIOS_H\r
+\r
+/* Define to 1 if you have the <term.h> header file. */\r
+#undef HAVE_TERM_H\r
+\r
+/* Define to 1 if you have the 'tgamma' function. */\r
+#undef HAVE_TGAMMA\r
+\r
+/* Define to 1 if you have the <thread.h> header file. */\r
+#undef HAVE_THREAD_H\r
+\r
+/* Define to 1 if you have the 'timegm' function. */\r
+#undef HAVE_TIMEGM\r
+\r
+/* Define to 1 if you have the 'times' function. */\r
+#undef HAVE_TIMES\r
+\r
+/* Define to 1 if you have the 'tmpfile' function. */\r
+#define HAVE_TMPFILE 1\r
+\r
+/* Define to 1 if you have the 'tmpnam' function. */\r
+#define HAVE_TMPNAM 1\r
+\r
+/* Define to 1 if you have the 'tmpnam_r' function. */\r
+#undef HAVE_TMPNAM_R\r
+\r
+/* Define to 1 if your 'struct tm' has 'tm_zone'. Deprecated, use\r
+ 'HAVE_STRUCT_TM_TM_ZONE' instead. */\r
+#undef HAVE_TM_ZONE\r
+\r
+/* Define to 1 if you have the 'truncate' function. */\r
+#undef HAVE_TRUNCATE\r
+\r
+/* Define to 1 if you don't have 'tm_zone' but do have the external array\r
+ 'tzname'. */\r
+#undef HAVE_TZNAME\r
+\r
+/* Define this if you have tcl and TCL_UTF_MAX==6 */\r
+#undef HAVE_UCS4_TCL\r
+\r
+/* Define to 1 if the system has the type 'uintptr_t'. */\r
+#define HAVE_UINTPTR_T 1\r
+\r
+/* Define to 1 if you have the 'uname' function. */\r
+#undef HAVE_UNAME\r
+\r
+/* Define to 1 if you have the <unistd.h> header file. */\r
+#define HAVE_UNISTD_H 1\r
+\r
+/* Define to 1 if you have the 'unsetenv' function. */\r
+#undef HAVE_UNSETENV\r
+\r
+/* Define if you have a useable wchar_t type defined in wchar.h; useable means\r
+ wchar_t must be an unsigned type with at least 16 bits. (see\r
+ Include/unicodeobject.h). */\r
+#define HAVE_USABLE_WCHAR_T 1\r
+\r
+/* Define to 1 if you have the <util.h> header file. */\r
+#undef HAVE_UTIL_H\r
+\r
+/* Define to 1 if you have the 'utimes' function. */\r
+#undef HAVE_UTIMES\r
+\r
+/* Define to 1 if you have the <utime.h> header file. */\r
+#define HAVE_UTIME_H 1\r
+\r
+/* Define to 1 if you have the 'wait3' function. */\r
+#undef HAVE_WAIT3\r
+\r
+/* Define to 1 if you have the 'wait4' function. */\r
+#undef HAVE_WAIT4\r
+\r
+/* Define to 1 if you have the 'waitpid' function. */\r
+#undef HAVE_WAITPID\r
+\r
+/* Define if the compiler provides a wchar.h header file. */\r
+#define HAVE_WCHAR_H 1\r
+\r
+/* Define to 1 if you have the 'wcscoll' function. */\r
+#define HAVE_WCSCOLL 1\r
+\r
+/* Define if tzset() actually switches the local timezone in a meaningful way.\r
+ */\r
+#undef HAVE_WORKING_TZSET\r
+\r
+/* Define if the zlib library has inflateCopy */\r
+#undef HAVE_ZLIB_COPY\r
+\r
+/* Define to 1 if you have the '_getpty' function. */\r
+#undef HAVE__GETPTY\r
+\r
+/* Define if you are using Mach cthreads directly under /include */\r
+#undef HURD_C_THREADS\r
+\r
+/* Define if you are using Mach cthreads under mach / */\r
+#undef MACH_C_THREADS\r
+\r
+/* Define to 1 if 'major', 'minor', and 'makedev' are declared in <mkdev.h>.\r
+ */\r
+#undef MAJOR_IN_MKDEV\r
+\r
+/* Define to 1 if 'major', 'minor', and 'makedev' are declared in\r
+ <sysmacros.h>. */\r
+#undef MAJOR_IN_SYSMACROS\r
+\r
+/* Define if mvwdelch in curses.h is an expression. */\r
+#undef MVWDELCH_IS_EXPRESSION\r
+\r
+/* Define to the address where bug reports for this package should be sent. */\r
+#define PACKAGE_BUGREPORT "edk2-devel@lists.sourceforge.net"\r
+\r
+/* Define to the full name of this package. */\r
+#define PACKAGE_NAME "EDK II Python Package"\r
+\r
+/* Define to the full name and version of this package. */\r
+#define PACKAGE_STRING "EDK II Python Package V0.8"\r
+\r
+/* Define to the one symbol short name of this package. */\r
+#define PACKAGE_TARNAME "EADK_Python"\r
+\r
+/* Define to the home page for this package. */\r
+#define PACKAGE_URL "http://edk2.tianocore.org/toolkit/python"\r
+\r
+/* Define to the version of this package. */\r
+#define PACKAGE_VERSION "V0.8"\r
+\r
+/* Define if POSIX semaphores aren't enabled on your system */\r
+#define POSIX_SEMAPHORES_NOT_ENABLED 1\r
+\r
+/* Defined if PTHREAD_SCOPE_SYSTEM supported. */\r
+#undef PTHREAD_SYSTEM_SCHED_SUPPORTED\r
+\r
+/* Define as the preferred size in bits of long digits */\r
+#undef PYLONG_BITS_IN_DIGIT\r
+\r
+/* Define to printf format modifier for long long type */\r
+#define PY_FORMAT_LONG_LONG "ll"\r
+\r
+/* Define to printf format modifier for Py_ssize_t */\r
+#define PY_FORMAT_SIZE_T "z"\r
+\r
+/* Define as the integral type used for Unicode representation. */\r
+#define PY_UNICODE_TYPE wchar_t\r
+\r
+/* Define if you want to build an interpreter with many run-time checks. */\r
+#undef Py_DEBUG\r
+\r
+/* Defined if Python is built as a shared library. */\r
+#undef Py_ENABLE_SHARED\r
+\r
+/* Define as the size of the unicode type. */\r
+#define Py_UNICODE_SIZE 2\r
+\r
+/* Define if you want to have a Unicode type. */\r
+#define Py_USING_UNICODE\r
+\r
+/* assume C89 semantics that RETSIGTYPE is always void */\r
+#undef RETSIGTYPE\r
+\r
+/* Define if setpgrp() must be called as setpgrp(0, 0). */\r
+#undef SETPGRP_HAVE_ARG\r
+\r
+/* Define this to be extension of shared libraries (including the dot!). */\r
+#undef SHLIB_EXT\r
+\r
+/* Define if i>>j for signed int i does not extend the sign bit when i < 0 */\r
+#undef SIGNED_RIGHT_SHIFT_ZERO_FILLS\r
+\r
+/* The size of 'double', as computed by sizeof. */\r
+#define SIZEOF_DOUBLE 8\r
+\r
+/* The size of 'float', as computed by sizeof. */\r
+#define SIZEOF_FLOAT 4\r
+\r
+/* The size of 'fpos_t', as computed by sizeof. */\r
+#define SIZEOF_FPOS_T 8\r
+\r
+/* The size of 'int', as computed by sizeof. */\r
+#define SIZEOF_INT 4\r
+\r
+/* The size of 'long', as computed by sizeof. */\r
+#define SIZEOF_LONG 4\r
+\r
+/* The size of 'long double', as computed by sizeof. */\r
+#undef SIZEOF_LONG_DOUBLE\r
+\r
+/* The size of 'long long', as computed by sizeof. */\r
+#define SIZEOF_LONG_LONG 8\r
+\r
+/* The size of 'off_t', as computed by sizeof. */\r
+#define SIZEOF_OFF_T 4\r
+\r
+/* The size of 'pid_t', as computed by sizeof. */\r
+#define SIZEOF_PID_T 4\r
+\r
+/* The size of 'pthread_t', as computed by sizeof. */\r
+#undef SIZEOF_PTHREAD_T\r
+\r
+/* The size of 'short', as computed by sizeof. */\r
+#define SIZEOF_SHORT 2\r
+\r
+/* The size of 'size_t', as computed by sizeof. */\r
+#define SIZEOF_SIZE_T 4\r
+\r
+/* The size of 'time_t', as computed by sizeof. */\r
+#define SIZEOF_TIME_T 4\r
+\r
+/* The size of 'uintptr_t', as computed by sizeof. */\r
+#define SIZEOF_UINTPTR_T 4\r
+\r
+/* The size of 'void *', as computed by sizeof. */\r
+#define SIZEOF_VOID_P 4\r
+\r
+/* The size of 'wchar_t', as computed by sizeof. */\r
+#define SIZEOF_WCHAR_T 2\r
+\r
+/* The size of '_Bool', as computed by sizeof. */\r
+#define SIZEOF__BOOL 1\r
+\r
+/* Define to 1 if you have the ANSI C header files. */\r
+#define STDC_HEADERS 1\r
+\r
+/* Define if you can safely include both <sys/select.h> and <sys/time.h>\r
+ (which you can't on SCO ODT 3.0). */\r
+#undef SYS_SELECT_WITH_SYS_TIME\r
+\r
+/* Define if tanh(-0.) is -0., or if platform doesn't have signed zeros */\r
+#undef TANH_PRESERVES_ZERO_SIGN\r
+\r
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */\r
+#undef TIME_WITH_SYS_TIME\r
+\r
+/* Define to 1 if your <sys/time.h> declares 'struct tm'. */\r
+#undef TM_IN_SYS_TIME\r
+\r
+/* Enable extensions on AIX 3, Interix. */\r
+#ifndef _ALL_SOURCE\r
+# undef _ALL_SOURCE\r
+#endif\r
+/* Enable GNU extensions on systems that have them. */\r
+#ifndef _GNU_SOURCE\r
+# undef _GNU_SOURCE\r
+#endif\r
+/* Enable threading extensions on Solaris. */\r
+#ifndef _POSIX_PTHREAD_SEMANTICS\r
+# undef _POSIX_PTHREAD_SEMANTICS\r
+#endif\r
+/* Enable extensions on HP NonStop. */\r
+#ifndef _TANDEM_SOURCE\r
+# undef _TANDEM_SOURCE\r
+#endif\r
+/* Enable general extensions on Solaris. */\r
+#ifndef __EXTENSIONS__\r
+# undef __EXTENSIONS__\r
+#endif\r
+\r
+\r
+/* Define if you want to use MacPython modules on MacOSX in unix-Python. */\r
+#undef USE_TOOLBOX_OBJECT_GLUE\r
+\r
+/* Define if a va_list is an array of some kind */\r
+#undef VA_LIST_IS_ARRAY\r
+\r
+/* Define if you want SIGFPE handled (see Include/pyfpe.h). */\r
+#undef WANT_SIGFPE_HANDLER\r
+\r
+/* Define if you want wctype.h functions to be used instead of the one\r
+ supplied by Python itself. (see Include/unicodectype.h). */\r
+#define WANT_WCTYPE_FUNCTIONS 1\r
+\r
+/* Define if WINDOW in curses.h offers a field _flags. */\r
+#undef WINDOW_HAS_FLAGS\r
+\r
+/* Define if you want documentation strings in extension modules */\r
+#undef WITH_DOC_STRINGS\r
+\r
+/* Define if you want to use the new-style (Openstep, Rhapsody, MacOS) dynamic\r
+ linker (dyld) instead of the old-style (NextStep) dynamic linker (rld).\r
+ Dyld is necessary to support frameworks. */\r
+#undef WITH_DYLD\r
+\r
+/* Define to 1 if libintl is needed for locale functions. */\r
+#undef WITH_LIBINTL\r
+\r
+/* Define if you want to produce an OpenStep/Rhapsody framework (shared\r
+ library plus accessory files). */\r
+#undef WITH_NEXT_FRAMEWORK\r
+\r
+/* Define if you want to compile in Python-specific mallocs */\r
+#undef WITH_PYMALLOC\r
+\r
+/* Define if you want to compile in rudimentary thread support */\r
+#undef WITH_THREAD\r
+\r
+/* Define to profile with the Pentium timestamp counter */\r
+#undef WITH_TSC\r
+\r
+/* Define if you want pymalloc to be disabled when running under valgrind */\r
+#undef WITH_VALGRIND\r
+\r
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most\r
+ significant byte first (like Motorola and SPARC, unlike Intel). */\r
+#if defined AC_APPLE_UNIVERSAL_BUILD\r
+# if defined __BIG_ENDIAN__\r
+# define WORDS_BIGENDIAN 1\r
+# endif\r
+#else\r
+# ifndef WORDS_BIGENDIAN\r
+# undef WORDS_BIGENDIAN\r
+# endif\r
+#endif\r
+\r
+/* Define if arithmetic is subject to x87-style double rounding issue */\r
+#undef X87_DOUBLE_ROUNDING\r
+\r
+/* Define on OpenBSD to activate all library features */\r
+#undef _BSD_SOURCE\r
+\r
+/* Define on Irix to enable u_int */\r
+#undef _BSD_TYPES\r
+\r
+/* Define on Darwin to activate all library features */\r
+#undef _DARWIN_C_SOURCE\r
+\r
+/* This must be set to 64 on some systems to enable large file support. */\r
+#undef _FILE_OFFSET_BITS\r
+\r
+/* Define on Linux to activate all library features */\r
+#undef _GNU_SOURCE\r
+\r
+/* This must be defined on some systems to enable large file support. */\r
+#undef _LARGEFILE_SOURCE\r
+\r
+/* Define to 1 if on MINIX. */\r
+#undef _MINIX\r
+\r
+/* Define on NetBSD to activate all library features */\r
+#ifndef _NETBSD_SOURCE\r
+ #define _NETBSD_SOURCE 1\r
+#endif\r
+\r
+/* Define _OSF_SOURCE to get the makedev macro. */\r
+#undef _OSF_SOURCE\r
+\r
+/* Define to 2 if the system does not provide POSIX.1 features except with\r
+ this defined. */\r
+#undef _POSIX_1_SOURCE\r
+\r
+/* Define to activate features from IEEE Stds 1003.1-2001 */\r
+#undef _POSIX_C_SOURCE\r
+\r
+/* Define to 1 if you need to in order for 'stat' and other things to work. */\r
+#undef _POSIX_SOURCE\r
+\r
+/* Define if you have POSIX threads, and your system does not define that. */\r
+#undef _POSIX_THREADS\r
+\r
+/* Define to force use of thread-safe errno, h_errno, and other functions */\r
+#undef _REENTRANT\r
+\r
+/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,\r
+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the\r
+ #define below would cause a syntax error. */\r
+#undef _UINT32_T\r
+\r
+/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,\r
+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the\r
+ #define below would cause a syntax error. */\r
+#undef _UINT64_T\r
+\r
+/* Define to the level of X/Open that your system supports */\r
+#undef _XOPEN_SOURCE\r
+\r
+/* Define to activate Unix95-and-earlier features */\r
+#undef _XOPEN_SOURCE_EXTENDED\r
+\r
+/* Define on FreeBSD to activate all library features */\r
+#undef __BSD_VISIBLE\r
+\r
+/* Define to 1 if type 'char' is unsigned and you are not using gcc. */\r
+#ifndef __CHAR_UNSIGNED__\r
+# undef __CHAR_UNSIGNED__\r
+#endif\r
+\r
+/* Defined on Solaris to see additional function prototypes. */\r
+#undef __EXTENSIONS__\r
+\r
+/* Define to 'long' if <time.h> doesn't define. */\r
+//#undef clock_t\r
+\r
+/* Define to empty if 'const' does not conform to ANSI C. */\r
+//#undef const\r
+\r
+/* Define to 'int' if <sys/types.h> doesn't define. */\r
+//#undef gid_t\r
+\r
+/* Define to the type of a signed integer type of width exactly 32 bits if\r
+ such a type exists and the standard includes do not define it. */\r
+//#undef int32_t\r
+\r
+/* Define to the type of a signed integer type of width exactly 64 bits if\r
+ such a type exists and the standard includes do not define it. */\r
+//#undef int64_t\r
+\r
+/* Define to 'int' if <sys/types.h> does not define. */\r
+//#undef mode_t\r
+\r
+/* Define to 'long int' if <sys/types.h> does not define. */\r
+//#undef off_t\r
+\r
+/* Define to 'int' if <sys/types.h> does not define. */\r
+//#undef pid_t\r
+\r
+/* Define to empty if the keyword does not work. */\r
+//#undef signed\r
+\r
+/* Define to 'unsigned int' if <sys/types.h> does not define. */\r
+//#undef size_t\r
+\r
+/* Define to 'int' if <sys/socket.h> does not define. */\r
+//#undef socklen_t\r
+\r
+/* Define to 'int' if <sys/types.h> doesn't define. */\r
+//#undef uid_t\r
+\r
+/* Define to the type of an unsigned integer type of width exactly 32 bits if\r
+ such a type exists and the standard includes do not define it. */\r
+//#undef uint32_t\r
+\r
+/* Define to the type of an unsigned integer type of width exactly 64 bits if\r
+ such a type exists and the standard includes do not define it. */\r
+//#undef uint64_t\r
+\r
+/* Define to empty if the keyword does not work. */\r
+//#undef volatile\r
+\r
+#endif /*Py_PYCONFIG_H*/\r
--- /dev/null
+ EDK II Python\r
+ ReadMe\r
+ Release 1.02\r
+ 18 Jan. 2013\r
+\r
+\r
+1. OVERVIEW\r
+===========\r
+This document is devoted to general information on building and setup of the\r
+Python environment for UEFI 2.3, the invocation of the interpreter, and things\r
+that make working with Python easier.\r
+\r
+It is assumed that you already have either UDK2010 or a current snapshot of\r
+the EDK II sources from www.tianocore.org, and that you can successfully build\r
+packages within that distribution.\r
+\r
+2. Release Notes\r
+================\r
+ 1) All C extension modules must be statically linked (built in)\r
+ 2) The site and os modules must exist as discrete files in ...\lib\python.27\r
+ 3) User-specific configurations are not supported.\r
+ 4) Environment variables are not supported.\r
+\r
+3. Getting and Building Python\r
+======================================================\r
+ 3.1 Getting Python\r
+ ==================\r
+ Currently only version 2.7.2 of the CPython distribution is supported. For development\r
+ ease, a subset of the Python 2.7.2 distribution has been included in the AppPkg source\r
+ tree. If a full distribution is desired, the Python-2.7.2 directory can be removed or\r
+ renamed and the full source code downloaded from http://www.python.org/ftp/python/2.7.2/.\r
+\r
+ A. Within your EDK II development tree, extract the Python distribution into\r
+ AppPkg/Applications/Python. This should create the\r
+ AppPkg/Applications/Python/Python-2.7.2 directory.\r
+\r
+ B. Copy the files from PyMod-2.7.2 into the corresponding directories within\r
+ the Python-2.7.2 tree. This will overwrite existing files with files\r
+ modified for UEFI usage.\r
+\r
+ 3.2 Building Python\r
+ ===================\r
+ A. Edit Efi/config.c to enable the built-in modules you need.\r
+ Mandatory Built-in Modules:\r
+ edk2 errno imp marshal\r
+\r
+ Additional built-in modules which are required to use the help()\r
+ functionality provided by PyDoc, are:\r
+ _codecs _collections _functools _random\r
+ _sre _struct _weakref binascii\r
+ cStringIO gc itertools math\r
+ operator time\r
+\r
+ B. Edit AppPkg/AppPkg.dsc to enable (uncomment) the PythonCore.inf line\r
+ within the [Components] section.\r
+\r
+ C. Build AppPkg, which includes Python, using the standard "build" command:\r
+ For example, to build Python for an X64 CPU architecture:\r
+ build -a X64 -p AppPkg\AppPkg.dsc\r
+\r
+4. Python-related paths and files\r
+=================================\r
+Python depends upon the existence of several directories and files on the\r
+target system.\r
+\r
+ \EFI Root of the UEFI system area.\r
+ |- \Tools Location of the Python.efi executable.\r
+ |- \Boot UEFI specified Boot directory.\r
+ |- \StdLib Root of the Standard Libraries sub-tree.\r
+ |- \etc Configuration files used by libraries.\r
+ |- \tmp Temporary files created by tmpfile(), etc.\r
+ |- \lib Root of the libraries tree.\r
+ |- \python.27 Directory containing the Python library modules.\r
+ |- \lib-dynload Dynamically loadable Python extensions.\r
+ |- \site-packages Site-specific packages and modules.\r
+\r
+\r
+5. Installing Python\r
+====================\r
+These directories, on the target system, are populated from the development\r
+system as follows:\r
+\r
+ * \Efi\Tools receives a copy of Build/AppPkg/DEBUG_VS2005/X64/Python.efi.\r
+ ^^^^^ ^^^^^^\r
+ Modify the host path to match the your build type and compiler.\r
+\r
+ * The \Efi\StdLib\etc directory is populated from the StdLib/Efi/StdLib/etc\r
+ source directory.\r
+\r
+ * Directory \Efi\StdLib\lib\python.27 is populated with packages and modules\r
+ from the AppPkg/Applications/Python/Python-2.7.2/Lib directory.\r
+ The recommended minimum set of modules (.py, .pyc, and/or .pyo):\r
+ os stat ntpath warnings traceback\r
+ site types copy_reg linecache genericpath\r
+\r
+ * Python C Extension Modules built as dynamically loadable extensions go into\r
+ the \Efi\StdLib\lib\python.27\lib-dynload directory. This functionality is not\r
+ yet implemented.\r
+\r
+\r
+6. Example: Enabling socket support\r
+===================================\r
+ 1. enable {"_socket", init_socket}, in Efi\config.c\r
+ 2. enable Python-2.7.2/Modules/socketmodule.c in PythonCore.inf.\r
+ 3. copy socket.py over to /Efi/StdLib/lib/python.27 on your target system.\r
+ 4. Make sure dependent modules are present(.py) or built in(.c):\r
+ functools, types, os, sys, warnings, cStringIO, StringIO, errno\r
+\r
+ 5. build -a X64 -p AppPkg\AppPkg.dsc\r
+ 6. copy Build\AppPkg\DEBUG_VS2005\X64\Python.efi to \Efi\Tools on your target system.\r
+ ^^^^ Modify as needed\r
+\r
+\r
+7. Supported C Modules\r
+======================\r
+ Module Name C File(s)\r
+ =============== =============================================\r
+ _ast Python/Python-ast.c\r
+ _bisect Modules/_bisectmodule.c\r
+ _codecs Modules/_codecsmodule.c\r
+ _codecs_cn Modules/cjkcodecs/_codecs_cn.c\r
+ _codecs_hk Modules/cjkcodecs/_codecs_hk.c\r
+ _codecs_iso2022 Modules/cjkcodecs/_codecs_iso2022.c\r
+ _codecs_jp Modules/cjkcodecs/_codecs_jp\r
+ _codecs_kr Modules/cjkcodecs/_codecs_kr\r
+ _codecs_tw Modules/cjkcodecs/_codecs_tw\r
+ _collections Modules/_collectionsmodule.c\r
+ _csv Modules/_csv.c\r
+ _functools Modules/_functoolsmodule.c\r
+ _heapq Modules/_heapqmodule.c\r
+ _io Modules/_io/_iomodule.c Modules/_io/*\r
+ _json Modules/_json.c\r
+ _md5 Modules/md5module.c Modules/md5.c\r
+ _multibytecodec Modules/cjkcodecs/_multibytecodec.c\r
+ _random Modules/_randommodule.c\r
+ _sha Modules/shamodule.c\r
+ _sha256 Modules/sha256module.c\r
+ _sha512 Modules/sha512module.c\r
+ _socket Modules/socketmodule.c\r
+ _sre Modules/_sre.c\r
+ _struct Modules/_struct.c\r
+ _symtable Modules/symtablemodule.c\r
+ _weakref Modules/_weakref.c\r
+ array Modules/arraymodule.c\r
+ binascii Modules/binascii.c\r
+ cmath Modules/cmathmodule.c\r
+ cPickle Modules/cPickle.c\r
+ cStringIO Modules/cStringIO.c\r
+ datetime Modules/datetimemodule.c\r
+ edk2 Modules/Efi/edk2module.c\r
+ errno Modules/errnomodule.c\r
+ future_builtins Modules/future_builtins.c\r
+ gc Modules/gcmodule.c\r
+ imp Python/import.c\r
+ itertools Modules/itertoolsmodule.c\r
+ marshal Python/marshal.c\r
+ math Modules/mathmodule.c Modules/_math.c\r
+ operator Modules/operator.c\r
+ parser Modules/parsermodule.c\r
+ select Modules/selectmodule.c\r
+ signal Modules/signalmodule.c\r
+ strop Modules/stropmodule.c\r
+ time Modules/timemodule.c\r
+ xxsubtype Modules/xxsubtype.c\r
+ zipimport Modules/zipimport.c\r
+ zlib Modules/zlibmodule.c Modules/zlib/*\r
+\r
+\r
+8. Tested Python Library Modules\r
+================================\r
+This is a partial list of the packages and modules of the Python Standard\r
+Library that have been tested or used in some manner.\r
+\r
+ encodings genericpath.py sha.py\r
+ importlib getopt.py SimpleHTTPServer.py\r
+ json hashlib.py site.py\r
+ pydoc_data heapq.py socket.py\r
+ xml HTMLParser.py SocketServer.py\r
+ abc.py inspect.py sre.py\r
+ argparse.py io.py sre_compile.py\r
+ ast.py keyword.py sre_constants.py\r
+ atexit.py linecache.py sre_parse.py\r
+ BaseHTTPServer.py locale.py stat.py\r
+ binhex.py md5.py string.py\r
+ bisect.py modulefinder.py StringIO.py\r
+ calendar.py ntpath.py struct.py\r
+ cmd.py numbers.py textwrap.py\r
+ codecs.py optparse.py token.py\r
+ collections.py os.py tokenize.py\r
+ copy.py platform.py traceback.py\r
+ copy_reg.py posixpath.py types.py\r
+ csv.py pydoc.py warnings.py\r
+ dummy_thread.py random.py weakref.py\r
+ fileinput.py re.py xmllib.py\r
+ formatter.py repr.py zipfile.py\r
+ functools.py runpy.py expat\r
+\r
+# # #\r
--- /dev/null
+/** @file\r
+ File object interface\r
+\r
+ Copyright (c) 2015, Daryl McDaniel. All rights reserved.<BR>\r
+ Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials are licensed and made available under\r
+ the terms and conditions of the BSD License that accompanies this distribution.\r
+ The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+**/\r
+\r
+#ifndef Py_FILEOBJECT_H\r
+#define Py_FILEOBJECT_H\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+typedef struct {\r
+ PyObject_HEAD\r
+ FILE *f_fp;\r
+ PyObject *f_name;\r
+ PyObject *f_mode;\r
+ int (*f_close)(FILE *);\r
+ int f_softspace; /* Flag used by 'print' command */\r
+ int f_binary; /* Flag which indicates whether the file is\r
+ open in binary (1) or text (0) mode */\r
+ char* f_buf; /* Allocated readahead buffer */\r
+ char* f_bufend; /* Points after last occupied position */\r
+ char* f_bufptr; /* Current buffer position */\r
+ char *f_setbuf; /* Buffer for setbuf(3) and setvbuf(3) */\r
+ int f_univ_newline; /* Handle any newline convention */\r
+ int f_newlinetypes; /* Types of newlines seen */\r
+ int f_skipnextlf; /* Skip next \n */\r
+ PyObject *f_encoding;\r
+ PyObject *f_errors;\r
+ PyObject *weakreflist; /* List of weak references */\r
+ int unlocked_count; /* Num. currently running sections of code\r
+ using f_fp with the GIL released. */\r
+ int readable;\r
+ int writable;\r
+} PyFileObject;\r
+\r
+PyAPI_DATA(PyTypeObject) PyFile_Type;\r
+\r
+#define PyFile_Check(op) PyObject_TypeCheck(op, &PyFile_Type)\r
+#define PyFile_CheckExact(op) (Py_TYPE(op) == &PyFile_Type)\r
+\r
+PyAPI_FUNC(PyObject *) PyFile_FromString(char *, char *);\r
+PyAPI_FUNC(void) PyFile_SetBufSize(PyObject *, int);\r
+PyAPI_FUNC(int) PyFile_SetEncoding(PyObject *, const char *);\r
+PyAPI_FUNC(int) PyFile_SetEncodingAndErrors(PyObject *, const char *, char *errors);\r
+PyAPI_FUNC(PyObject *) PyFile_FromFile(FILE *, char *, char *,\r
+ int (*)(FILE *));\r
+PyAPI_FUNC(FILE *) PyFile_AsFile(PyObject *);\r
+PyAPI_FUNC(void) PyFile_IncUseCount(PyFileObject *);\r
+PyAPI_FUNC(void) PyFile_DecUseCount(PyFileObject *);\r
+PyAPI_FUNC(PyObject *) PyFile_Name(PyObject *);\r
+PyAPI_FUNC(PyObject *) PyFile_GetLine(PyObject *, int);\r
+PyAPI_FUNC(int) PyFile_WriteObject(PyObject *, PyObject *, int);\r
+PyAPI_FUNC(int) PyFile_SoftSpace(PyObject *, int);\r
+PyAPI_FUNC(int) PyFile_WriteString(const char *, PyObject *);\r
+PyAPI_FUNC(int) PyObject_AsFileDescriptor(PyObject *);\r
+\r
+/* The default encoding used by the platform file system APIs\r
+ If non-NULL, this is different than the default encoding for strings\r
+*/\r
+PyAPI_DATA(const char *) Py_FileSystemDefaultEncoding;\r
+\r
+/* Routines to replace fread() and fgets() which accept any of \r, \n\r
+ or \r\n as line terminators.\r
+*/\r
+#define PY_STDIOTEXTMODE "b"\r
+char *Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *);\r
+size_t Py_UniversalNewlineFread(char *, size_t, FILE *, PyObject *);\r
+\r
+/* A routine to do sanity checking on the file mode string. returns\r
+ non-zero on if an exception occurred\r
+*/\r
+int _PyFile_SanitizeMode(char *mode);\r
+\r
+//#if defined _MSC_VER && _MSC_VER >= 1400\r
+/* A routine to check if a file descriptor is valid on Windows. Returns 0\r
+ * and sets errno to EBADF if it isn't. This is to avoid Assertions\r
+ * from various functions in the Windows CRT beginning with\r
+ * Visual Studio 2005\r
+ */\r
+//int _PyVerify_fd(int fd);\r
+//#elif defined _MSC_VER && _MSC_VER >= 1200\r
+/* fdopen doesn't set errno EBADF and crashes for large fd on debug build */\r
+//#define _PyVerify_fd(fd) (_get_osfhandle(fd) >= 0)\r
+//#else\r
+#define _PyVerify_fd(A) (1) /* dummy */\r
+//#endif\r
+\r
+/* A routine to check if a file descriptor can be select()-ed. */\r
+#ifdef HAVE_SELECT\r
+ #define _PyIsSelectable_fd(FD) (((FD) >= 0) && ((FD) < FD_SETSIZE))\r
+#else\r
+ #define _PyIsSelectable_fd(FD) (1)\r
+#endif /* HAVE_SELECT */\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+#endif /* !Py_FILEOBJECT_H */\r
--- /dev/null
+/** @file\r
+ Operating system dependencies.\r
+\r
+ Copyright (c) 2015, Daryl McDaniel. All rights reserved.<BR>\r
+ Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials are licensed and made available under\r
+ the terms and conditions of the BSD License that accompanies this distribution.\r
+ The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+**/\r
+\r
+#ifndef Py_OSDEFS_H\r
+#define Py_OSDEFS_H\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+\r
+/* Mod by chrish: QNX has WATCOM, but isn't DOS */\r
+#if !defined(__QNX__) && !defined(UEFI_C_SOURCE)\r
+#if defined(MS_WINDOWS) || defined(__BORLANDC__) || defined(__WATCOMC__) || defined(__DJGPP__) || defined(PYOS_OS2)\r
+#if defined(PYOS_OS2) && defined(PYCC_GCC)\r
+#define MAXPATHLEN 260\r
+#define SEP '/'\r
+#define ALTSEP '\\'\r
+#else\r
+#define SEP '\\'\r
+#define ALTSEP '/'\r
+#define MAXPATHLEN 256\r
+#endif\r
+#define DELIM ';'\r
+#endif\r
+#endif\r
+\r
+#ifdef RISCOS\r
+#define SEP '.'\r
+#define MAXPATHLEN 256\r
+#define DELIM ','\r
+#endif\r
+\r
+\r
+/* Filename separator */\r
+#ifndef SEP\r
+#define SEP '/'\r
+#define ALTSEP '\\'\r
+#endif\r
+\r
+/* Max pathname length */\r
+#ifdef __hpux\r
+# include <sys/param.h>\r
+# include <limits.h>\r
+# ifndef PATH_MAX\r
+# define PATH_MAX MAXPATHLEN\r
+# endif\r
+#endif\r
+\r
+#ifndef MAXPATHLEN\r
+#if defined(PATH_MAX) && PATH_MAX > 1024\r
+#define MAXPATHLEN PATH_MAX\r
+#else\r
+#define MAXPATHLEN 1024\r
+#endif\r
+#endif\r
+\r
+/* Search path entry delimiter */\r
+#ifndef DELIM\r
+# ifdef UEFI_C_SOURCE\r
+# define DELIM ';'\r
+# define DELIM_STR ";"\r
+# else\r
+# define DELIM ':'\r
+# endif\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+#endif /* !Py_OSDEFS_H */\r
--- /dev/null
+/** @file\r
+ Symbols and macros to supply platform-independent interfaces to basic\r
+ C language & library operations whose spellings vary across platforms.\r
+\r
+ Copyright (c) 2015, Daryl McDaniel. All rights reserved.<BR>\r
+ Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials are licensed and made available under\r
+ the terms and conditions of the BSD License that accompanies this distribution.\r
+ The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+**/\r
+\r
+#ifndef Py_PYPORT_H\r
+#define Py_PYPORT_H\r
+\r
+#include "pyconfig.h" /* include for defines */\r
+\r
+/* Some versions of HP-UX & Solaris need inttypes.h for int32_t,\r
+ INT32_MAX, etc. */\r
+#ifdef HAVE_INTTYPES_H\r
+#include <inttypes.h>\r
+#endif\r
+\r
+#ifdef HAVE_STDINT_H\r
+#include <stdint.h>\r
+#endif\r
+\r
+/**************************************************************************\r
+Symbols and macros to supply platform-independent interfaces to basic\r
+C language & library operations whose spellings vary across platforms.\r
+\r
+Please try to make documentation here as clear as possible: by definition,\r
+the stuff here is trying to illuminate C's darkest corners.\r
+\r
+Config #defines referenced here:\r
+\r
+SIGNED_RIGHT_SHIFT_ZERO_FILLS\r
+Meaning: To be defined iff i>>j does not extend the sign bit when i is a\r
+ signed integral type and i < 0.\r
+Used in: Py_ARITHMETIC_RIGHT_SHIFT\r
+\r
+Py_DEBUG\r
+Meaning: Extra checks compiled in for debug mode.\r
+Used in: Py_SAFE_DOWNCAST\r
+\r
+HAVE_UINTPTR_T\r
+Meaning: The C9X type uintptr_t is supported by the compiler\r
+Used in: Py_uintptr_t\r
+\r
+HAVE_LONG_LONG\r
+Meaning: The compiler supports the C type "long long"\r
+Used in: PY_LONG_LONG\r
+\r
+**************************************************************************/\r
+\r
+\r
+/* For backward compatibility only. Obsolete, do not use. */\r
+#ifdef HAVE_PROTOTYPES\r
+#define Py_PROTO(x) x\r
+#else\r
+#define Py_PROTO(x) ()\r
+#endif\r
+#ifndef Py_FPROTO\r
+#define Py_FPROTO(x) Py_PROTO(x)\r
+#endif\r
+\r
+/* typedefs for some C9X-defined synonyms for integral types.\r
+ *\r
+ * The names in Python are exactly the same as the C9X names, except with a\r
+ * Py_ prefix. Until C9X is universally implemented, this is the only way\r
+ * to ensure that Python gets reliable names that don't conflict with names\r
+ * in non-Python code that are playing their own tricks to define the C9X\r
+ * names.\r
+ *\r
+ * NOTE: don't go nuts here! Python has no use for *most* of the C9X\r
+ * integral synonyms. Only define the ones we actually need.\r
+ */\r
+\r
+#ifdef HAVE_LONG_LONG\r
+#ifndef PY_LONG_LONG\r
+#define PY_LONG_LONG long long\r
+#if defined(LLONG_MAX)\r
+/* If LLONG_MAX is defined in limits.h, use that. */\r
+#define PY_LLONG_MIN LLONG_MIN\r
+#define PY_LLONG_MAX LLONG_MAX\r
+#define PY_ULLONG_MAX ULLONG_MAX\r
+#elif defined(__LONG_LONG_MAX__)\r
+/* Otherwise, if GCC has a builtin define, use that. */\r
+#define PY_LLONG_MAX __LONG_LONG_MAX__\r
+#define PY_LLONG_MIN (-PY_LLONG_MAX-1)\r
+#define PY_ULLONG_MAX (__LONG_LONG_MAX__*2ULL + 1ULL)\r
+#else\r
+/* Otherwise, rely on two's complement. */\r
+#define PY_ULLONG_MAX (~0ULL)\r
+#define PY_LLONG_MAX ((long long)(PY_ULLONG_MAX>>1))\r
+#define PY_LLONG_MIN (-PY_LLONG_MAX-1)\r
+#endif /* LLONG_MAX */\r
+#endif\r
+#endif /* HAVE_LONG_LONG */\r
+\r
+/* a build with 30-bit digits for Python long integers needs an exact-width\r
+ * 32-bit unsigned integer type to store those digits. (We could just use\r
+ * type 'unsigned long', but that would be wasteful on a system where longs\r
+ * are 64-bits.) On Unix systems, the autoconf macro AC_TYPE_UINT32_T defines\r
+ * uint32_t to be such a type unless stdint.h or inttypes.h defines uint32_t.\r
+ * However, it doesn't set HAVE_UINT32_T, so we do that here.\r
+ */\r
+#ifdef uint32_t\r
+#define HAVE_UINT32_T 1\r
+#endif\r
+\r
+#ifdef HAVE_UINT32_T\r
+#ifndef PY_UINT32_T\r
+#define PY_UINT32_T uint32_t\r
+#endif\r
+#endif\r
+\r
+/* Macros for a 64-bit unsigned integer type; used for type 'twodigits' in the\r
+ * long integer implementation, when 30-bit digits are enabled.\r
+ */\r
+#ifdef uint64_t\r
+#define HAVE_UINT64_T 1\r
+#endif\r
+\r
+#ifdef HAVE_UINT64_T\r
+#ifndef PY_UINT64_T\r
+#define PY_UINT64_T uint64_t\r
+#endif\r
+#endif\r
+\r
+/* Signed variants of the above */\r
+#ifdef int32_t\r
+#define HAVE_INT32_T 1\r
+#endif\r
+\r
+#ifdef HAVE_INT32_T\r
+#ifndef PY_INT32_T\r
+#define PY_INT32_T int32_t\r
+#endif\r
+#endif\r
+\r
+#ifdef int64_t\r
+#define HAVE_INT64_T 1\r
+#endif\r
+\r
+#ifdef HAVE_INT64_T\r
+#ifndef PY_INT64_T\r
+#define PY_INT64_T int64_t\r
+#endif\r
+#endif\r
+\r
+/* If PYLONG_BITS_IN_DIGIT is not defined then we'll use 30-bit digits if all\r
+ the necessary integer types are available, and we're on a 64-bit platform\r
+ (as determined by SIZEOF_VOID_P); otherwise we use 15-bit digits. */\r
+\r
+#ifndef PYLONG_BITS_IN_DIGIT\r
+#if (defined HAVE_UINT64_T && defined HAVE_INT64_T && \\r
+ defined HAVE_UINT32_T && defined HAVE_INT32_T && SIZEOF_VOID_P >= 8)\r
+#define PYLONG_BITS_IN_DIGIT 30\r
+#else\r
+#define PYLONG_BITS_IN_DIGIT 15\r
+#endif\r
+#endif\r
+\r
+/* uintptr_t is the C9X name for an unsigned integral type such that a\r
+ * legitimate void* can be cast to uintptr_t and then back to void* again\r
+ * without loss of information. Similarly for intptr_t, wrt a signed\r
+ * integral type.\r
+ */\r
+#ifdef HAVE_UINTPTR_T\r
+typedef uintptr_t Py_uintptr_t;\r
+typedef intptr_t Py_intptr_t;\r
+\r
+#elif SIZEOF_VOID_P <= SIZEOF_INT\r
+typedef unsigned int Py_uintptr_t;\r
+typedef int Py_intptr_t;\r
+\r
+#elif SIZEOF_VOID_P <= SIZEOF_LONG\r
+typedef unsigned long Py_uintptr_t;\r
+typedef long Py_intptr_t;\r
+\r
+#elif defined(HAVE_LONG_LONG) && (SIZEOF_VOID_P <= SIZEOF_LONG_LONG)\r
+typedef unsigned PY_LONG_LONG Py_uintptr_t;\r
+typedef PY_LONG_LONG Py_intptr_t;\r
+\r
+#else\r
+# error "Python needs a typedef for Py_uintptr_t in pyport.h."\r
+#endif /* HAVE_UINTPTR_T */\r
+\r
+/* Py_ssize_t is a signed integral type such that sizeof(Py_ssize_t) ==\r
+ * sizeof(size_t). C99 doesn't define such a thing directly (size_t is an\r
+ * unsigned integral type). See PEP 353 for details.\r
+ */\r
+#ifdef HAVE_SSIZE_T\r
+typedef ssize_t Py_ssize_t;\r
+#elif SIZEOF_VOID_P == SIZEOF_SIZE_T\r
+typedef Py_intptr_t Py_ssize_t;\r
+#else\r
+# error "Python needs a typedef for Py_ssize_t in pyport.h."\r
+#endif\r
+\r
+/* Largest possible value of size_t.\r
+ SIZE_MAX is part of C99, so it might be defined on some\r
+ platforms. If it is not defined, (size_t)-1 is a portable\r
+ definition for C89, due to the way signed->unsigned\r
+ conversion is defined. */\r
+#ifdef SIZE_MAX\r
+#define PY_SIZE_MAX SIZE_MAX\r
+#else\r
+#define PY_SIZE_MAX ((size_t)-1)\r
+#endif\r
+\r
+/* Largest positive value of type Py_ssize_t. */\r
+#define PY_SSIZE_T_MAX ((Py_ssize_t)(((size_t)-1)>>1))\r
+/* Smallest negative value of type Py_ssize_t. */\r
+#define PY_SSIZE_T_MIN (-PY_SSIZE_T_MAX-1)\r
+\r
+#if SIZEOF_PID_T > SIZEOF_LONG\r
+# error "Python doesn't support sizeof(pid_t) > sizeof(long)"\r
+#endif\r
+\r
+/* PY_FORMAT_SIZE_T is a platform-specific modifier for use in a printf\r
+ * format to convert an argument with the width of a size_t or Py_ssize_t.\r
+ * C99 introduced "z" for this purpose, but not all platforms support that;\r
+ * e.g., MS compilers use "I" instead.\r
+ *\r
+ * These "high level" Python format functions interpret "z" correctly on\r
+ * all platforms (Python interprets the format string itself, and does whatever\r
+ * the platform C requires to convert a size_t/Py_ssize_t argument):\r
+ *\r
+ * PyString_FromFormat\r
+ * PyErr_Format\r
+ * PyString_FromFormatV\r
+ *\r
+ * Lower-level uses require that you interpolate the correct format modifier\r
+ * yourself (e.g., calling printf, fprintf, sprintf, PyOS_snprintf); for\r
+ * example,\r
+ *\r
+ * Py_ssize_t index;\r
+ * fprintf(stderr, "index %" PY_FORMAT_SIZE_T "d sucks\n", index);\r
+ *\r
+ * That will expand to %ld, or %Id, or to something else correct for a\r
+ * Py_ssize_t on the platform.\r
+ */\r
+#ifndef PY_FORMAT_SIZE_T\r
+# if SIZEOF_SIZE_T == SIZEOF_INT && !defined(__APPLE__)\r
+# define PY_FORMAT_SIZE_T ""\r
+# elif SIZEOF_SIZE_T == SIZEOF_LONG\r
+# define PY_FORMAT_SIZE_T "l"\r
+# elif defined(MS_WINDOWS)\r
+# define PY_FORMAT_SIZE_T "I"\r
+# else\r
+# error "This platform's pyconfig.h needs to define PY_FORMAT_SIZE_T"\r
+# endif\r
+#endif\r
+\r
+/* PY_FORMAT_LONG_LONG is analogous to PY_FORMAT_SIZE_T above, but for\r
+ * the long long type instead of the size_t type. It's only available\r
+ * when HAVE_LONG_LONG is defined. The "high level" Python format\r
+ * functions listed above will interpret "lld" or "llu" correctly on\r
+ * all platforms.\r
+ */\r
+#ifdef HAVE_LONG_LONG\r
+# ifndef PY_FORMAT_LONG_LONG\r
+# if defined(MS_WIN64) || defined(MS_WINDOWS)\r
+# define PY_FORMAT_LONG_LONG "I64"\r
+# else\r
+# error "This platform's pyconfig.h needs to define PY_FORMAT_LONG_LONG"\r
+# endif\r
+# endif\r
+#endif\r
+\r
+/* Py_LOCAL can be used instead of static to get the fastest possible calling\r
+ * convention for functions that are local to a given module.\r
+ *\r
+ * Py_LOCAL_INLINE does the same thing, and also explicitly requests inlining,\r
+ * for platforms that support that.\r
+ *\r
+ * If PY_LOCAL_AGGRESSIVE is defined before python.h is included, more\r
+ * "aggressive" inlining/optimizaion is enabled for the entire module. This\r
+ * may lead to code bloat, and may slow things down for those reasons. It may\r
+ * also lead to errors, if the code relies on pointer aliasing. Use with\r
+ * care.\r
+ *\r
+ * NOTE: You can only use this for functions that are entirely local to a\r
+ * module; functions that are exported via method tables, callbacks, etc,\r
+ * should keep using static.\r
+ */\r
+\r
+#undef USE_INLINE /* XXX - set via configure? */\r
+\r
+#if defined(_MSC_VER)\r
+#if defined(PY_LOCAL_AGGRESSIVE)\r
+/* enable more aggressive optimization for visual studio */\r
+//#pragma optimize("agtw", on)\r
+#pragma optimize("gt", on) // a and w are not legal for VS2005\r
+#endif\r
+/* ignore warnings if the compiler decides not to inline a function */\r
+#pragma warning(disable: 4710)\r
+/* fastest possible local call under MSVC */\r
+#define Py_LOCAL(type) static type __fastcall\r
+#define Py_LOCAL_INLINE(type) static __inline type __fastcall\r
+#elif defined(USE_INLINE)\r
+#define Py_LOCAL(type) static type\r
+#define Py_LOCAL_INLINE(type) static inline type\r
+#else\r
+#define Py_LOCAL(type) static type\r
+#define Py_LOCAL_INLINE(type) static type\r
+#endif\r
+\r
+/* Py_MEMCPY can be used instead of memcpy in cases where the copied blocks\r
+ * are often very short. While most platforms have highly optimized code for\r
+ * large transfers, the setup costs for memcpy are often quite high. MEMCPY\r
+ * solves this by doing short copies "in line".\r
+ */\r
+\r
+#if defined(_MSC_VER)\r
+#define Py_MEMCPY(target, source, length) do { \\r
+ size_t i_, n_ = (length); \\r
+ char *t_ = (void*) (target); \\r
+ const char *s_ = (void*) (source); \\r
+ if (n_ >= 16) \\r
+ memcpy(t_, s_, n_); \\r
+ else \\r
+ for (i_ = 0; i_ < n_; i_++) \\r
+ t_[i_] = s_[i_]; \\r
+ } while (0)\r
+#else\r
+#define Py_MEMCPY memcpy\r
+#endif\r
+\r
+#include <stdlib.h>\r
+\r
+#ifdef HAVE_IEEEFP_H\r
+#include <ieeefp.h> /* needed for 'finite' declaration on some platforms */\r
+#endif\r
+\r
+#include <math.h> /* Moved here from the math section, before extern "C" */\r
+\r
+/********************************************\r
+ * WRAPPER FOR <time.h> and/or <sys/time.h> *\r
+ ********************************************/\r
+\r
+#ifdef TIME_WITH_SYS_TIME\r
+#include <sys/time.h>\r
+#include <time.h>\r
+#else /* !TIME_WITH_SYS_TIME */\r
+#ifdef HAVE_SYS_TIME_H\r
+#include <sys/time.h>\r
+#else /* !HAVE_SYS_TIME_H */\r
+#include <time.h>\r
+#endif /* !HAVE_SYS_TIME_H */\r
+#endif /* !TIME_WITH_SYS_TIME */\r
+\r
+\r
+/******************************\r
+ * WRAPPER FOR <sys/select.h> *\r
+ ******************************/\r
+\r
+/* NB caller must include <sys/types.h> */\r
+\r
+#ifdef HAVE_SYS_SELECT_H\r
+\r
+#include <sys/select.h>\r
+\r
+#endif /* !HAVE_SYS_SELECT_H */\r
+\r
+/*******************************\r
+ * stat() and fstat() fiddling *\r
+ *******************************/\r
+\r
+/* We expect that stat and fstat exist on most systems.\r
+ * It's confirmed on Unix, Mac and Windows.\r
+ * If you don't have them, add\r
+ * #define DONT_HAVE_STAT\r
+ * and/or\r
+ * #define DONT_HAVE_FSTAT\r
+ * to your pyconfig.h. Python code beyond this should check HAVE_STAT and\r
+ * HAVE_FSTAT instead.\r
+ * Also\r
+ * #define HAVE_SYS_STAT_H\r
+ * if <sys/stat.h> exists on your platform, and\r
+ * #define HAVE_STAT_H\r
+ * if <stat.h> does.\r
+ */\r
+#ifndef DONT_HAVE_STAT\r
+#define HAVE_STAT\r
+#endif\r
+\r
+#ifndef DONT_HAVE_FSTAT\r
+#define HAVE_FSTAT\r
+#endif\r
+\r
+#ifdef RISCOS\r
+#include <sys/types.h>\r
+#include "unixstuff.h"\r
+#endif\r
+\r
+#ifdef HAVE_SYS_STAT_H\r
+#if defined(PYOS_OS2) && defined(PYCC_GCC)\r
+#include <sys/types.h>\r
+#endif\r
+#include <sys/stat.h>\r
+#elif defined(HAVE_STAT_H)\r
+#include <stat.h>\r
+#endif\r
+\r
+#if defined(PYCC_VACPP)\r
+/* VisualAge C/C++ Failed to Define MountType Field in sys/stat.h */\r
+#define S_IFMT (S_IFDIR|S_IFCHR|S_IFREG)\r
+#endif\r
+\r
+#ifndef S_ISREG\r
+#define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)\r
+#endif\r
+\r
+#ifndef S_ISDIR\r
+#define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR)\r
+#endif\r
+\r
+\r
+#ifdef __cplusplus\r
+/* Move this down here since some C++ #include's don't like to be included\r
+ inside an extern "C" */\r
+extern "C" {\r
+#endif\r
+\r
+\r
+/* Py_ARITHMETIC_RIGHT_SHIFT\r
+ * C doesn't define whether a right-shift of a signed integer sign-extends\r
+ * or zero-fills. Here a macro to force sign extension:\r
+ * Py_ARITHMETIC_RIGHT_SHIFT(TYPE, I, J)\r
+ * Return I >> J, forcing sign extension. Arithmetically, return the\r
+ * floor of I/2**J.\r
+ * Requirements:\r
+ * I should have signed integer type. In the terminology of C99, this can\r
+ * be either one of the five standard signed integer types (signed char,\r
+ * short, int, long, long long) or an extended signed integer type.\r
+ * J is an integer >= 0 and strictly less than the number of bits in the\r
+ * type of I (because C doesn't define what happens for J outside that\r
+ * range either).\r
+ * TYPE used to specify the type of I, but is now ignored. It's been left\r
+ * in for backwards compatibility with versions <= 2.6 or 3.0.\r
+ * Caution:\r
+ * I may be evaluated more than once.\r
+ */\r
+#ifdef SIGNED_RIGHT_SHIFT_ZERO_FILLS\r
+#define Py_ARITHMETIC_RIGHT_SHIFT(TYPE, I, J) \\r
+ ((I) < 0 ? -1-((-1-(I)) >> (J)) : (I) >> (J))\r
+#else\r
+#define Py_ARITHMETIC_RIGHT_SHIFT(TYPE, I, J) ((I) >> (J))\r
+#endif\r
+\r
+/* Py_FORCE_EXPANSION(X)\r
+ * "Simply" returns its argument. However, macro expansions within the\r
+ * argument are evaluated. This unfortunate trickery is needed to get\r
+ * token-pasting to work as desired in some cases.\r
+ */\r
+#define Py_FORCE_EXPANSION(X) X\r
+\r
+/* Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW)\r
+ * Cast VALUE to type NARROW from type WIDE. In Py_DEBUG mode, this\r
+ * assert-fails if any information is lost.\r
+ * Caution:\r
+ * VALUE may be evaluated more than once.\r
+ */\r
+#ifdef Py_DEBUG\r
+#define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) \\r
+ (assert((WIDE)(NARROW)(VALUE) == (VALUE)), (NARROW)(VALUE))\r
+#else\r
+#define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) (NARROW)(VALUE)\r
+#endif\r
+\r
+/* Py_SET_ERRNO_ON_MATH_ERROR(x)\r
+ * If a libm function did not set errno, but it looks like the result\r
+ * overflowed or not-a-number, set errno to ERANGE or EDOM. Set errno\r
+ * to 0 before calling a libm function, and invoke this macro after,\r
+ * passing the function result.\r
+ * Caution:\r
+ * This isn't reliable. See Py_OVERFLOWED comments.\r
+ * X is evaluated more than once.\r
+ */\r
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || (defined(__hpux) && defined(__ia64))\r
+#define _Py_SET_EDOM_FOR_NAN(X) if (isnan(X)) errno = EDOM;\r
+#else\r
+#define _Py_SET_EDOM_FOR_NAN(X) ;\r
+#endif\r
+#define Py_SET_ERRNO_ON_MATH_ERROR(X) \\r
+ do { \\r
+ if (errno == 0) { \\r
+ if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL) \\r
+ errno = ERANGE; \\r
+ else _Py_SET_EDOM_FOR_NAN(X) \\r
+ } \\r
+ } while(0)\r
+\r
+/* Py_SET_ERANGE_ON_OVERFLOW(x)\r
+ * An alias of Py_SET_ERRNO_ON_MATH_ERROR for backward-compatibility.\r
+ */\r
+#define Py_SET_ERANGE_IF_OVERFLOW(X) Py_SET_ERRNO_ON_MATH_ERROR(X)\r
+\r
+/* Py_ADJUST_ERANGE1(x)\r
+ * Py_ADJUST_ERANGE2(x, y)\r
+ * Set errno to 0 before calling a libm function, and invoke one of these\r
+ * macros after, passing the function result(s) (Py_ADJUST_ERANGE2 is useful\r
+ * for functions returning complex results). This makes two kinds of\r
+ * adjustments to errno: (A) If it looks like the platform libm set\r
+ * errno=ERANGE due to underflow, clear errno. (B) If it looks like the\r
+ * platform libm overflowed but didn't set errno, force errno to ERANGE. In\r
+ * effect, we're trying to force a useful implementation of C89 errno\r
+ * behavior.\r
+ * Caution:\r
+ * This isn't reliable. See Py_OVERFLOWED comments.\r
+ * X and Y may be evaluated more than once.\r
+ */\r
+#define Py_ADJUST_ERANGE1(X) \\r
+ do { \\r
+ if (errno == 0) { \\r
+ if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL) \\r
+ errno = ERANGE; \\r
+ } \\r
+ else if (errno == ERANGE && (X) == 0.0) \\r
+ errno = 0; \\r
+ } while(0)\r
+\r
+#define Py_ADJUST_ERANGE2(X, Y) \\r
+ do { \\r
+ if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL || \\r
+ (Y) == Py_HUGE_VAL || (Y) == -Py_HUGE_VAL) { \\r
+ if (errno == 0) \\r
+ errno = ERANGE; \\r
+ } \\r
+ else if (errno == ERANGE) \\r
+ errno = 0; \\r
+ } while(0)\r
+\r
+/* The functions _Py_dg_strtod and _Py_dg_dtoa in Python/dtoa.c (which are\r
+ * required to support the short float repr introduced in Python 3.1) require\r
+ * that the floating-point unit that's being used for arithmetic operations\r
+ * on C doubles is set to use 53-bit precision. It also requires that the\r
+ * FPU rounding mode is round-half-to-even, but that's less often an issue.\r
+ *\r
+ * If your FPU isn't already set to 53-bit precision/round-half-to-even, and\r
+ * you want to make use of _Py_dg_strtod and _Py_dg_dtoa, then you should\r
+ *\r
+ * #define HAVE_PY_SET_53BIT_PRECISION 1\r
+ *\r
+ * and also give appropriate definitions for the following three macros:\r
+ *\r
+ * _PY_SET_53BIT_PRECISION_START : store original FPU settings, and\r
+ * set FPU to 53-bit precision/round-half-to-even\r
+ * _PY_SET_53BIT_PRECISION_END : restore original FPU settings\r
+ * _PY_SET_53BIT_PRECISION_HEADER : any variable declarations needed to\r
+ * use the two macros above.\r
+ *\r
+ * The macros are designed to be used within a single C function: see\r
+ * Python/pystrtod.c for an example of their use.\r
+ */\r
+\r
+/* get and set x87 control word for gcc/x86 */\r
+#ifdef HAVE_GCC_ASM_FOR_X87\r
+#define HAVE_PY_SET_53BIT_PRECISION 1\r
+/* _Py_get/set_387controlword functions are defined in Python/pymath.c */\r
+#define _Py_SET_53BIT_PRECISION_HEADER \\r
+ unsigned short old_387controlword, new_387controlword\r
+#define _Py_SET_53BIT_PRECISION_START \\r
+ do { \\r
+ old_387controlword = _Py_get_387controlword(); \\r
+ new_387controlword = (old_387controlword & ~0x0f00) | 0x0200; \\r
+ if (new_387controlword != old_387controlword) \\r
+ _Py_set_387controlword(new_387controlword); \\r
+ } while (0)\r
+#define _Py_SET_53BIT_PRECISION_END \\r
+ if (new_387controlword != old_387controlword) \\r
+ _Py_set_387controlword(old_387controlword)\r
+#endif\r
+\r
+/* get and set x87 control word for VisualStudio/x86 */\r
+#if defined(_MSC_VER) && !defined(_WIN64) && !defined(UEFI_C_SOURCE) /* x87 not supported in 64-bit */\r
+#define HAVE_PY_SET_53BIT_PRECISION 1\r
+#define _Py_SET_53BIT_PRECISION_HEADER \\r
+ unsigned int old_387controlword, new_387controlword, out_387controlword\r
+/* We use the __control87_2 function to set only the x87 control word.\r
+ The SSE control word is unaffected. */\r
+#define _Py_SET_53BIT_PRECISION_START \\r
+ do { \\r
+ __control87_2(0, 0, &old_387controlword, NULL); \\r
+ new_387controlword = \\r
+ (old_387controlword & ~(_MCW_PC | _MCW_RC)) | (_PC_53 | _RC_NEAR); \\r
+ if (new_387controlword != old_387controlword) \\r
+ __control87_2(new_387controlword, _MCW_PC | _MCW_RC, \\r
+ &out_387controlword, NULL); \\r
+ } while (0)\r
+#define _Py_SET_53BIT_PRECISION_END \\r
+ do { \\r
+ if (new_387controlword != old_387controlword) \\r
+ __control87_2(old_387controlword, _MCW_PC | _MCW_RC, \\r
+ &out_387controlword, NULL); \\r
+ } while (0)\r
+#endif\r
+\r
+/* default definitions are empty */\r
+#ifndef HAVE_PY_SET_53BIT_PRECISION\r
+#define _Py_SET_53BIT_PRECISION_HEADER\r
+#define _Py_SET_53BIT_PRECISION_START\r
+#define _Py_SET_53BIT_PRECISION_END\r
+#endif\r
+\r
+/* If we can't guarantee 53-bit precision, don't use the code\r
+ in Python/dtoa.c, but fall back to standard code. This\r
+ means that repr of a float will be long (17 sig digits).\r
+\r
+ Realistically, there are two things that could go wrong:\r
+\r
+ (1) doubles aren't IEEE 754 doubles, or\r
+ (2) we're on x86 with the rounding precision set to 64-bits\r
+ (extended precision), and we don't know how to change\r
+ the rounding precision.\r
+ */\r
+\r
+#if !defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754) && \\r
+ !defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) && \\r
+ !defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754)\r
+#define PY_NO_SHORT_FLOAT_REPR\r
+#endif\r
+\r
+/* double rounding is symptomatic of use of extended precision on x86. If\r
+ we're seeing double rounding, and we don't have any mechanism available for\r
+ changing the FPU rounding precision, then don't use Python/dtoa.c. */\r
+#if defined(X87_DOUBLE_ROUNDING) && !defined(HAVE_PY_SET_53BIT_PRECISION)\r
+#define PY_NO_SHORT_FLOAT_REPR\r
+#endif\r
+\r
+/* Py_DEPRECATED(version)\r
+ * Declare a variable, type, or function deprecated.\r
+ * Usage:\r
+ * extern int old_var Py_DEPRECATED(2.3);\r
+ * typedef int T1 Py_DEPRECATED(2.4);\r
+ * extern int x() Py_DEPRECATED(2.5);\r
+ */\r
+#if defined(__GNUC__) && ((__GNUC__ >= 4) || \\r
+ (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))\r
+#define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))\r
+#else\r
+#define Py_DEPRECATED(VERSION_UNUSED)\r
+#endif\r
+\r
+/**************************************************************************\r
+Prototypes that are missing from the standard include files on some systems\r
+(and possibly only some versions of such systems.)\r
+\r
+Please be conservative with adding new ones, document them and enclose them\r
+in platform-specific #ifdefs.\r
+**************************************************************************/\r
+\r
+#ifdef SOLARIS\r
+/* Unchecked */\r
+extern int gethostname(char *, int);\r
+#endif\r
+\r
+#ifdef __BEOS__\r
+/* Unchecked */\r
+/* It's in the libs, but not the headers... - [cjh] */\r
+int shutdown( int, int );\r
+#endif\r
+\r
+#ifdef HAVE__GETPTY\r
+#include <sys/types.h> /* we need to import mode_t */\r
+extern char * _getpty(int *, int, mode_t, int);\r
+#endif\r
+\r
+/* On QNX 6, struct termio must be declared by including sys/termio.h\r
+ if TCGETA, TCSETA, TCSETAW, or TCSETAF are used. sys/termio.h must\r
+ be included before termios.h or it will generate an error. */\r
+#if defined(HAVE_SYS_TERMIO_H) && !defined(__hpux)\r
+#include <sys/termio.h>\r
+#endif\r
+\r
+#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)\r
+#if !defined(HAVE_PTY_H) && !defined(HAVE_LIBUTIL_H) && !defined(HAVE_UTIL_H)\r
+/* BSDI does not supply a prototype for the 'openpty' and 'forkpty'\r
+ functions, even though they are included in libutil. */\r
+#include <termios.h>\r
+extern int openpty(int *, int *, char *, struct termios *, struct winsize *);\r
+extern pid_t forkpty(int *, char *, struct termios *, struct winsize *);\r
+#endif /* !defined(HAVE_PTY_H) && !defined(HAVE_LIBUTIL_H) */\r
+#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */\r
+\r
+\r
+/* These are pulled from various places. It isn't obvious on what platforms\r
+ they are necessary, nor what the exact prototype should look like (which\r
+ is likely to vary between platforms!) If you find you need one of these\r
+ declarations, please move them to a platform-specific block and include\r
+ proper prototypes. */\r
+#if 0\r
+\r
+/* From Modules/resource.c */\r
+extern int getrusage();\r
+extern int getpagesize();\r
+\r
+/* From Python/sysmodule.c and Modules/posixmodule.c */\r
+extern int fclose(FILE *);\r
+\r
+/* From Modules/posixmodule.c */\r
+extern int fdatasync(int);\r
+#endif /* 0 */\r
+\r
+\r
+/* On 4.4BSD-descendants, ctype functions serves the whole range of\r
+ * wchar_t character set rather than single byte code points only.\r
+ * This characteristic can break some operations of string object\r
+ * including str.upper() and str.split() on UTF-8 locales. This\r
+ * workaround was provided by Tim Robbins of FreeBSD project.\r
+ */\r
+\r
+#ifdef __FreeBSD__\r
+#include <osreldate.h>\r
+#if __FreeBSD_version > 500039\r
+# define _PY_PORT_CTYPE_UTF8_ISSUE\r
+#endif\r
+#endif\r
+\r
+\r
+#if defined(__APPLE__)\r
+# define _PY_PORT_CTYPE_UTF8_ISSUE\r
+#endif\r
+\r
+#ifdef _PY_PORT_CTYPE_UTF8_ISSUE\r
+#include <ctype.h>\r
+#include <wctype.h>\r
+#undef isalnum\r
+#define isalnum(c) iswalnum(btowc(c))\r
+#undef isalpha\r
+#define isalpha(c) iswalpha(btowc(c))\r
+#undef islower\r
+#define islower(c) iswlower(btowc(c))\r
+#undef isspace\r
+#define isspace(c) iswspace(btowc(c))\r
+#undef isupper\r
+#define isupper(c) iswupper(btowc(c))\r
+#undef tolower\r
+#define tolower(c) towlower(btowc(c))\r
+#undef toupper\r
+#define toupper(c) towupper(btowc(c))\r
+#endif\r
+\r
+\r
+/* Declarations for symbol visibility.\r
+\r
+ PyAPI_FUNC(type): Declares a public Python API function and return type\r
+ PyAPI_DATA(type): Declares public Python data and its type\r
+ PyMODINIT_FUNC: A Python module init function. If these functions are\r
+ inside the Python core, they are private to the core.\r
+ If in an extension module, it may be declared with\r
+ external linkage depending on the platform.\r
+\r
+ As a number of platforms support/require "__declspec(dllimport/dllexport)",\r
+ we support a HAVE_DECLSPEC_DLL macro to save duplication.\r
+*/\r
+\r
+/*\r
+ All windows ports, except cygwin, are handled in PC/pyconfig.h.\r
+\r
+ BeOS and cygwin are the only other autoconf platform requiring special\r
+ linkage handling and both of these use __declspec().\r
+*/\r
+#if defined(__CYGWIN__) || defined(__BEOS__)\r
+# define HAVE_DECLSPEC_DLL\r
+#endif\r
+\r
+/* only get special linkage if built as shared or platform is Cygwin */\r
+#if defined(Py_ENABLE_SHARED) || defined(__CYGWIN__)\r
+# if defined(HAVE_DECLSPEC_DLL)\r
+# ifdef Py_BUILD_CORE\r
+# define PyAPI_FUNC(RTYPE) __declspec(dllexport) RTYPE\r
+# define PyAPI_DATA(RTYPE) extern __declspec(dllexport) RTYPE\r
+ /* module init functions inside the core need no external linkage */\r
+ /* except for Cygwin to handle embedding (FIXME: BeOS too?) */\r
+# if defined(__CYGWIN__)\r
+# define PyMODINIT_FUNC __declspec(dllexport) void\r
+# else /* __CYGWIN__ */\r
+# define PyMODINIT_FUNC void\r
+# endif /* __CYGWIN__ */\r
+# else /* Py_BUILD_CORE */\r
+ /* Building an extension module, or an embedded situation */\r
+ /* public Python functions and data are imported */\r
+ /* Under Cygwin, auto-import functions to prevent compilation */\r
+ /* failures similar to those described at the bottom of 4.1: */\r
+ /* http://docs.python.org/extending/windows.html#a-cookbook-approach */\r
+# if !defined(__CYGWIN__)\r
+# define PyAPI_FUNC(RTYPE) __declspec(dllimport) RTYPE\r
+# endif /* !__CYGWIN__ */\r
+# define PyAPI_DATA(RTYPE) extern __declspec(dllimport) RTYPE\r
+ /* module init functions outside the core must be exported */\r
+# if defined(__cplusplus)\r
+# define PyMODINIT_FUNC extern "C" __declspec(dllexport) void\r
+# else /* __cplusplus */\r
+# define PyMODINIT_FUNC __declspec(dllexport) void\r
+# endif /* __cplusplus */\r
+# endif /* Py_BUILD_CORE */\r
+# endif /* HAVE_DECLSPEC */\r
+#endif /* Py_ENABLE_SHARED */\r
+\r
+/* If no external linkage macros defined by now, create defaults */\r
+#ifndef PyAPI_FUNC\r
+# define PyAPI_FUNC(RTYPE) RTYPE\r
+#endif\r
+#ifndef PyAPI_DATA\r
+# define PyAPI_DATA(RTYPE) extern RTYPE\r
+#endif\r
+#ifndef PyMODINIT_FUNC\r
+# if defined(__cplusplus)\r
+# define PyMODINIT_FUNC extern "C" void\r
+# else /* __cplusplus */\r
+# define PyMODINIT_FUNC void\r
+# endif /* __cplusplus */\r
+#endif\r
+\r
+/* Deprecated DL_IMPORT and DL_EXPORT macros */\r
+#if defined(Py_ENABLE_SHARED) && defined (HAVE_DECLSPEC_DLL)\r
+# if defined(Py_BUILD_CORE)\r
+# define DL_IMPORT(RTYPE) __declspec(dllexport) RTYPE\r
+# define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE\r
+# else\r
+# define DL_IMPORT(RTYPE) __declspec(dllimport) RTYPE\r
+# define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE\r
+# endif\r
+#endif\r
+#ifndef DL_EXPORT\r
+# define DL_EXPORT(RTYPE) RTYPE\r
+#endif\r
+#ifndef DL_IMPORT\r
+# define DL_IMPORT(RTYPE) RTYPE\r
+#endif\r
+/* End of deprecated DL_* macros */\r
+\r
+/* If the fd manipulation macros aren't defined,\r
+ here is a set that should do the job */\r
+\r
+#if 0 /* disabled and probably obsolete */\r
+\r
+#ifndef FD_SETSIZE\r
+#define FD_SETSIZE 256\r
+#endif\r
+\r
+#ifndef FD_SET\r
+\r
+typedef long fd_mask;\r
+\r
+#define NFDBITS (sizeof(fd_mask) * NBBY) /* bits per mask */\r
+#ifndef howmany\r
+#define howmany(x, y) (((x)+((y)-1))/(y))\r
+#endif /* howmany */\r
+\r
+typedef struct fd_set {\r
+ fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];\r
+} fd_set;\r
+\r
+#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))\r
+#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))\r
+#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))\r
+#define FD_ZERO(p) memset((char *)(p), '\0', sizeof(*(p)))\r
+\r
+#endif /* FD_SET */\r
+\r
+#endif /* fd manipulation macros */\r
+\r
+\r
+/* limits.h constants that may be missing */\r
+\r
+#ifndef INT_MAX\r
+#define INT_MAX 2147483647\r
+#endif\r
+\r
+#ifndef LONG_MAX\r
+#if SIZEOF_LONG == 4\r
+#define LONG_MAX 0X7FFFFFFFL\r
+#elif SIZEOF_LONG == 8\r
+#define LONG_MAX 0X7FFFFFFFFFFFFFFFL\r
+#else\r
+#error "could not set LONG_MAX in pyport.h"\r
+#endif\r
+#endif\r
+\r
+#ifndef LONG_MIN\r
+#define LONG_MIN (-LONG_MAX-1)\r
+#endif\r
+\r
+#ifndef LONG_BIT\r
+#define LONG_BIT (8 * SIZEOF_LONG)\r
+#endif\r
+\r
+#if LONG_BIT != 8 * SIZEOF_LONG\r
+/* 04-Oct-2000 LONG_BIT is apparently (mis)defined as 64 on some recent\r
+ * 32-bit platforms using gcc. We try to catch that here at compile-time\r
+ * rather than waiting for integer multiplication to trigger bogus\r
+ * overflows.\r
+ */\r
+#error "LONG_BIT definition appears wrong for platform (bad gcc/glibc config?)."\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+/*\r
+ * Hide GCC attributes from compilers that don't support them.\r
+ */\r
+#if (!defined(__GNUC__) || __GNUC__ < 2 || \\r
+ (__GNUC__ == 2 && __GNUC_MINOR__ < 7) ) && \\r
+ !defined(RISCOS)\r
+#define Py_GCC_ATTRIBUTE(x)\r
+#else\r
+#define Py_GCC_ATTRIBUTE(x) __attribute__(x)\r
+#endif\r
+\r
+/*\r
+ * Add PyArg_ParseTuple format where available.\r
+ */\r
+#ifdef HAVE_ATTRIBUTE_FORMAT_PARSETUPLE\r
+#define Py_FORMAT_PARSETUPLE(func,p1,p2) __attribute__((format(func,p1,p2)))\r
+#else\r
+#define Py_FORMAT_PARSETUPLE(func,p1,p2)\r
+#endif\r
+\r
+/*\r
+ * Specify alignment on compilers that support it.\r
+ */\r
+#if defined(__GNUC__) && __GNUC__ >= 3\r
+#define Py_ALIGNED(x) __attribute__((aligned(x)))\r
+#else\r
+#define Py_ALIGNED(x)\r
+#endif\r
+\r
+/* Eliminate end-of-loop code not reached warnings from SunPro C\r
+ * when using do{...}while(0) macros\r
+ */\r
+#ifdef __SUNPRO_C\r
+#pragma error_messages (off,E_END_OF_LOOP_CODE_NOT_REACHED)\r
+#endif\r
+\r
+/*\r
+ * Older Microsoft compilers don't support the C99 long long literal suffixes,\r
+ * so these will be defined in PC/pyconfig.h for those compilers.\r
+ */\r
+#ifndef Py_LL\r
+#define Py_LL(x) x##LL\r
+#endif\r
+\r
+#ifndef Py_ULL\r
+#define Py_ULL(x) Py_LL(x##U)\r
+#endif\r
+\r
+#endif /* Py_PYPORT_H */\r
--- /dev/null
+# Module 'ntpath' -- common operations on WinNT/Win95 pathnames\r
+"""Common pathname manipulations, WindowsNT/95 version.\r
+\r
+Instead of importing this module directly, import os and refer to this\r
+module as os.path.\r
+"""\r
+\r
+import os\r
+import sys\r
+import stat\r
+import genericpath\r
+import warnings\r
+\r
+from genericpath import *\r
+from genericpath import _unicode\r
+\r
+__all__ = ["normcase","isabs","join","splitdrive","split","splitext",\r
+ "basename","dirname","commonprefix","getsize","getmtime",\r
+ "getatime","getctime", "islink","exists","lexists","isdir","isfile",\r
+ "ismount","walk","expanduser","expandvars","normpath","abspath",\r
+ "splitunc","curdir","pardir","sep","pathsep","defpath","altsep",\r
+ "extsep","devnull","realpath","supports_unicode_filenames","relpath"]\r
+\r
+# strings representing various path-related bits and pieces\r
+curdir = '.'\r
+pardir = '..'\r
+extsep = '.'\r
+sep = '\\'\r
+pathsep = ';'\r
+altsep = '/'\r
+defpath = '.;C:\\bin'\r
+if 'ce' in sys.builtin_module_names:\r
+ defpath = '\\Windows'\r
+elif 'os2' in sys.builtin_module_names:\r
+ # OS/2 w/ VACPP\r
+ altsep = '/'\r
+devnull = 'nul'\r
+\r
+# Normalize the case of a pathname and map slashes to backslashes.\r
+# Other normalizations (such as optimizing '../' away) are not done\r
+# (this is done by normpath).\r
+\r
+def normcase(s):\r
+ """Normalize case of pathname.\r
+\r
+ Makes all characters lowercase and all slashes into backslashes."""\r
+ return s.replace("/", "\\").lower()\r
+\r
+\r
+# Return whether a path is absolute.\r
+# Trivial in Posix, harder on the Mac or MS-DOS.\r
+# For DOS it is absolute if it starts with a slash or backslash (current\r
+# volume), or if a pathname after the volume letter and colon / UNC resource\r
+# starts with a slash or backslash.\r
+\r
+def isabs(s):\r
+ """Test whether a path is absolute"""\r
+ s = splitdrive(s)[1]\r
+ return s != '' and s[:1] in '/\\'\r
+\r
+\r
+# Join two (or more) paths.\r
+def join(path, *paths):\r
+ """Join two or more pathname components, inserting "\\" as needed."""\r
+ result_drive, result_path = splitdrive(path)\r
+ for p in paths:\r
+ p_drive, p_path = splitdrive(p)\r
+ if p_path and p_path[0] in '\\/':\r
+ # Second path is absolute\r
+ if p_drive or not result_drive:\r
+ result_drive = p_drive\r
+ result_path = p_path\r
+ continue\r
+ elif p_drive and p_drive != result_drive:\r
+ if p_drive.lower() != result_drive.lower():\r
+ # Different drives => ignore the first path entirely\r
+ result_drive = p_drive\r
+ result_path = p_path\r
+ continue\r
+ # Same drive in different case\r
+ result_drive = p_drive\r
+ # Second path is relative to the first\r
+ if result_path and result_path[-1] not in '\\/':\r
+ result_path = result_path + '\\'\r
+ result_path = result_path + p_path\r
+ ## add separator between UNC and non-absolute path\r
+ if (result_path and result_path[0] not in '\\/' and\r
+ result_drive and result_drive[-1:] != ':'):\r
+ return result_drive + sep + result_path\r
+ return result_drive + result_path\r
+\r
+\r
+# Split a path in a drive specification (a drive letter followed by a\r
+# colon) and the path specification.\r
+# It is always true that drivespec + pathspec == p\r
+def splitdrive(p):\r
+ """Split a pathname into drive/UNC sharepoint and relative path specifiers.\r
+ Returns a 2-tuple (drive_or_unc, path); either part may be empty.\r
+\r
+ If you assign\r
+ result = splitdrive(p)\r
+ It is always true that:\r
+ result[0] + result[1] == p\r
+\r
+ If the path contained a drive letter, drive_or_unc will contain everything\r
+ up to and including the colon. e.g. splitdrive("c:/dir") returns ("c:", "/dir")\r
+\r
+ If the path contained a UNC path, the drive_or_unc will contain the host name\r
+ and share up to but not including the fourth directory separator character.\r
+ e.g. splitdrive("//host/computer/dir") returns ("//host/computer", "/dir")\r
+\r
+ Paths cannot contain both a drive letter and a UNC path.\r
+\r
+ """\r
+ if len(p) > 1:\r
+ normp = p.replace(altsep, sep)\r
+ if (normp[0:2] == sep*2) and (normp[2:3] != sep):\r
+ # is a UNC path:\r
+ # vvvvvvvvvvvvvvvvvvvv drive letter or UNC path\r
+ # \\machine\mountpoint\directory\etc\...\r
+ # directory ^^^^^^^^^^^^^^^\r
+ index = normp.find(sep, 2)\r
+ if index == -1:\r
+ return '', p\r
+ index2 = normp.find(sep, index + 1)\r
+ # a UNC path can't have two slashes in a row\r
+ # (after the initial two)\r
+ if index2 == index + 1:\r
+ return '', p\r
+ if index2 == -1:\r
+ index2 = len(p)\r
+ return p[:index2], p[index2:]\r
+ if normp[1] == ':':\r
+ return p[:2], p[2:]\r
+ return '', p\r
+\r
+# Parse UNC paths\r
+def splitunc(p):\r
+ """Split a pathname into UNC mount point and relative path specifiers.\r
+\r
+ Return a 2-tuple (unc, rest); either part may be empty.\r
+ If unc is not empty, it has the form '//host/mount' (or similar\r
+ using backslashes). unc+rest is always the input path.\r
+ Paths containing drive letters never have an UNC part.\r
+ """\r
+ if p[1:2] == ':':\r
+ return '', p # Drive letter present\r
+ firstTwo = p[0:2]\r
+ if firstTwo == '//' or firstTwo == '\\\\':\r
+ # is a UNC path:\r
+ # vvvvvvvvvvvvvvvvvvvv equivalent to drive letter\r
+ # \\machine\mountpoint\directories...\r
+ # directory ^^^^^^^^^^^^^^^\r
+ normp = p.replace('\\', '/')\r
+ index = normp.find('/', 2)\r
+ if index <= 2:\r
+ return '', p\r
+ index2 = normp.find('/', index + 1)\r
+ # a UNC path can't have two slashes in a row\r
+ # (after the initial two)\r
+ if index2 == index + 1:\r
+ return '', p\r
+ if index2 == -1:\r
+ index2 = len(p)\r
+ return p[:index2], p[index2:]\r
+ return '', p\r
+\r
+\r
+# Split a path in head (everything up to the last '/') and tail (the\r
+# rest). After the trailing '/' is stripped, the invariant\r
+# join(head, tail) == p holds.\r
+# The resulting head won't end in '/' unless it is the root.\r
+\r
+def split(p):\r
+ """Split a pathname.\r
+\r
+ Return tuple (head, tail) where tail is everything after the final slash.\r
+ Either part may be empty."""\r
+\r
+ d, p = splitdrive(p)\r
+ # set i to index beyond p's last slash\r
+ i = len(p)\r
+ while i and p[i-1] not in '/\\':\r
+ i = i - 1\r
+ head, tail = p[:i], p[i:] # now tail has no slashes\r
+ # remove trailing slashes from head, unless it's all slashes\r
+ head2 = head\r
+ while head2 and head2[-1] in '/\\':\r
+ head2 = head2[:-1]\r
+ head = head2 or head\r
+ return d + head, tail\r
+\r
+\r
+# Split a path in root and extension.\r
+# The extension is everything starting at the last dot in the last\r
+# pathname component; the root is everything before that.\r
+# It is always true that root + ext == p.\r
+\r
+def splitext(p):\r
+ return genericpath._splitext(p, sep, altsep, extsep)\r
+splitext.__doc__ = genericpath._splitext.__doc__\r
+\r
+\r
+# Return the tail (basename) part of a path.\r
+\r
+def basename(p):\r
+ """Returns the final component of a pathname"""\r
+ return split(p)[1]\r
+\r
+\r
+# Return the head (dirname) part of a path.\r
+\r
+def dirname(p):\r
+ """Returns the directory component of a pathname"""\r
+ return split(p)[0]\r
+\r
+# Is a path a symbolic link?\r
+# This will always return false on systems where posix.lstat doesn't exist.\r
+\r
+def islink(path):\r
+ """Test for symbolic link.\r
+ On WindowsNT/95 and OS/2 always returns false\r
+ """\r
+ return False\r
+\r
+# alias exists to lexists\r
+lexists = exists\r
+\r
+# Is a path a mount point? Either a root (with or without drive letter)\r
+# or an UNC path with at most a / or \ after the mount point.\r
+\r
+def ismount(path):\r
+ """Test whether a path is a mount point (defined as root of drive)"""\r
+ unc, rest = splitunc(path)\r
+ if unc:\r
+ return rest in ("", "/", "\\")\r
+ p = splitdrive(path)[1]\r
+ return len(p) == 1 and p[0] in '/\\'\r
+\r
+\r
+# Directory tree walk.\r
+# For each directory under top (including top itself, but excluding\r
+# '.' and '..'), func(arg, dirname, filenames) is called, where\r
+# dirname is the name of the directory and filenames is the list\r
+# of files (and subdirectories etc.) in the directory.\r
+# The func may modify the filenames list, to implement a filter,\r
+# or to impose a different order of visiting.\r
+\r
+def walk(top, func, arg):\r
+ """Directory tree walk with callback function.\r
+\r
+ For each directory in the directory tree rooted at top (including top\r
+ itself, but excluding '.' and '..'), call func(arg, dirname, fnames).\r
+ dirname is the name of the directory, and fnames a list of the names of\r
+ the files and subdirectories in dirname (excluding '.' and '..'). func\r
+ may modify the fnames list in-place (e.g. via del or slice assignment),\r
+ and walk will only recurse into the subdirectories whose names remain in\r
+ fnames; this can be used to implement a filter, or to impose a specific\r
+ order of visiting. No semantics are defined for, or required of, arg,\r
+ beyond that arg is always passed to func. It can be used, e.g., to pass\r
+ a filename pattern, or a mutable object designed to accumulate\r
+ statistics. Passing None for arg is common."""\r
+ warnings.warnpy3k("In 3.x, os.path.walk is removed in favor of os.walk.",\r
+ stacklevel=2)\r
+ try:\r
+ names = os.listdir(top)\r
+ except os.error:\r
+ return\r
+ func(arg, top, names)\r
+ for name in names:\r
+ name = join(top, name)\r
+ if isdir(name):\r
+ walk(name, func, arg)\r
+\r
+\r
+# Expand paths beginning with '~' or '~user'.\r
+# '~' means $HOME; '~user' means that user's home directory.\r
+# If the path doesn't begin with '~', or if the user or $HOME is unknown,\r
+# the path is returned unchanged (leaving error reporting to whatever\r
+# function is called with the expanded path as argument).\r
+# See also module 'glob' for expansion of *, ? and [...] in pathnames.\r
+# (A function should also be defined to do full *sh-style environment\r
+# variable expansion.)\r
+\r
+def expanduser(path):\r
+ """Expand ~ and ~user constructs.\r
+\r
+ If user or $HOME is unknown, do nothing."""\r
+ if path[:1] != '~':\r
+ return path\r
+ i, n = 1, len(path)\r
+ while i < n and path[i] not in '/\\':\r
+ i = i + 1\r
+\r
+ if 'HOME' in os.environ:\r
+ userhome = os.environ['HOME']\r
+ elif 'USERPROFILE' in os.environ:\r
+ userhome = os.environ['USERPROFILE']\r
+ elif not 'HOMEPATH' in os.environ:\r
+ return path\r
+ else:\r
+ try:\r
+ drive = os.environ['HOMEDRIVE']\r
+ except KeyError:\r
+ drive = ''\r
+ userhome = join(drive, os.environ['HOMEPATH'])\r
+\r
+ if i != 1: #~user\r
+ userhome = join(dirname(userhome), path[1:i])\r
+\r
+ return userhome + path[i:]\r
+\r
+\r
+# Expand paths containing shell variable substitutions.\r
+# The following rules apply:\r
+# - no expansion within single quotes\r
+# - '$$' is translated into '$'\r
+# - '%%' is translated into '%' if '%%' are not seen in %var1%%var2%\r
+# - ${varname} is accepted.\r
+# - $varname is accepted.\r
+# - %varname% is accepted.\r
+# - varnames can be made out of letters, digits and the characters '_-'\r
+# (though is not verified in the ${varname} and %varname% cases)\r
+# XXX With COMMAND.COM you can use any characters in a variable name,\r
+# XXX except '^|<>='.\r
+\r
+def expandvars(path):\r
+ """Expand shell variables of the forms $var, ${var} and %var%.\r
+\r
+ Unknown variables are left unchanged."""\r
+ if '$' not in path and '%' not in path:\r
+ return path\r
+ import string\r
+ varchars = string.ascii_letters + string.digits + '_-'\r
+ if isinstance(path, _unicode):\r
+ encoding = sys.getfilesystemencoding()\r
+ def getenv(var):\r
+ return os.environ[var.encode(encoding)].decode(encoding)\r
+ else:\r
+ def getenv(var):\r
+ return os.environ[var]\r
+ res = ''\r
+ index = 0\r
+ pathlen = len(path)\r
+ while index < pathlen:\r
+ c = path[index]\r
+ if c == '\'': # no expansion within single quotes\r
+ path = path[index + 1:]\r
+ pathlen = len(path)\r
+ try:\r
+ index = path.index('\'')\r
+ res = res + '\'' + path[:index + 1]\r
+ except ValueError:\r
+ res = res + c + path\r
+ index = pathlen - 1\r
+ elif c == '%': # variable or '%'\r
+ if path[index + 1:index + 2] == '%':\r
+ res = res + c\r
+ index = index + 1\r
+ else:\r
+ path = path[index+1:]\r
+ pathlen = len(path)\r
+ try:\r
+ index = path.index('%')\r
+ except ValueError:\r
+ res = res + '%' + path\r
+ index = pathlen - 1\r
+ else:\r
+ var = path[:index]\r
+ try:\r
+ res = res + getenv(var)\r
+ except KeyError:\r
+ res = res + '%' + var + '%'\r
+ elif c == '$': # variable or '$$'\r
+ if path[index + 1:index + 2] == '$':\r
+ res = res + c\r
+ index = index + 1\r
+ elif path[index + 1:index + 2] == '{':\r
+ path = path[index+2:]\r
+ pathlen = len(path)\r
+ try:\r
+ index = path.index('}')\r
+ var = path[:index]\r
+ try:\r
+ res = res + getenv(var)\r
+ except KeyError:\r
+ res = res + '${' + var + '}'\r
+ except ValueError:\r
+ res = res + '${' + path\r
+ index = pathlen - 1\r
+ else:\r
+ var = ''\r
+ index = index + 1\r
+ c = path[index:index + 1]\r
+ while c != '' and c in varchars:\r
+ var = var + c\r
+ index = index + 1\r
+ c = path[index:index + 1]\r
+ try:\r
+ res = res + getenv(var)\r
+ except KeyError:\r
+ res = res + '$' + var\r
+ if c != '':\r
+ index = index - 1\r
+ else:\r
+ res = res + c\r
+ index = index + 1\r
+ return res\r
+\r
+\r
+# Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A\B.\r
+# Previously, this function also truncated pathnames to 8+3 format,\r
+# but as this module is called "ntpath", that's obviously wrong!\r
+\r
+def normpath(path):\r
+ """Normalize path, eliminating double slashes, etc."""\r
+ # Preserve unicode (if path is unicode)\r
+ backslash, dot = (u'\\', u'.') if isinstance(path, _unicode) else ('\\', '.')\r
+ if path.startswith(('\\\\.\\', '\\\\?\\')):\r
+ # in the case of paths with these prefixes:\r
+ # \\.\ -> device names\r
+ # \\?\ -> literal paths\r
+ # do not do any normalization, but return the path unchanged\r
+ return path\r
+ path = path.replace("/", "\\")\r
+ prefix, path = splitdrive(path)\r
+ # We need to be careful here. If the prefix is empty, and the path starts\r
+ # with a backslash, it could either be an absolute path on the current\r
+ # drive (\dir1\dir2\file) or a UNC filename (\\server\mount\dir1\file). It\r
+ # is therefore imperative NOT to collapse multiple backslashes blindly in\r
+ # that case.\r
+ # The code below preserves multiple backslashes when there is no drive\r
+ # letter. This means that the invalid filename \\\a\b is preserved\r
+ # unchanged, where a\\\b is normalised to a\b. It's not clear that there\r
+ # is any better behaviour for such edge cases.\r
+ if prefix == '':\r
+ # No drive letter - preserve initial backslashes\r
+ while path[:1] == "\\":\r
+ prefix = prefix + backslash\r
+ path = path[1:]\r
+ else:\r
+ # We have a drive letter - collapse initial backslashes\r
+ if path.startswith("\\"):\r
+ prefix = prefix + backslash\r
+ path = path.lstrip("\\")\r
+ comps = path.split("\\")\r
+ i = 0\r
+ while i < len(comps):\r
+ if comps[i] in ('.', ''):\r
+ del comps[i]\r
+ elif comps[i] == '..':\r
+ if i > 0 and comps[i-1] != '..':\r
+ del comps[i-1:i+1]\r
+ i -= 1\r
+ elif i == 0 and prefix.endswith("\\"):\r
+ del comps[i]\r
+ else:\r
+ i += 1\r
+ else:\r
+ i += 1\r
+ # If the path is now empty, substitute '.'\r
+ if not prefix and not comps:\r
+ comps.append(dot)\r
+ return prefix + backslash.join(comps)\r
+\r
+\r
+# Return an absolute path.\r
+try:\r
+ from nt import _getfullpathname\r
+\r
+except ImportError: # not running on Windows - mock up something sensible\r
+ def abspath(path):\r
+ """Return the absolute version of a path."""\r
+ if not isabs(path):\r
+ if isinstance(path, _unicode):\r
+ cwd = os.getcwdu()\r
+ else:\r
+ cwd = os.getcwd()\r
+ path = join(cwd, path)\r
+ return normpath(path)\r
+\r
+else: # use native Windows method on Windows\r
+ def abspath(path):\r
+ """Return the absolute version of a path."""\r
+\r
+ if path: # Empty path must return current working directory.\r
+ try:\r
+ path = _getfullpathname(path)\r
+ except WindowsError:\r
+ pass # Bad path - return unchanged.\r
+ elif isinstance(path, _unicode):\r
+ path = os.getcwdu()\r
+ else:\r
+ path = os.getcwd()\r
+ return normpath(path)\r
+\r
+# realpath is a no-op on systems without islink support\r
+realpath = abspath\r
+# Win9x family and earlier have no Unicode filename support.\r
+supports_unicode_filenames = (hasattr(sys, "getwindowsversion") and\r
+ sys.getwindowsversion()[3] >= 2)\r
+\r
+def _abspath_split(path):\r
+ abs = abspath(normpath(path))\r
+ prefix, rest = splitunc(abs)\r
+ is_unc = bool(prefix)\r
+ if not is_unc:\r
+ prefix, rest = splitdrive(abs)\r
+ return is_unc, prefix, [x for x in rest.split(sep) if x]\r
+\r
+def relpath(path, start=curdir):\r
+ """Return a relative version of a path"""\r
+\r
+ if not path:\r
+ raise ValueError("no path specified")\r
+\r
+ start_is_unc, start_prefix, start_list = _abspath_split(start)\r
+ path_is_unc, path_prefix, path_list = _abspath_split(path)\r
+\r
+ if path_is_unc ^ start_is_unc:\r
+ raise ValueError("Cannot mix UNC and non-UNC paths (%s and %s)"\r
+ % (path, start))\r
+ if path_prefix.lower() != start_prefix.lower():\r
+ if path_is_unc:\r
+ raise ValueError("path is on UNC root %s, start on UNC root %s"\r
+ % (path_prefix, start_prefix))\r
+ else:\r
+ raise ValueError("path is on drive %s, start on drive %s"\r
+ % (path_prefix, start_prefix))\r
+ # Work out how much of the filepath is shared by start and path.\r
+ i = 0\r
+ for e1, e2 in zip(start_list, path_list):\r
+ if e1.lower() != e2.lower():\r
+ break\r
+ i += 1\r
+\r
+ rel_list = [pardir] * (len(start_list)-i) + path_list[i:]\r
+ if not rel_list:\r
+ return curdir\r
+ return join(*rel_list)\r
+\r
+try:\r
+ # The genericpath.isdir implementation uses os.stat and checks the mode\r
+ # attribute to tell whether or not the path is a directory.\r
+ # This is overkill on Windows - just pass the path to GetFileAttributes\r
+ # and check the attribute from there.\r
+ from nt import _isdir as isdir\r
+except ImportError:\r
+ # Use genericpath.isdir as imported above.\r
+ pass\r
--- /dev/null
+r"""OS routines for NT or Posix depending on what system we're on.\r
+\r
+This exports:\r
+ - all functions from posix, nt, os2, or ce, e.g. unlink, stat, etc.\r
+ - os.path is one of the modules posixpath, or ntpath\r
+ - os.name is 'posix', 'nt', 'os2', 'ce' or 'riscos'\r
+ - os.curdir is a string representing the current directory ('.' or ':')\r
+ - os.pardir is a string representing the parent directory ('..' or '::')\r
+ - os.sep is the (or a most common) pathname separator ('/' or ':' or '\\')\r
+ - os.extsep is the extension separator ('.' or '/')\r
+ - os.altsep is the alternate pathname separator (None or '/')\r
+ - os.pathsep is the component separator used in $PATH etc\r
+ - os.linesep is the line separator in text files ('\r' or '\n' or '\r\n')\r
+ - os.defpath is the default search path for executables\r
+ - os.devnull is the file path of the null device ('/dev/null', etc.)\r
+\r
+Programs that import and use 'os' stand a better chance of being\r
+portable between different platforms. Of course, they must then\r
+only use functions that are defined by all platforms (e.g., unlink\r
+and opendir), and leave all pathname manipulation to os.path\r
+(e.g., split and join).\r
+"""\r
+\r
+#'\r
+\r
+import sys, errno\r
+\r
+_names = sys.builtin_module_names\r
+\r
+# Note: more names are added to __all__ later.\r
+__all__ = ["altsep", "curdir", "pardir", "sep", "extsep", "pathsep", "linesep",\r
+ "defpath", "name", "path", "devnull",\r
+ "SEEK_SET", "SEEK_CUR", "SEEK_END"]\r
+\r
+def _get_exports_list(module):\r
+ try:\r
+ return list(module.__all__)\r
+ except AttributeError:\r
+ return [n for n in dir(module) if n[0] != '_']\r
+\r
+if 'posix' in _names:\r
+ name = 'posix'\r
+ linesep = '\n'\r
+ from posix import *\r
+ try:\r
+ from posix import _exit\r
+ except ImportError:\r
+ pass\r
+ import posixpath as path\r
+\r
+ import posix\r
+ __all__.extend(_get_exports_list(posix))\r
+ del posix\r
+\r
+elif 'nt' in _names:\r
+ name = 'nt'\r
+ linesep = '\r\n'\r
+ from nt import *\r
+ try:\r
+ from nt import _exit\r
+ except ImportError:\r
+ pass\r
+ import ntpath as path\r
+\r
+ import nt\r
+ __all__.extend(_get_exports_list(nt))\r
+ del nt\r
+\r
+elif 'os2' in _names:\r
+ name = 'os2'\r
+ linesep = '\r\n'\r
+ from os2 import *\r
+ try:\r
+ from os2 import _exit\r
+ except ImportError:\r
+ pass\r
+ if sys.version.find('EMX GCC') == -1:\r
+ import ntpath as path\r
+ else:\r
+ import os2emxpath as path\r
+ from _emx_link import link\r
+\r
+ import os2\r
+ __all__.extend(_get_exports_list(os2))\r
+ del os2\r
+\r
+elif 'ce' in _names:\r
+ name = 'ce'\r
+ linesep = '\r\n'\r
+ from ce import *\r
+ try:\r
+ from ce import _exit\r
+ except ImportError:\r
+ pass\r
+ # We can use the standard Windows path.\r
+ import ntpath as path\r
+\r
+ import ce\r
+ __all__.extend(_get_exports_list(ce))\r
+ del ce\r
+\r
+elif 'riscos' in _names:\r
+ name = 'riscos'\r
+ linesep = '\n'\r
+ from riscos import *\r
+ try:\r
+ from riscos import _exit\r
+ except ImportError:\r
+ pass\r
+ import riscospath as path\r
+\r
+ import riscos\r
+ __all__.extend(_get_exports_list(riscos))\r
+ del riscos\r
+\r
+else:\r
+ raise ImportError, 'no os specific module found'\r
+\r
+sys.modules['os.path'] = path\r
+from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep,\r
+ devnull)\r
+\r
+del _names\r
+\r
+# Python uses fixed values for the SEEK_ constants; they are mapped\r
+# to native constants if necessary in posixmodule.c\r
+SEEK_SET = 0\r
+SEEK_CUR = 1\r
+SEEK_END = 2\r
+\r
+#'\r
+\r
+# Super directory utilities.\r
+# (Inspired by Eric Raymond; the doc strings are mostly his)\r
+\r
+def makedirs(name, mode=0777):\r
+ """makedirs(path [, mode=0777])\r
+\r
+ Super-mkdir; create a leaf directory and all intermediate ones.\r
+ Works like mkdir, except that any intermediate path segment (not\r
+ just the rightmost) will be created if it does not exist. This is\r
+ recursive.\r
+\r
+ """\r
+ head, tail = path.split(name)\r
+ if not tail:\r
+ head, tail = path.split(head)\r
+ if head and tail and not path.exists(head):\r
+ try:\r
+ makedirs(head, mode)\r
+ except OSError, e:\r
+ # be happy if someone already created the path\r
+ if e.errno != errno.EEXIST:\r
+ raise\r
+ if tail == curdir: # xxx/newdir/. exists if xxx/newdir exists\r
+ return\r
+ mkdir(name, mode)\r
+\r
+def removedirs(name):\r
+ """removedirs(path)\r
+\r
+ Super-rmdir; remove a leaf directory and all empty intermediate\r
+ ones. Works like rmdir except that, if the leaf directory is\r
+ successfully removed, directories corresponding to rightmost path\r
+ segments will be pruned away until either the whole path is\r
+ consumed or an error occurs. Errors during this latter phase are\r
+ ignored -- they generally mean that a directory was not empty.\r
+\r
+ """\r
+ rmdir(name)\r
+ head, tail = path.split(name)\r
+ if not tail:\r
+ head, tail = path.split(head)\r
+ while head and tail:\r
+ try:\r
+ rmdir(head)\r
+ except error:\r
+ break\r
+ head, tail = path.split(head)\r
+\r
+def renames(old, new):\r
+ """renames(old, new)\r
+\r
+ Super-rename; create directories as necessary and delete any left\r
+ empty. Works like rename, except creation of any intermediate\r
+ directories needed to make the new pathname good is attempted\r
+ first. After the rename, directories corresponding to rightmost\r
+ path segments of the old name will be pruned until either the\r
+ whole path is consumed or a nonempty directory is found.\r
+\r
+ Note: this function can fail with the new directory structure made\r
+ if you lack permissions needed to unlink the leaf directory or\r
+ file.\r
+\r
+ """\r
+ head, tail = path.split(new)\r
+ if head and tail and not path.exists(head):\r
+ makedirs(head)\r
+ rename(old, new)\r
+ head, tail = path.split(old)\r
+ if head and tail:\r
+ try:\r
+ removedirs(head)\r
+ except error:\r
+ pass\r
+\r
+__all__.extend(["makedirs", "removedirs", "renames"])\r
+\r
+def walk(top, topdown=True, onerror=None, followlinks=False):\r
+ """Directory tree generator.\r
+\r
+ For each directory in the directory tree rooted at top (including top\r
+ itself, but excluding '.' and '..'), yields a 3-tuple\r
+\r
+ dirpath, dirnames, filenames\r
+\r
+ dirpath is a string, the path to the directory. dirnames is a list of\r
+ the names of the subdirectories in dirpath (excluding '.' and '..').\r
+ filenames is a list of the names of the non-directory files in dirpath.\r
+ Note that the names in the lists are just names, with no path components.\r
+ To get a full path (which begins with top) to a file or directory in\r
+ dirpath, do os.path.join(dirpath, name).\r
+\r
+ If optional arg 'topdown' is true or not specified, the triple for a\r
+ directory is generated before the triples for any of its subdirectories\r
+ (directories are generated top down). If topdown is false, the triple\r
+ for a directory is generated after the triples for all of its\r
+ subdirectories (directories are generated bottom up).\r
+\r
+ When topdown is true, the caller can modify the dirnames list in-place\r
+ (e.g., via del or slice assignment), and walk will only recurse into the\r
+ subdirectories whose names remain in dirnames; this can be used to prune the\r
+ search, or to impose a specific order of visiting. Modifying dirnames when\r
+ topdown is false is ineffective, since the directories in dirnames have\r
+ already been generated by the time dirnames itself is generated. No matter\r
+ the value of topdown, the list of subdirectories is retrieved before the\r
+ tuples for the directory and its subdirectories are generated.\r
+\r
+ By default errors from the os.listdir() call are ignored. If\r
+ optional arg 'onerror' is specified, it should be a function; it\r
+ will be called with one argument, an os.error instance. It can\r
+ report the error to continue with the walk, or raise the exception\r
+ to abort the walk. Note that the filename is available as the\r
+ filename attribute of the exception object.\r
+\r
+ By default, os.walk does not follow symbolic links to subdirectories on\r
+ systems that support them. In order to get this functionality, set the\r
+ optional argument 'followlinks' to true.\r
+\r
+ Caution: if you pass a relative pathname for top, don't change the\r
+ current working directory between resumptions of walk. walk never\r
+ changes the current directory, and assumes that the client doesn't\r
+ either.\r
+\r
+ Example:\r
+\r
+ import os\r
+ from os.path import join, getsize\r
+ for root, dirs, files in os.walk('python/Lib/email'):\r
+ print root, "consumes",\r
+ print sum([getsize(join(root, name)) for name in files]),\r
+ print "bytes in", len(files), "non-directory files"\r
+ if 'CVS' in dirs:\r
+ dirs.remove('CVS') # don't visit CVS directories\r
+\r
+ """\r
+\r
+ islink, join, isdir = path.islink, path.join, path.isdir\r
+\r
+ # We may not have read permission for top, in which case we can't\r
+ # get a list of the files the directory contains. os.path.walk\r
+ # always suppressed the exception then, rather than blow up for a\r
+ # minor reason when (say) a thousand readable directories are still\r
+ # left to visit. That logic is copied here.\r
+ try:\r
+ # Note that listdir and error are globals in this module due\r
+ # to earlier import-*.\r
+ names = listdir(top)\r
+ except error, err:\r
+ if onerror is not None:\r
+ onerror(err)\r
+ return\r
+\r
+ dirs, nondirs = [], []\r
+ for name in names:\r
+ if isdir(join(top, name)):\r
+ dirs.append(name)\r
+ else:\r
+ nondirs.append(name)\r
+\r
+ if topdown:\r
+ yield top, dirs, nondirs\r
+ for name in dirs:\r
+ new_path = join(top, name)\r
+ if followlinks or not islink(new_path):\r
+ for x in walk(new_path, topdown, onerror, followlinks):\r
+ yield x\r
+ if not topdown:\r
+ yield top, dirs, nondirs\r
+\r
+__all__.append("walk")\r
+\r
+# Make sure os.environ exists, at least\r
+try:\r
+ environ\r
+except NameError:\r
+ environ = {}\r
+\r
+def execl(file, *args):\r
+ """execl(file, *args)\r
+\r
+ Execute the executable file with argument list args, replacing the\r
+ current process. """\r
+ execv(file, args)\r
+\r
+def execle(file, *args):\r
+ """execle(file, *args, env)\r
+\r
+ Execute the executable file with argument list args and\r
+ environment env, replacing the current process. """\r
+ env = args[-1]\r
+ execve(file, args[:-1], env)\r
+\r
+def execlp(file, *args):\r
+ """execlp(file, *args)\r
+\r
+ Execute the executable file (which is searched for along $PATH)\r
+ with argument list args, replacing the current process. """\r
+ execvp(file, args)\r
+\r
+def execlpe(file, *args):\r
+ """execlpe(file, *args, env)\r
+\r
+ Execute the executable file (which is searched for along $PATH)\r
+ with argument list args and environment env, replacing the current\r
+ process. """\r
+ env = args[-1]\r
+ execvpe(file, args[:-1], env)\r
+\r
+def execvp(file, args):\r
+ """execvp(file, args)\r
+\r
+ Execute the executable file (which is searched for along $PATH)\r
+ with argument list args, replacing the current process.\r
+ args may be a list or tuple of strings. """\r
+ _execvpe(file, args)\r
+\r
+def execvpe(file, args, env):\r
+ """execvpe(file, args, env)\r
+\r
+ Execute the executable file (which is searched for along $PATH)\r
+ with argument list args and environment env , replacing the\r
+ current process.\r
+ args may be a list or tuple of strings. """\r
+ _execvpe(file, args, env)\r
+\r
+__all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"])\r
+\r
+def _execvpe(file, args, env=None):\r
+ if env is not None:\r
+ func = execve\r
+ argrest = (args, env)\r
+ else:\r
+ func = execv\r
+ argrest = (args,)\r
+ env = environ\r
+\r
+ head, tail = path.split(file)\r
+ if head:\r
+ func(file, *argrest)\r
+ return\r
+ if 'PATH' in env:\r
+ envpath = env['PATH']\r
+ else:\r
+ envpath = defpath\r
+ PATH = envpath.split(pathsep)\r
+ saved_exc = None\r
+ saved_tb = None\r
+ for dir in PATH:\r
+ fullname = path.join(dir, file)\r
+ try:\r
+ func(fullname, *argrest)\r
+ except error, e:\r
+ tb = sys.exc_info()[2]\r
+ if (e.errno != errno.ENOENT and e.errno != errno.ENOTDIR\r
+ and saved_exc is None):\r
+ saved_exc = e\r
+ saved_tb = tb\r
+ if saved_exc:\r
+ raise error, saved_exc, saved_tb\r
+ raise error, e, tb\r
+\r
+# Change environ to automatically call putenv() if it exists\r
+try:\r
+ # This will fail if there's no putenv\r
+ putenv\r
+except NameError:\r
+ pass\r
+else:\r
+ import UserDict\r
+\r
+ # Fake unsetenv() for Windows\r
+ # not sure about os2 here but\r
+ # I'm guessing they are the same.\r
+\r
+ if name in ('os2', 'nt'):\r
+ def unsetenv(key):\r
+ putenv(key, "")\r
+\r
+ if name == "riscos":\r
+ # On RISC OS, all env access goes through getenv and putenv\r
+ from riscosenviron import _Environ\r
+ elif name in ('os2', 'nt'): # Where Env Var Names Must Be UPPERCASE\r
+ # But we store them as upper case\r
+ class _Environ(UserDict.IterableUserDict):\r
+ def __init__(self, environ):\r
+ UserDict.UserDict.__init__(self)\r
+ data = self.data\r
+ for k, v in environ.items():\r
+ data[k.upper()] = v\r
+ def __setitem__(self, key, item):\r
+ putenv(key, item)\r
+ self.data[key.upper()] = item\r
+ def __getitem__(self, key):\r
+ return self.data[key.upper()]\r
+ try:\r
+ unsetenv\r
+ except NameError:\r
+ def __delitem__(self, key):\r
+ del self.data[key.upper()]\r
+ else:\r
+ def __delitem__(self, key):\r
+ unsetenv(key)\r
+ del self.data[key.upper()]\r
+ def clear(self):\r
+ for key in self.data.keys():\r
+ unsetenv(key)\r
+ del self.data[key]\r
+ def pop(self, key, *args):\r
+ unsetenv(key)\r
+ return self.data.pop(key.upper(), *args)\r
+ def has_key(self, key):\r
+ return key.upper() in self.data\r
+ def __contains__(self, key):\r
+ return key.upper() in self.data\r
+ def get(self, key, failobj=None):\r
+ return self.data.get(key.upper(), failobj)\r
+ def update(self, dict=None, **kwargs):\r
+ if dict:\r
+ try:\r
+ keys = dict.keys()\r
+ except AttributeError:\r
+ # List of (key, value)\r
+ for k, v in dict:\r
+ self[k] = v\r
+ else:\r
+ # got keys\r
+ # cannot use items(), since mappings\r
+ # may not have them.\r
+ for k in keys:\r
+ self[k] = dict[k]\r
+ if kwargs:\r
+ self.update(kwargs)\r
+ def copy(self):\r
+ return dict(self)\r
+\r
+ else: # Where Env Var Names Can Be Mixed Case\r
+ class _Environ(UserDict.IterableUserDict):\r
+ def __init__(self, environ):\r
+ UserDict.UserDict.__init__(self)\r
+ self.data = environ\r
+ def __setitem__(self, key, item):\r
+ putenv(key, item)\r
+ self.data[key] = item\r
+ def update(self, dict=None, **kwargs):\r
+ if dict:\r
+ try:\r
+ keys = dict.keys()\r
+ except AttributeError:\r
+ # List of (key, value)\r
+ for k, v in dict:\r
+ self[k] = v\r
+ else:\r
+ # got keys\r
+ # cannot use items(), since mappings\r
+ # may not have them.\r
+ for k in keys:\r
+ self[k] = dict[k]\r
+ if kwargs:\r
+ self.update(kwargs)\r
+ try:\r
+ unsetenv\r
+ except NameError:\r
+ pass\r
+ else:\r
+ def __delitem__(self, key):\r
+ unsetenv(key)\r
+ del self.data[key]\r
+ def clear(self):\r
+ for key in self.data.keys():\r
+ unsetenv(key)\r
+ del self.data[key]\r
+ def pop(self, key, *args):\r
+ unsetenv(key)\r
+ return self.data.pop(key, *args)\r
+ def copy(self):\r
+ return dict(self)\r
+\r
+\r
+ environ = _Environ(environ)\r
+\r
+def getenv(key, default=None):\r
+ """Get an environment variable, return None if it doesn't exist.\r
+ The optional second argument can specify an alternate default."""\r
+ return environ.get(key, default)\r
+__all__.append("getenv")\r
+\r
+def _exists(name):\r
+ return name in globals()\r
+\r
+# Supply spawn*() (probably only for Unix)\r
+if _exists("fork") and not _exists("spawnv") and _exists("execv"):\r
+\r
+ P_WAIT = 0\r
+ P_NOWAIT = P_NOWAITO = 1\r
+\r
+ # XXX Should we support P_DETACH? I suppose it could fork()**2\r
+ # and close the std I/O streams. Also, P_OVERLAY is the same\r
+ # as execv*()?\r
+\r
+ def _spawnvef(mode, file, args, env, func):\r
+ # Internal helper; func is the exec*() function to use\r
+ pid = fork()\r
+ if not pid:\r
+ # Child\r
+ try:\r
+ if env is None:\r
+ func(file, args)\r
+ else:\r
+ func(file, args, env)\r
+ except:\r
+ _exit(127)\r
+ else:\r
+ # Parent\r
+ if mode == P_NOWAIT:\r
+ return pid # Caller is responsible for waiting!\r
+ while 1:\r
+ wpid, sts = waitpid(pid, 0)\r
+ if WIFSTOPPED(sts):\r
+ continue\r
+ elif WIFSIGNALED(sts):\r
+ return -WTERMSIG(sts)\r
+ elif WIFEXITED(sts):\r
+ return WEXITSTATUS(sts)\r
+ else:\r
+ raise error, "Not stopped, signaled or exited???"\r
+\r
+ def spawnv(mode, file, args):\r
+ """spawnv(mode, file, args) -> integer\r
+\r
+Execute file with arguments from args in a subprocess.\r
+If mode == P_NOWAIT return the pid of the process.\r
+If mode == P_WAIT return the process's exit code if it exits normally;\r
+otherwise return -SIG, where SIG is the signal that killed it. """\r
+ return _spawnvef(mode, file, args, None, execv)\r
+\r
+ def spawnve(mode, file, args, env):\r
+ """spawnve(mode, file, args, env) -> integer\r
+\r
+Execute file with arguments from args in a subprocess with the\r
+specified environment.\r
+If mode == P_NOWAIT return the pid of the process.\r
+If mode == P_WAIT return the process's exit code if it exits normally;\r
+otherwise return -SIG, where SIG is the signal that killed it. """\r
+ return _spawnvef(mode, file, args, env, execve)\r
+\r
+ # Note: spawnvp[e] is't currently supported on Windows\r
+\r
+ def spawnvp(mode, file, args):\r
+ """spawnvp(mode, file, args) -> integer\r
+\r
+Execute file (which is looked for along $PATH) with arguments from\r
+args in a subprocess.\r
+If mode == P_NOWAIT return the pid of the process.\r
+If mode == P_WAIT return the process's exit code if it exits normally;\r
+otherwise return -SIG, where SIG is the signal that killed it. """\r
+ return _spawnvef(mode, file, args, None, execvp)\r
+\r
+ def spawnvpe(mode, file, args, env):\r
+ """spawnvpe(mode, file, args, env) -> integer\r
+\r
+Execute file (which is looked for along $PATH) with arguments from\r
+args in a subprocess with the supplied environment.\r
+If mode == P_NOWAIT return the pid of the process.\r
+If mode == P_WAIT return the process's exit code if it exits normally;\r
+otherwise return -SIG, where SIG is the signal that killed it. """\r
+ return _spawnvef(mode, file, args, env, execvpe)\r
+\r
+if _exists("spawnv"):\r
+ # These aren't supplied by the basic Windows code\r
+ # but can be easily implemented in Python\r
+\r
+ def spawnl(mode, file, *args):\r
+ """spawnl(mode, file, *args) -> integer\r
+\r
+Execute file with arguments from args in a subprocess.\r
+If mode == P_NOWAIT return the pid of the process.\r
+If mode == P_WAIT return the process's exit code if it exits normally;\r
+otherwise return -SIG, where SIG is the signal that killed it. """\r
+ return spawnv(mode, file, args)\r
+\r
+ def spawnle(mode, file, *args):\r
+ """spawnle(mode, file, *args, env) -> integer\r
+\r
+Execute file with arguments from args in a subprocess with the\r
+supplied environment.\r
+If mode == P_NOWAIT return the pid of the process.\r
+If mode == P_WAIT return the process's exit code if it exits normally;\r
+otherwise return -SIG, where SIG is the signal that killed it. """\r
+ env = args[-1]\r
+ return spawnve(mode, file, args[:-1], env)\r
+\r
+\r
+ __all__.extend(["spawnv", "spawnve", "spawnl", "spawnle",])\r
+\r
+\r
+if _exists("spawnvp"):\r
+ # At the moment, Windows doesn't implement spawnvp[e],\r
+ # so it won't have spawnlp[e] either.\r
+ def spawnlp(mode, file, *args):\r
+ """spawnlp(mode, file, *args) -> integer\r
+\r
+Execute file (which is looked for along $PATH) with arguments from\r
+args in a subprocess with the supplied environment.\r
+If mode == P_NOWAIT return the pid of the process.\r
+If mode == P_WAIT return the process's exit code if it exits normally;\r
+otherwise return -SIG, where SIG is the signal that killed it. """\r
+ return spawnvp(mode, file, args)\r
+\r
+ def spawnlpe(mode, file, *args):\r
+ """spawnlpe(mode, file, *args, env) -> integer\r
+\r
+Execute file (which is looked for along $PATH) with arguments from\r
+args in a subprocess with the supplied environment.\r
+If mode == P_NOWAIT return the pid of the process.\r
+If mode == P_WAIT return the process's exit code if it exits normally;\r
+otherwise return -SIG, where SIG is the signal that killed it. """\r
+ env = args[-1]\r
+ return spawnvpe(mode, file, args[:-1], env)\r
+\r
+\r
+ __all__.extend(["spawnvp", "spawnvpe", "spawnlp", "spawnlpe",])\r
+\r
+\r
+# Supply popen2 etc. (for Unix)\r
+if _exists("fork"):\r
+ if not _exists("popen2"):\r
+ def popen2(cmd, mode="t", bufsize=-1):\r
+ """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd'\r
+ may be a sequence, in which case arguments will be passed directly to\r
+ the program without shell intervention (as with os.spawnv()). If 'cmd'\r
+ is a string it will be passed to the shell (as with os.system()). If\r
+ 'bufsize' is specified, it sets the buffer size for the I/O pipes. The\r
+ file objects (child_stdin, child_stdout) are returned."""\r
+ import warnings\r
+ msg = "os.popen2 is deprecated. Use the subprocess module."\r
+ warnings.warn(msg, DeprecationWarning, stacklevel=2)\r
+\r
+ import subprocess\r
+ PIPE = subprocess.PIPE\r
+ p = subprocess.Popen(cmd, shell=isinstance(cmd, basestring),\r
+ bufsize=bufsize, stdin=PIPE, stdout=PIPE,\r
+ close_fds=True)\r
+ return p.stdin, p.stdout\r
+ __all__.append("popen2")\r
+\r
+ if not _exists("popen3"):\r
+ def popen3(cmd, mode="t", bufsize=-1):\r
+ """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd'\r
+ may be a sequence, in which case arguments will be passed directly to\r
+ the program without shell intervention (as with os.spawnv()). If 'cmd'\r
+ is a string it will be passed to the shell (as with os.system()). If\r
+ 'bufsize' is specified, it sets the buffer size for the I/O pipes. The\r
+ file objects (child_stdin, child_stdout, child_stderr) are returned."""\r
+ import warnings\r
+ msg = "os.popen3 is deprecated. Use the subprocess module."\r
+ warnings.warn(msg, DeprecationWarning, stacklevel=2)\r
+\r
+ import subprocess\r
+ PIPE = subprocess.PIPE\r
+ p = subprocess.Popen(cmd, shell=isinstance(cmd, basestring),\r
+ bufsize=bufsize, stdin=PIPE, stdout=PIPE,\r
+ stderr=PIPE, close_fds=True)\r
+ return p.stdin, p.stdout, p.stderr\r
+ __all__.append("popen3")\r
+\r
+ if not _exists("popen4"):\r
+ def popen4(cmd, mode="t", bufsize=-1):\r
+ """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd'\r
+ may be a sequence, in which case arguments will be passed directly to\r
+ the program without shell intervention (as with os.spawnv()). If 'cmd'\r
+ is a string it will be passed to the shell (as with os.system()). If\r
+ 'bufsize' is specified, it sets the buffer size for the I/O pipes. The\r
+ file objects (child_stdin, child_stdout_stderr) are returned."""\r
+ import warnings\r
+ msg = "os.popen4 is deprecated. Use the subprocess module."\r
+ warnings.warn(msg, DeprecationWarning, stacklevel=2)\r
+\r
+ import subprocess\r
+ PIPE = subprocess.PIPE\r
+ p = subprocess.Popen(cmd, shell=isinstance(cmd, basestring),\r
+ bufsize=bufsize, stdin=PIPE, stdout=PIPE,\r
+ stderr=subprocess.STDOUT, close_fds=True)\r
+ return p.stdin, p.stdout\r
+ __all__.append("popen4")\r
+\r
+import copy_reg as _copy_reg\r
+\r
+def _make_stat_result(tup, dict):\r
+ return stat_result(tup, dict)\r
+\r
+def _pickle_stat_result(sr):\r
+ (type, args) = sr.__reduce__()\r
+ return (_make_stat_result, args)\r
+\r
+try:\r
+ _copy_reg.pickle(stat_result, _pickle_stat_result, _make_stat_result)\r
+except NameError: # stat_result may not exist\r
+ pass\r
+\r
+def _make_statvfs_result(tup, dict):\r
+ return statvfs_result(tup, dict)\r
+\r
+def _pickle_statvfs_result(sr):\r
+ (type, args) = sr.__reduce__()\r
+ return (_make_statvfs_result, args)\r
+\r
+try:\r
+ _copy_reg.pickle(statvfs_result, _pickle_statvfs_result,\r
+ _make_statvfs_result)\r
+except NameError: # statvfs_result may not exist\r
+ pass\r
--- /dev/null
+#!/usr/bin/env python\r
+# -*- coding: latin-1 -*-\r
+"""Generate Python documentation in HTML or text for interactive use.\r
+\r
+In the Python interpreter, do "from pydoc import help" to provide online\r
+help. Calling help(thing) on a Python object documents the object.\r
+\r
+Or, at the shell command line outside of Python:\r
+\r
+Run "pydoc <name>" to show documentation on something. <name> may be\r
+the name of a function, module, package, or a dotted reference to a\r
+class or function within a module or module in a package. If the\r
+argument contains a path segment delimiter (e.g. slash on Unix,\r
+backslash on Windows) it is treated as the path to a Python source file.\r
+\r
+Run "pydoc -k <keyword>" to search for a keyword in the synopsis lines\r
+of all available modules.\r
+\r
+Run "pydoc -p <port>" to start an HTTP server on a given port on the\r
+local machine to generate documentation web pages. Port number 0 can be\r
+used to get an arbitrary unused port.\r
+\r
+For platforms without a command line, "pydoc -g" starts the HTTP server\r
+and also pops up a little window for controlling it.\r
+\r
+Run "pydoc -w <name>" to write out the HTML documentation for a module\r
+to a file named "<name>.html".\r
+\r
+Module docs for core modules are assumed to be in\r
+\r
+ http://docs.python.org/library/\r
+\r
+This can be overridden by setting the PYTHONDOCS environment variable\r
+to a different URL or to a local directory containing the Library\r
+Reference Manual pages.\r
+"""\r
+\r
+__author__ = "Ka-Ping Yee <ping@lfw.org>"\r
+__date__ = "26 February 2001"\r
+\r
+__version__ = "$Revision: 88564 $"\r
+__credits__ = """Guido van Rossum, for an excellent programming language.\r
+Tommy Burnette, the original creator of manpy.\r
+Paul Prescod, for all his work on onlinehelp.\r
+Richard Chamberlain, for the first implementation of textdoc.\r
+"""\r
+\r
+# Known bugs that can't be fixed here:\r
+# - imp.load_module() cannot be prevented from clobbering existing\r
+# loaded modules, so calling synopsis() on a binary module file\r
+# changes the contents of any existing module with the same name.\r
+# - If the __file__ attribute on a module is a relative path and\r
+# the current directory is changed with os.chdir(), an incorrect\r
+# path will be displayed.\r
+\r
+import sys, imp, os, re, types, inspect, __builtin__, pkgutil, warnings\r
+from repr import Repr\r
+from string import expandtabs, find, join, lower, split, strip, rfind, rstrip\r
+from traceback import extract_tb\r
+try:\r
+ from collections import deque\r
+except ImportError:\r
+ # Python 2.3 compatibility\r
+ class deque(list):\r
+ def popleft(self):\r
+ return self.pop(0)\r
+\r
+# --------------------------------------------------------- common routines\r
+\r
+def pathdirs():\r
+ """Convert sys.path into a list of absolute, existing, unique paths."""\r
+ dirs = []\r
+ normdirs = []\r
+ for dir in sys.path:\r
+ dir = os.path.abspath(dir or '.')\r
+ normdir = os.path.normcase(dir)\r
+ if normdir not in normdirs and os.path.isdir(dir):\r
+ dirs.append(dir)\r
+ normdirs.append(normdir)\r
+ return dirs\r
+\r
+def getdoc(object):\r
+ """Get the doc string or comments for an object."""\r
+ result = inspect.getdoc(object) or inspect.getcomments(object)\r
+ result = _encode(result)\r
+ return result and re.sub('^ *\n', '', rstrip(result)) or ''\r
+\r
+def splitdoc(doc):\r
+ """Split a doc string into a synopsis line (if any) and the rest."""\r
+ lines = split(strip(doc), '\n')\r
+ if len(lines) == 1:\r
+ return lines[0], ''\r
+ elif len(lines) >= 2 and not rstrip(lines[1]):\r
+ return lines[0], join(lines[2:], '\n')\r
+ return '', join(lines, '\n')\r
+\r
+def classname(object, modname):\r
+ """Get a class name and qualify it with a module name if necessary."""\r
+ name = object.__name__\r
+ if object.__module__ != modname:\r
+ name = object.__module__ + '.' + name\r
+ return name\r
+\r
+def isdata(object):\r
+ """Check if an object is of a type that probably means it's data."""\r
+ return not (inspect.ismodule(object) or inspect.isclass(object) or\r
+ inspect.isroutine(object) or inspect.isframe(object) or\r
+ inspect.istraceback(object) or inspect.iscode(object))\r
+\r
+def replace(text, *pairs):\r
+ """Do a series of global replacements on a string."""\r
+ while pairs:\r
+ text = join(split(text, pairs[0]), pairs[1])\r
+ pairs = pairs[2:]\r
+ return text\r
+\r
+def cram(text, maxlen):\r
+ """Omit part of a string if needed to make it fit in a maximum length."""\r
+ if len(text) > maxlen:\r
+ pre = max(0, (maxlen-3)//2)\r
+ post = max(0, maxlen-3-pre)\r
+ return text[:pre] + '...' + text[len(text)-post:]\r
+ return text\r
+\r
+_re_stripid = re.compile(r' at 0x[0-9a-f]{6,16}(>+)$', re.IGNORECASE)\r
+def stripid(text):\r
+ """Remove the hexadecimal id from a Python object representation."""\r
+ # The behaviour of %p is implementation-dependent in terms of case.\r
+ return _re_stripid.sub(r'\1', text)\r
+\r
+def _is_some_method(obj):\r
+ return inspect.ismethod(obj) or inspect.ismethoddescriptor(obj)\r
+\r
+def allmethods(cl):\r
+ methods = {}\r
+ for key, value in inspect.getmembers(cl, _is_some_method):\r
+ methods[key] = 1\r
+ for base in cl.__bases__:\r
+ methods.update(allmethods(base)) # all your base are belong to us\r
+ for key in methods.keys():\r
+ methods[key] = getattr(cl, key)\r
+ return methods\r
+\r
+def _split_list(s, predicate):\r
+ """Split sequence s via predicate, and return pair ([true], [false]).\r
+\r
+ The return value is a 2-tuple of lists,\r
+ ([x for x in s if predicate(x)],\r
+ [x for x in s if not predicate(x)])\r
+ """\r
+\r
+ yes = []\r
+ no = []\r
+ for x in s:\r
+ if predicate(x):\r
+ yes.append(x)\r
+ else:\r
+ no.append(x)\r
+ return yes, no\r
+\r
+def visiblename(name, all=None, obj=None):\r
+ """Decide whether to show documentation on a variable."""\r
+ # Certain special names are redundant.\r
+ _hidden_names = ('__builtins__', '__doc__', '__file__', '__path__',\r
+ '__module__', '__name__', '__slots__', '__package__')\r
+ if name in _hidden_names: return 0\r
+ # Private names are hidden, but special names are displayed.\r
+ if name.startswith('__') and name.endswith('__'): return 1\r
+ # Namedtuples have public fields and methods with a single leading underscore\r
+ if name.startswith('_') and hasattr(obj, '_fields'):\r
+ return 1\r
+ if all is not None:\r
+ # only document that which the programmer exported in __all__\r
+ return name in all\r
+ else:\r
+ return not name.startswith('_')\r
+\r
+def classify_class_attrs(object):\r
+ """Wrap inspect.classify_class_attrs, with fixup for data descriptors."""\r
+ def fixup(data):\r
+ name, kind, cls, value = data\r
+ if inspect.isdatadescriptor(value):\r
+ kind = 'data descriptor'\r
+ return name, kind, cls, value\r
+ return map(fixup, inspect.classify_class_attrs(object))\r
+\r
+# ----------------------------------------------------- Unicode support helpers\r
+\r
+try:\r
+ _unicode = unicode\r
+except NameError:\r
+ # If Python is built without Unicode support, the unicode type\r
+ # will not exist. Fake one that nothing will match, and make\r
+ # the _encode function that do nothing.\r
+ class _unicode(object):\r
+ pass\r
+ _encoding = 'ascii'\r
+ def _encode(text, encoding='ascii'):\r
+ return text\r
+else:\r
+ import locale\r
+ _encoding = locale.getpreferredencoding()\r
+\r
+ def _encode(text, encoding=None):\r
+ if isinstance(text, unicode):\r
+ return text.encode(encoding or _encoding, 'xmlcharrefreplace')\r
+ else:\r
+ return text\r
+\r
+def _binstr(obj):\r
+ # Ensure that we have an encoded (binary) string representation of obj,\r
+ # even if it is a unicode string.\r
+ if isinstance(obj, _unicode):\r
+ return obj.encode(_encoding, 'xmlcharrefreplace')\r
+ return str(obj)\r
+\r
+# ----------------------------------------------------- module manipulation\r
+\r
+def ispackage(path):\r
+ """Guess whether a path refers to a package directory."""\r
+ if os.path.isdir(path):\r
+ for ext in ('.py', '.pyc', '.pyo'):\r
+ if os.path.isfile(os.path.join(path, '__init__' + ext)):\r
+ return True\r
+ return False\r
+\r
+def source_synopsis(file):\r
+ line = file.readline()\r
+ while line[:1] == '#' or not strip(line):\r
+ line = file.readline()\r
+ if not line: break\r
+ line = strip(line)\r
+ if line[:4] == 'r"""': line = line[1:]\r
+ if line[:3] == '"""':\r
+ line = line[3:]\r
+ if line[-1:] == '\\': line = line[:-1]\r
+ while not strip(line):\r
+ line = file.readline()\r
+ if not line: break\r
+ result = strip(split(line, '"""')[0])\r
+ else: result = None\r
+ return result\r
+\r
+def synopsis(filename, cache={}):\r
+ """Get the one-line summary out of a module file."""\r
+ mtime = os.stat(filename).st_mtime\r
+ lastupdate, result = cache.get(filename, (None, None))\r
+ if lastupdate is None or lastupdate < mtime:\r
+ info = inspect.getmoduleinfo(filename)\r
+ try:\r
+ file = open(filename)\r
+ except IOError:\r
+ # module can't be opened, so skip it\r
+ return None\r
+ if info and 'b' in info[2]: # binary modules have to be imported\r
+ try: module = imp.load_module('__temp__', file, filename, info[1:])\r
+ except: return None\r
+ result = module.__doc__.splitlines()[0] if module.__doc__ else None\r
+ del sys.modules['__temp__']\r
+ else: # text modules can be directly examined\r
+ result = source_synopsis(file)\r
+ file.close()\r
+ cache[filename] = (mtime, result)\r
+ return result\r
+\r
+class ErrorDuringImport(Exception):\r
+ """Errors that occurred while trying to import something to document it."""\r
+ def __init__(self, filename, exc_info):\r
+ exc, value, tb = exc_info\r
+ self.filename = filename\r
+ self.exc = exc\r
+ self.value = value\r
+ self.tb = tb\r
+\r
+ def __str__(self):\r
+ exc = self.exc\r
+ if type(exc) is types.ClassType:\r
+ exc = exc.__name__\r
+ return 'problem in %s - %s: %s' % (self.filename, exc, self.value)\r
+\r
+def importfile(path):\r
+ """Import a Python source file or compiled file given its path."""\r
+ magic = imp.get_magic()\r
+ file = open(path, 'r')\r
+ if file.read(len(magic)) == magic:\r
+ kind = imp.PY_COMPILED\r
+ else:\r
+ kind = imp.PY_SOURCE\r
+ file.close()\r
+ filename = os.path.basename(path)\r
+ name, ext = os.path.splitext(filename)\r
+ file = open(path, 'r')\r
+ try:\r
+ module = imp.load_module(name, file, path, (ext, 'r', kind))\r
+ except:\r
+ raise ErrorDuringImport(path, sys.exc_info())\r
+ file.close()\r
+ return module\r
+\r
+def safeimport(path, forceload=0, cache={}):\r
+ """Import a module; handle errors; return None if the module isn't found.\r
+\r
+ If the module *is* found but an exception occurs, it's wrapped in an\r
+ ErrorDuringImport exception and reraised. Unlike __import__, if a\r
+ package path is specified, the module at the end of the path is returned,\r
+ not the package at the beginning. If the optional 'forceload' argument\r
+ is 1, we reload the module from disk (unless it's a dynamic extension)."""\r
+ try:\r
+ # If forceload is 1 and the module has been previously loaded from\r
+ # disk, we always have to reload the module. Checking the file's\r
+ # mtime isn't good enough (e.g. the module could contain a class\r
+ # that inherits from another module that has changed).\r
+ if forceload and path in sys.modules:\r
+ if path not in sys.builtin_module_names:\r
+ # Avoid simply calling reload() because it leaves names in\r
+ # the currently loaded module lying around if they're not\r
+ # defined in the new source file. Instead, remove the\r
+ # module from sys.modules and re-import. Also remove any\r
+ # submodules because they won't appear in the newly loaded\r
+ # module's namespace if they're already in sys.modules.\r
+ subs = [m for m in sys.modules if m.startswith(path + '.')]\r
+ for key in [path] + subs:\r
+ # Prevent garbage collection.\r
+ cache[key] = sys.modules[key]\r
+ del sys.modules[key]\r
+ module = __import__(path)\r
+ except:\r
+ # Did the error occur before or after the module was found?\r
+ (exc, value, tb) = info = sys.exc_info()\r
+ if path in sys.modules:\r
+ # An error occurred while executing the imported module.\r
+ raise ErrorDuringImport(sys.modules[path].__file__, info)\r
+ elif exc is SyntaxError:\r
+ # A SyntaxError occurred before we could execute the module.\r
+ raise ErrorDuringImport(value.filename, info)\r
+ elif exc is ImportError and extract_tb(tb)[-1][2]=='safeimport':\r
+ # The import error occurred directly in this function,\r
+ # which means there is no such module in the path.\r
+ return None\r
+ else:\r
+ # Some other error occurred during the importing process.\r
+ raise ErrorDuringImport(path, sys.exc_info())\r
+ for part in split(path, '.')[1:]:\r
+ try: module = getattr(module, part)\r
+ except AttributeError: return None\r
+ return module\r
+\r
+# ---------------------------------------------------- formatter base class\r
+\r
+class Doc:\r
+ def document(self, object, name=None, *args):\r
+ """Generate documentation for an object."""\r
+ args = (object, name) + args\r
+ # 'try' clause is to attempt to handle the possibility that inspect\r
+ # identifies something in a way that pydoc itself has issues handling;\r
+ # think 'super' and how it is a descriptor (which raises the exception\r
+ # by lacking a __name__ attribute) and an instance.\r
+ if inspect.isgetsetdescriptor(object): return self.docdata(*args)\r
+ if inspect.ismemberdescriptor(object): return self.docdata(*args)\r
+ try:\r
+ if inspect.ismodule(object): return self.docmodule(*args)\r
+ if inspect.isclass(object): return self.docclass(*args)\r
+ if inspect.isroutine(object): return self.docroutine(*args)\r
+ except AttributeError:\r
+ pass\r
+ if isinstance(object, property): return self.docproperty(*args)\r
+ return self.docother(*args)\r
+\r
+ def fail(self, object, name=None, *args):\r
+ """Raise an exception for unimplemented types."""\r
+ message = "don't know how to document object%s of type %s" % (\r
+ name and ' ' + repr(name), type(object).__name__)\r
+ raise TypeError, message\r
+\r
+ docmodule = docclass = docroutine = docother = docproperty = docdata = fail\r
+\r
+ def getdocloc(self, object):\r
+ """Return the location of module docs or None"""\r
+\r
+ try:\r
+ file = inspect.getabsfile(object)\r
+ except TypeError:\r
+ file = '(built-in)'\r
+\r
+ docloc = os.environ.get("PYTHONDOCS",\r
+ "http://docs.python.org/library")\r
+ basedir = os.path.join(sys.exec_prefix, "lib",\r
+ "python"+sys.version[0:3])\r
+ if (isinstance(object, type(os)) and\r
+ (object.__name__ in ('errno', 'exceptions', 'gc', 'imp',\r
+ 'marshal', 'posix', 'signal', 'sys',\r
+ 'thread', 'zipimport') or\r
+ (file.startswith(basedir) and\r
+ not file.startswith(os.path.join(basedir, 'site-packages')))) and\r
+ object.__name__ not in ('xml.etree', 'test.pydoc_mod')):\r
+ if docloc.startswith("http://"):\r
+ docloc = "%s/%s" % (docloc.rstrip("/"), object.__name__)\r
+ else:\r
+ docloc = os.path.join(docloc, object.__name__ + ".html")\r
+ else:\r
+ docloc = None\r
+ return docloc\r
+\r
+# -------------------------------------------- HTML documentation generator\r
+\r
+class HTMLRepr(Repr):\r
+ """Class for safely making an HTML representation of a Python object."""\r
+ def __init__(self):\r
+ Repr.__init__(self)\r
+ self.maxlist = self.maxtuple = 20\r
+ self.maxdict = 10\r
+ self.maxstring = self.maxother = 100\r
+\r
+ def escape(self, text):\r
+ return replace(text, '&', '&', '<', '<', '>', '>')\r
+\r
+ def repr(self, object):\r
+ return Repr.repr(self, object)\r
+\r
+ def repr1(self, x, level):\r
+ if hasattr(type(x), '__name__'):\r
+ methodname = 'repr_' + join(split(type(x).__name__), '_')\r
+ if hasattr(self, methodname):\r
+ return getattr(self, methodname)(x, level)\r
+ return self.escape(cram(stripid(repr(x)), self.maxother))\r
+\r
+ def repr_string(self, x, level):\r
+ test = cram(x, self.maxstring)\r
+ testrepr = repr(test)\r
+ if '\\' in test and '\\' not in replace(testrepr, r'\\', ''):\r
+ # Backslashes are only literal in the string and are never\r
+ # needed to make any special characters, so show a raw string.\r
+ return 'r' + testrepr[0] + self.escape(test) + testrepr[0]\r
+ return re.sub(r'((\\[\\abfnrtv\'"]|\\[0-9]..|\\x..|\\u....)+)',\r
+ r'<font color="#c040c0">\1</font>',\r
+ self.escape(testrepr))\r
+\r
+ repr_str = repr_string\r
+\r
+ def repr_instance(self, x, level):\r
+ try:\r
+ return self.escape(cram(stripid(repr(x)), self.maxstring))\r
+ except:\r
+ return self.escape('<%s instance>' % x.__class__.__name__)\r
+\r
+ repr_unicode = repr_string\r
+\r
+class HTMLDoc(Doc):\r
+ """Formatter class for HTML documentation."""\r
+\r
+ # ------------------------------------------- HTML formatting utilities\r
+\r
+ _repr_instance = HTMLRepr()\r
+ repr = _repr_instance.repr\r
+ escape = _repr_instance.escape\r
+\r
+ def page(self, title, contents):\r
+ """Format an HTML page."""\r
+ return _encode('''\r
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">\r
+<html><head><title>Python: %s</title>\r
+<meta charset="utf-8">\r
+</head><body bgcolor="#f0f0f8">\r
+%s\r
+</body></html>''' % (title, contents), 'ascii')\r
+\r
+ def heading(self, title, fgcol, bgcol, extras=''):\r
+ """Format a page heading."""\r
+ return '''\r
+<table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="heading">\r
+<tr bgcolor="%s">\r
+<td valign=bottom> <br>\r
+<font color="%s" face="helvetica, arial"> <br>%s</font></td\r
+><td align=right valign=bottom\r
+><font color="%s" face="helvetica, arial">%s</font></td></tr></table>\r
+ ''' % (bgcol, fgcol, title, fgcol, extras or ' ')\r
+\r
+ def section(self, title, fgcol, bgcol, contents, width=6,\r
+ prelude='', marginalia=None, gap=' '):\r
+ """Format a section with a heading."""\r
+ if marginalia is None:\r
+ marginalia = '<tt>' + ' ' * width + '</tt>'\r
+ result = '''<p>\r
+<table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="section">\r
+<tr bgcolor="%s">\r
+<td colspan=3 valign=bottom> <br>\r
+<font color="%s" face="helvetica, arial">%s</font></td></tr>\r
+ ''' % (bgcol, fgcol, title)\r
+ if prelude:\r
+ result = result + '''\r
+<tr bgcolor="%s"><td rowspan=2>%s</td>\r
+<td colspan=2>%s</td></tr>\r
+<tr><td>%s</td>''' % (bgcol, marginalia, prelude, gap)\r
+ else:\r
+ result = result + '''\r
+<tr><td bgcolor="%s">%s</td><td>%s</td>''' % (bgcol, marginalia, gap)\r
+\r
+ return result + '\n<td width="100%%">%s</td></tr></table>' % contents\r
+\r
+ def bigsection(self, title, *args):\r
+ """Format a section with a big heading."""\r
+ title = '<big><strong>%s</strong></big>' % title\r
+ return self.section(title, *args)\r
+\r
+ def preformat(self, text):\r
+ """Format literal preformatted text."""\r
+ text = self.escape(expandtabs(text))\r
+ return replace(text, '\n\n', '\n \n', '\n\n', '\n \n',\r
+ ' ', ' ', '\n', '<br>\n')\r
+\r
+ def multicolumn(self, list, format, cols=4):\r
+ """Format a list of items into a multi-column list."""\r
+ result = ''\r
+ rows = (len(list)+cols-1)//cols\r
+ for col in range(cols):\r
+ result = result + '<td width="%d%%" valign=top>' % (100//cols)\r
+ for i in range(rows*col, rows*col+rows):\r
+ if i < len(list):\r
+ result = result + format(list[i]) + '<br>\n'\r
+ result = result + '</td>'\r
+ return '<table width="100%%" summary="list"><tr>%s</tr></table>' % result\r
+\r
+ def grey(self, text): return '<font color="#909090">%s</font>' % text\r
+\r
+ def namelink(self, name, *dicts):\r
+ """Make a link for an identifier, given name-to-URL mappings."""\r
+ for dict in dicts:\r
+ if name in dict:\r
+ return '<a href="%s">%s</a>' % (dict[name], name)\r
+ return name\r
+\r
+ def classlink(self, object, modname):\r
+ """Make a link for a class."""\r
+ name, module = object.__name__, sys.modules.get(object.__module__)\r
+ if hasattr(module, name) and getattr(module, name) is object:\r
+ return '<a href="%s.html#%s">%s</a>' % (\r
+ module.__name__, name, classname(object, modname))\r
+ return classname(object, modname)\r
+\r
+ def modulelink(self, object):\r
+ """Make a link for a module."""\r
+ return '<a href="%s.html">%s</a>' % (object.__name__, object.__name__)\r
+\r
+ def modpkglink(self, data):\r
+ """Make a link for a module or package to display in an index."""\r
+ name, path, ispackage, shadowed = data\r
+ if shadowed:\r
+ return self.grey(name)\r
+ if path:\r
+ url = '%s.%s.html' % (path, name)\r
+ else:\r
+ url = '%s.html' % name\r
+ if ispackage:\r
+ text = '<strong>%s</strong> (package)' % name\r
+ else:\r
+ text = name\r
+ return '<a href="%s">%s</a>' % (url, text)\r
+\r
+ def markup(self, text, escape=None, funcs={}, classes={}, methods={}):\r
+ """Mark up some plain text, given a context of symbols to look for.\r
+ Each context dictionary maps object names to anchor names."""\r
+ escape = escape or self.escape\r
+ results = []\r
+ here = 0\r
+ pattern = re.compile(r'\b((http|ftp)://\S+[\w/]|'\r
+ r'RFC[- ]?(\d+)|'\r
+ r'PEP[- ]?(\d+)|'\r
+ r'(self\.)?(\w+))')\r
+ while True:\r
+ match = pattern.search(text, here)\r
+ if not match: break\r
+ start, end = match.span()\r
+ results.append(escape(text[here:start]))\r
+\r
+ all, scheme, rfc, pep, selfdot, name = match.groups()\r
+ if scheme:\r
+ url = escape(all).replace('"', '"')\r
+ results.append('<a href="%s">%s</a>' % (url, url))\r
+ elif rfc:\r
+ url = 'http://www.rfc-editor.org/rfc/rfc%d.txt' % int(rfc)\r
+ results.append('<a href="%s">%s</a>' % (url, escape(all)))\r
+ elif pep:\r
+ url = 'http://www.python.org/dev/peps/pep-%04d/' % int(pep)\r
+ results.append('<a href="%s">%s</a>' % (url, escape(all)))\r
+ elif selfdot:\r
+ # Create a link for methods like 'self.method(...)'\r
+ # and use <strong> for attributes like 'self.attr'\r
+ if text[end:end+1] == '(':\r
+ results.append('self.' + self.namelink(name, methods))\r
+ else:\r
+ results.append('self.<strong>%s</strong>' % name)\r
+ elif text[end:end+1] == '(':\r
+ results.append(self.namelink(name, methods, funcs, classes))\r
+ else:\r
+ results.append(self.namelink(name, classes))\r
+ here = end\r
+ results.append(escape(text[here:]))\r
+ return join(results, '')\r
+\r
+ # ---------------------------------------------- type-specific routines\r
+\r
+ def formattree(self, tree, modname, parent=None):\r
+ """Produce HTML for a class tree as given by inspect.getclasstree()."""\r
+ result = ''\r
+ for entry in tree:\r
+ if type(entry) is type(()):\r
+ c, bases = entry\r
+ result = result + '<dt><font face="helvetica, arial">'\r
+ result = result + self.classlink(c, modname)\r
+ if bases and bases != (parent,):\r
+ parents = []\r
+ for base in bases:\r
+ parents.append(self.classlink(base, modname))\r
+ result = result + '(' + join(parents, ', ') + ')'\r
+ result = result + '\n</font></dt>'\r
+ elif type(entry) is type([]):\r
+ result = result + '<dd>\n%s</dd>\n' % self.formattree(\r
+ entry, modname, c)\r
+ return '<dl>\n%s</dl>\n' % result\r
+\r
+ def docmodule(self, object, name=None, mod=None, *ignored):\r
+ """Produce HTML documentation for a module object."""\r
+ name = object.__name__ # ignore the passed-in name\r
+ try:\r
+ all = object.__all__\r
+ except AttributeError:\r
+ all = None\r
+ parts = split(name, '.')\r
+ links = []\r
+ for i in range(len(parts)-1):\r
+ links.append(\r
+ '<a href="%s.html"><font color="#ffffff">%s</font></a>' %\r
+ (join(parts[:i+1], '.'), parts[i]))\r
+ linkedname = join(links + parts[-1:], '.')\r
+ head = '<big><big><strong>%s</strong></big></big>' % linkedname\r
+ try:\r
+ path = inspect.getabsfile(object)\r
+ url = path\r
+ if sys.platform == 'win32':\r
+ import nturl2path\r
+ url = nturl2path.pathname2url(path)\r
+ filelink = '<a href="file:%s">%s</a>' % (url, path)\r
+ except TypeError:\r
+ filelink = '(built-in)'\r
+ info = []\r
+ if hasattr(object, '__version__'):\r
+ version = _binstr(object.__version__)\r
+ if version[:11] == '$' + 'Revision: ' and version[-1:] == '$':\r
+ version = strip(version[11:-1])\r
+ info.append('version %s' % self.escape(version))\r
+ if hasattr(object, '__date__'):\r
+ info.append(self.escape(_binstr(object.__date__)))\r
+ if info:\r
+ head = head + ' (%s)' % join(info, ', ')\r
+ docloc = self.getdocloc(object)\r
+ if docloc is not None:\r
+ docloc = '<br><a href="%(docloc)s">Module Docs</a>' % locals()\r
+ else:\r
+ docloc = ''\r
+ result = self.heading(\r
+ head, '#ffffff', '#7799ee',\r
+ '<a href=".">index</a><br>' + filelink + docloc)\r
+\r
+ modules = inspect.getmembers(object, inspect.ismodule)\r
+\r
+ classes, cdict = [], {}\r
+ for key, value in inspect.getmembers(object, inspect.isclass):\r
+ # if __all__ exists, believe it. Otherwise use old heuristic.\r
+ if (all is not None or\r
+ (inspect.getmodule(value) or object) is object):\r
+ if visiblename(key, all, object):\r
+ classes.append((key, value))\r
+ cdict[key] = cdict[value] = '#' + key\r
+ for key, value in classes:\r
+ for base in value.__bases__:\r
+ key, modname = base.__name__, base.__module__\r
+ module = sys.modules.get(modname)\r
+ if modname != name and module and hasattr(module, key):\r
+ if getattr(module, key) is base:\r
+ if not key in cdict:\r
+ cdict[key] = cdict[base] = modname + '.html#' + key\r
+ funcs, fdict = [], {}\r
+ for key, value in inspect.getmembers(object, inspect.isroutine):\r
+ # if __all__ exists, believe it. Otherwise use old heuristic.\r
+ if (all is not None or\r
+ inspect.isbuiltin(value) or inspect.getmodule(value) is object):\r
+ if visiblename(key, all, object):\r
+ funcs.append((key, value))\r
+ fdict[key] = '#-' + key\r
+ if inspect.isfunction(value): fdict[value] = fdict[key]\r
+ data = []\r
+ for key, value in inspect.getmembers(object, isdata):\r
+ if visiblename(key, all, object):\r
+ data.append((key, value))\r
+\r
+ doc = self.markup(getdoc(object), self.preformat, fdict, cdict)\r
+ doc = doc and '<tt>%s</tt>' % doc\r
+ result = result + '<p>%s</p>\n' % doc\r
+\r
+ if hasattr(object, '__path__'):\r
+ modpkgs = []\r
+ for importer, modname, ispkg in pkgutil.iter_modules(object.__path__):\r
+ modpkgs.append((modname, name, ispkg, 0))\r
+ modpkgs.sort()\r
+ contents = self.multicolumn(modpkgs, self.modpkglink)\r
+ result = result + self.bigsection(\r
+ 'Package Contents', '#ffffff', '#aa55cc', contents)\r
+ elif modules:\r
+ contents = self.multicolumn(\r
+ modules, lambda key_value, s=self: s.modulelink(key_value[1]))\r
+ result = result + self.bigsection(\r
+ 'Modules', '#ffffff', '#aa55cc', contents)\r
+\r
+ if classes:\r
+ classlist = map(lambda key_value: key_value[1], classes)\r
+ contents = [\r
+ self.formattree(inspect.getclasstree(classlist, 1), name)]\r
+ for key, value in classes:\r
+ contents.append(self.document(value, key, name, fdict, cdict))\r
+ result = result + self.bigsection(\r
+ 'Classes', '#ffffff', '#ee77aa', join(contents))\r
+ if funcs:\r
+ contents = []\r
+ for key, value in funcs:\r
+ contents.append(self.document(value, key, name, fdict, cdict))\r
+ result = result + self.bigsection(\r
+ 'Functions', '#ffffff', '#eeaa77', join(contents))\r
+ if data:\r
+ contents = []\r
+ for key, value in data:\r
+ contents.append(self.document(value, key))\r
+ result = result + self.bigsection(\r
+ 'Data', '#ffffff', '#55aa55', join(contents, '<br>\n'))\r
+ if hasattr(object, '__author__'):\r
+ contents = self.markup(_binstr(object.__author__), self.preformat)\r
+ result = result + self.bigsection(\r
+ 'Author', '#ffffff', '#7799ee', contents)\r
+ if hasattr(object, '__credits__'):\r
+ contents = self.markup(_binstr(object.__credits__), self.preformat)\r
+ result = result + self.bigsection(\r
+ 'Credits', '#ffffff', '#7799ee', contents)\r
+\r
+ return result\r
+\r
+ def docclass(self, object, name=None, mod=None, funcs={}, classes={},\r
+ *ignored):\r
+ """Produce HTML documentation for a class object."""\r
+ realname = object.__name__\r
+ name = name or realname\r
+ bases = object.__bases__\r
+\r
+ contents = []\r
+ push = contents.append\r
+\r
+ # Cute little class to pump out a horizontal rule between sections.\r
+ class HorizontalRule:\r
+ def __init__(self):\r
+ self.needone = 0\r
+ def maybe(self):\r
+ if self.needone:\r
+ push('<hr>\n')\r
+ self.needone = 1\r
+ hr = HorizontalRule()\r
+\r
+ # List the mro, if non-trivial.\r
+ mro = deque(inspect.getmro(object))\r
+ if len(mro) > 2:\r
+ hr.maybe()\r
+ push('<dl><dt>Method resolution order:</dt>\n')\r
+ for base in mro:\r
+ push('<dd>%s</dd>\n' % self.classlink(base,\r
+ object.__module__))\r
+ push('</dl>\n')\r
+\r
+ def spill(msg, attrs, predicate):\r
+ ok, attrs = _split_list(attrs, predicate)\r
+ if ok:\r
+ hr.maybe()\r
+ push(msg)\r
+ for name, kind, homecls, value in ok:\r
+ try:\r
+ value = getattr(object, name)\r
+ except Exception:\r
+ # Some descriptors may meet a failure in their __get__.\r
+ # (bug #1785)\r
+ push(self._docdescriptor(name, value, mod))\r
+ else:\r
+ push(self.document(value, name, mod,\r
+ funcs, classes, mdict, object))\r
+ push('\n')\r
+ return attrs\r
+\r
+ def spilldescriptors(msg, attrs, predicate):\r
+ ok, attrs = _split_list(attrs, predicate)\r
+ if ok:\r
+ hr.maybe()\r
+ push(msg)\r
+ for name, kind, homecls, value in ok:\r
+ push(self._docdescriptor(name, value, mod))\r
+ return attrs\r
+\r
+ def spilldata(msg, attrs, predicate):\r
+ ok, attrs = _split_list(attrs, predicate)\r
+ if ok:\r
+ hr.maybe()\r
+ push(msg)\r
+ for name, kind, homecls, value in ok:\r
+ base = self.docother(getattr(object, name), name, mod)\r
+ if (hasattr(value, '__call__') or\r
+ inspect.isdatadescriptor(value)):\r
+ doc = getattr(value, "__doc__", None)\r
+ else:\r
+ doc = None\r
+ if doc is None:\r
+ push('<dl><dt>%s</dl>\n' % base)\r
+ else:\r
+ doc = self.markup(getdoc(value), self.preformat,\r
+ funcs, classes, mdict)\r
+ doc = '<dd><tt>%s</tt>' % doc\r
+ push('<dl><dt>%s%s</dl>\n' % (base, doc))\r
+ push('\n')\r
+ return attrs\r
+\r
+ attrs = filter(lambda data: visiblename(data[0], obj=object),\r
+ classify_class_attrs(object))\r
+ mdict = {}\r
+ for key, kind, homecls, value in attrs:\r
+ mdict[key] = anchor = '#' + name + '-' + key\r
+ try:\r
+ value = getattr(object, name)\r
+ except Exception:\r
+ # Some descriptors may meet a failure in their __get__.\r
+ # (bug #1785)\r
+ pass\r
+ try:\r
+ # The value may not be hashable (e.g., a data attr with\r
+ # a dict or list value).\r
+ mdict[value] = anchor\r
+ except TypeError:\r
+ pass\r
+\r
+ while attrs:\r
+ if mro:\r
+ thisclass = mro.popleft()\r
+ else:\r
+ thisclass = attrs[0][2]\r
+ attrs, inherited = _split_list(attrs, lambda t: t[2] is thisclass)\r
+\r
+ if thisclass is __builtin__.object:\r
+ attrs = inherited\r
+ continue\r
+ elif thisclass is object:\r
+ tag = 'defined here'\r
+ else:\r
+ tag = 'inherited from %s' % self.classlink(thisclass,\r
+ object.__module__)\r
+ tag += ':<br>\n'\r
+\r
+ # Sort attrs by name.\r
+ try:\r
+ attrs.sort(key=lambda t: t[0])\r
+ except TypeError:\r
+ attrs.sort(lambda t1, t2: cmp(t1[0], t2[0])) # 2.3 compat\r
+\r
+ # Pump out the attrs, segregated by kind.\r
+ attrs = spill('Methods %s' % tag, attrs,\r
+ lambda t: t[1] == 'method')\r
+ attrs = spill('Class methods %s' % tag, attrs,\r
+ lambda t: t[1] == 'class method')\r
+ attrs = spill('Static methods %s' % tag, attrs,\r
+ lambda t: t[1] == 'static method')\r
+ attrs = spilldescriptors('Data descriptors %s' % tag, attrs,\r
+ lambda t: t[1] == 'data descriptor')\r
+ attrs = spilldata('Data and other attributes %s' % tag, attrs,\r
+ lambda t: t[1] == 'data')\r
+ assert attrs == []\r
+ attrs = inherited\r
+\r
+ contents = ''.join(contents)\r
+\r
+ if name == realname:\r
+ title = '<a name="%s">class <strong>%s</strong></a>' % (\r
+ name, realname)\r
+ else:\r
+ title = '<strong>%s</strong> = <a name="%s">class %s</a>' % (\r
+ name, name, realname)\r
+ if bases:\r
+ parents = []\r
+ for base in bases:\r
+ parents.append(self.classlink(base, object.__module__))\r
+ title = title + '(%s)' % join(parents, ', ')\r
+ doc = self.markup(getdoc(object), self.preformat, funcs, classes, mdict)\r
+ doc = doc and '<tt>%s<br> </tt>' % doc\r
+\r
+ return self.section(title, '#000000', '#ffc8d8', contents, 3, doc)\r
+\r
+ def formatvalue(self, object):\r
+ """Format an argument default value as text."""\r
+ return self.grey('=' + self.repr(object))\r
+\r
+ def docroutine(self, object, name=None, mod=None,\r
+ funcs={}, classes={}, methods={}, cl=None):\r
+ """Produce HTML documentation for a function or method object."""\r
+ realname = object.__name__\r
+ name = name or realname\r
+ anchor = (cl and cl.__name__ or '') + '-' + name\r
+ note = ''\r
+ skipdocs = 0\r
+ if inspect.ismethod(object):\r
+ imclass = object.im_class\r
+ if cl:\r
+ if imclass is not cl:\r
+ note = ' from ' + self.classlink(imclass, mod)\r
+ else:\r
+ if object.im_self is not None:\r
+ note = ' method of %s instance' % self.classlink(\r
+ object.im_self.__class__, mod)\r
+ else:\r
+ note = ' unbound %s method' % self.classlink(imclass,mod)\r
+ object = object.im_func\r
+\r
+ if name == realname:\r
+ title = '<a name="%s"><strong>%s</strong></a>' % (anchor, realname)\r
+ else:\r
+ if (cl and realname in cl.__dict__ and\r
+ cl.__dict__[realname] is object):\r
+ reallink = '<a href="#%s">%s</a>' % (\r
+ cl.__name__ + '-' + realname, realname)\r
+ skipdocs = 1\r
+ else:\r
+ reallink = realname\r
+ title = '<a name="%s"><strong>%s</strong></a> = %s' % (\r
+ anchor, name, reallink)\r
+ if inspect.isfunction(object):\r
+ args, varargs, varkw, defaults = inspect.getargspec(object)\r
+ argspec = inspect.formatargspec(\r
+ args, varargs, varkw, defaults, formatvalue=self.formatvalue)\r
+ if realname == '<lambda>':\r
+ title = '<strong>%s</strong> <em>lambda</em> ' % name\r
+ argspec = argspec[1:-1] # remove parentheses\r
+ else:\r
+ argspec = '(...)'\r
+\r
+ decl = title + argspec + (note and self.grey(\r
+ '<font face="helvetica, arial">%s</font>' % note))\r
+\r
+ if skipdocs:\r
+ return '<dl><dt>%s</dt></dl>\n' % decl\r
+ else:\r
+ doc = self.markup(\r
+ getdoc(object), self.preformat, funcs, classes, methods)\r
+ doc = doc and '<dd><tt>%s</tt></dd>' % doc\r
+ return '<dl><dt>%s</dt>%s</dl>\n' % (decl, doc)\r
+\r
+ def _docdescriptor(self, name, value, mod):\r
+ results = []\r
+ push = results.append\r
+\r
+ if name:\r
+ push('<dl><dt><strong>%s</strong></dt>\n' % name)\r
+ if value.__doc__ is not None:\r
+ doc = self.markup(getdoc(value), self.preformat)\r
+ push('<dd><tt>%s</tt></dd>\n' % doc)\r
+ push('</dl>\n')\r
+\r
+ return ''.join(results)\r
+\r
+ def docproperty(self, object, name=None, mod=None, cl=None):\r
+ """Produce html documentation for a property."""\r
+ return self._docdescriptor(name, object, mod)\r
+\r
+ def docother(self, object, name=None, mod=None, *ignored):\r
+ """Produce HTML documentation for a data object."""\r
+ lhs = name and '<strong>%s</strong> = ' % name or ''\r
+ return lhs + self.repr(object)\r
+\r
+ def docdata(self, object, name=None, mod=None, cl=None):\r
+ """Produce html documentation for a data descriptor."""\r
+ return self._docdescriptor(name, object, mod)\r
+\r
+ def index(self, dir, shadowed=None):\r
+ """Generate an HTML index for a directory of modules."""\r
+ modpkgs = []\r
+ if shadowed is None: shadowed = {}\r
+ for importer, name, ispkg in pkgutil.iter_modules([dir]):\r
+ modpkgs.append((name, '', ispkg, name in shadowed))\r
+ shadowed[name] = 1\r
+\r
+ modpkgs.sort()\r
+ contents = self.multicolumn(modpkgs, self.modpkglink)\r
+ return self.bigsection(dir, '#ffffff', '#ee77aa', contents)\r
+\r
+# -------------------------------------------- text documentation generator\r
+\r
+class TextRepr(Repr):\r
+ """Class for safely making a text representation of a Python object."""\r
+ def __init__(self):\r
+ Repr.__init__(self)\r
+ self.maxlist = self.maxtuple = 20\r
+ self.maxdict = 10\r
+ self.maxstring = self.maxother = 100\r
+\r
+ def repr1(self, x, level):\r
+ if hasattr(type(x), '__name__'):\r
+ methodname = 'repr_' + join(split(type(x).__name__), '_')\r
+ if hasattr(self, methodname):\r
+ return getattr(self, methodname)(x, level)\r
+ return cram(stripid(repr(x)), self.maxother)\r
+\r
+ def repr_string(self, x, level):\r
+ test = cram(x, self.maxstring)\r
+ testrepr = repr(test)\r
+ if '\\' in test and '\\' not in replace(testrepr, r'\\', ''):\r
+ # Backslashes are only literal in the string and are never\r
+ # needed to make any special characters, so show a raw string.\r
+ return 'r' + testrepr[0] + test + testrepr[0]\r
+ return testrepr\r
+\r
+ repr_str = repr_string\r
+\r
+ def repr_instance(self, x, level):\r
+ try:\r
+ return cram(stripid(repr(x)), self.maxstring)\r
+ except:\r
+ return '<%s instance>' % x.__class__.__name__\r
+\r
+class TextDoc(Doc):\r
+ """Formatter class for text documentation."""\r
+\r
+ # ------------------------------------------- text formatting utilities\r
+\r
+ _repr_instance = TextRepr()\r
+ repr = _repr_instance.repr\r
+\r
+ def bold(self, text):\r
+ """Format a string in bold by overstriking."""\r
+ return join(map(lambda ch: ch + '\b' + ch, text), '')\r
+\r
+ def indent(self, text, prefix=' '):\r
+ """Indent text by prepending a given prefix to each line."""\r
+ if not text: return ''\r
+ lines = split(text, '\n')\r
+ lines = map(lambda line, prefix=prefix: prefix + line, lines)\r
+ if lines: lines[-1] = rstrip(lines[-1])\r
+ return join(lines, '\n')\r
+\r
+ def section(self, title, contents):\r
+ """Format a section with a given heading."""\r
+ return self.bold(title) + '\n' + rstrip(self.indent(contents)) + '\n\n'\r
+\r
+ # ---------------------------------------------- type-specific routines\r
+\r
+ def formattree(self, tree, modname, parent=None, prefix=''):\r
+ """Render in text a class tree as returned by inspect.getclasstree()."""\r
+ result = ''\r
+ for entry in tree:\r
+ if type(entry) is type(()):\r
+ c, bases = entry\r
+ result = result + prefix + classname(c, modname)\r
+ if bases and bases != (parent,):\r
+ parents = map(lambda c, m=modname: classname(c, m), bases)\r
+ result = result + '(%s)' % join(parents, ', ')\r
+ result = result + '\n'\r
+ elif type(entry) is type([]):\r
+ result = result + self.formattree(\r
+ entry, modname, c, prefix + ' ')\r
+ return result\r
+\r
+ def docmodule(self, object, name=None, mod=None):\r
+ """Produce text documentation for a given module object."""\r
+ name = object.__name__ # ignore the passed-in name\r
+ synop, desc = splitdoc(getdoc(object))\r
+ result = self.section('NAME', name + (synop and ' - ' + synop))\r
+\r
+ try:\r
+ all = object.__all__\r
+ except AttributeError:\r
+ all = None\r
+\r
+ try:\r
+ file = inspect.getabsfile(object)\r
+ except TypeError:\r
+ file = '(built-in)'\r
+ result = result + self.section('FILE', file)\r
+\r
+ docloc = self.getdocloc(object)\r
+ if docloc is not None:\r
+ result = result + self.section('MODULE DOCS', docloc)\r
+\r
+ if desc:\r
+ result = result + self.section('DESCRIPTION', desc)\r
+\r
+ classes = []\r
+ for key, value in inspect.getmembers(object, inspect.isclass):\r
+ # if __all__ exists, believe it. Otherwise use old heuristic.\r
+ if (all is not None\r
+ or (inspect.getmodule(value) or object) is object):\r
+ if visiblename(key, all, object):\r
+ classes.append((key, value))\r
+ funcs = []\r
+ for key, value in inspect.getmembers(object, inspect.isroutine):\r
+ # if __all__ exists, believe it. Otherwise use old heuristic.\r
+ if (all is not None or\r
+ inspect.isbuiltin(value) or inspect.getmodule(value) is object):\r
+ if visiblename(key, all, object):\r
+ funcs.append((key, value))\r
+ data = []\r
+ for key, value in inspect.getmembers(object, isdata):\r
+ if visiblename(key, all, object):\r
+ data.append((key, value))\r
+\r
+ modpkgs = []\r
+ modpkgs_names = set()\r
+ if hasattr(object, '__path__'):\r
+ for importer, modname, ispkg in pkgutil.iter_modules(object.__path__):\r
+ modpkgs_names.add(modname)\r
+ if ispkg:\r
+ modpkgs.append(modname + ' (package)')\r
+ else:\r
+ modpkgs.append(modname)\r
+\r
+ modpkgs.sort()\r
+ result = result + self.section(\r
+ 'PACKAGE CONTENTS', join(modpkgs, '\n'))\r
+\r
+ # Detect submodules as sometimes created by C extensions\r
+ submodules = []\r
+ for key, value in inspect.getmembers(object, inspect.ismodule):\r
+ if value.__name__.startswith(name + '.') and key not in modpkgs_names:\r
+ submodules.append(key)\r
+ if submodules:\r
+ submodules.sort()\r
+ result = result + self.section(\r
+ 'SUBMODULES', join(submodules, '\n'))\r
+\r
+ if classes:\r
+ classlist = map(lambda key_value: key_value[1], classes)\r
+ contents = [self.formattree(\r
+ inspect.getclasstree(classlist, 1), name)]\r
+ for key, value in classes:\r
+ contents.append(self.document(value, key, name))\r
+ result = result + self.section('CLASSES', join(contents, '\n'))\r
+\r
+ if funcs:\r
+ contents = []\r
+ for key, value in funcs:\r
+ contents.append(self.document(value, key, name))\r
+ result = result + self.section('FUNCTIONS', join(contents, '\n'))\r
+\r
+ if data:\r
+ contents = []\r
+ for key, value in data:\r
+ contents.append(self.docother(value, key, name, maxlen=70))\r
+ result = result + self.section('DATA', join(contents, '\n'))\r
+\r
+ if hasattr(object, '__version__'):\r
+ version = _binstr(object.__version__)\r
+ if version[:11] == '$' + 'Revision: ' and version[-1:] == '$':\r
+ version = strip(version[11:-1])\r
+ result = result + self.section('VERSION', version)\r
+ if hasattr(object, '__date__'):\r
+ result = result + self.section('DATE', _binstr(object.__date__))\r
+ if hasattr(object, '__author__'):\r
+ result = result + self.section('AUTHOR', _binstr(object.__author__))\r
+ if hasattr(object, '__credits__'):\r
+ result = result + self.section('CREDITS', _binstr(object.__credits__))\r
+ return result\r
+\r
+ def docclass(self, object, name=None, mod=None, *ignored):\r
+ """Produce text documentation for a given class object."""\r
+ realname = object.__name__\r
+ name = name or realname\r
+ bases = object.__bases__\r
+\r
+ def makename(c, m=object.__module__):\r
+ return classname(c, m)\r
+\r
+ if name == realname:\r
+ title = 'class ' + self.bold(realname)\r
+ else:\r
+ title = self.bold(name) + ' = class ' + realname\r
+ if bases:\r
+ parents = map(makename, bases)\r
+ title = title + '(%s)' % join(parents, ', ')\r
+\r
+ doc = getdoc(object)\r
+ contents = doc and [doc + '\n'] or []\r
+ push = contents.append\r
+\r
+ # List the mro, if non-trivial.\r
+ mro = deque(inspect.getmro(object))\r
+ if len(mro) > 2:\r
+ push("Method resolution order:")\r
+ for base in mro:\r
+ push(' ' + makename(base))\r
+ push('')\r
+\r
+ # Cute little class to pump out a horizontal rule between sections.\r
+ class HorizontalRule:\r
+ def __init__(self):\r
+ self.needone = 0\r
+ def maybe(self):\r
+ if self.needone:\r
+ push('-' * 70)\r
+ self.needone = 1\r
+ hr = HorizontalRule()\r
+\r
+ def spill(msg, attrs, predicate):\r
+ ok, attrs = _split_list(attrs, predicate)\r
+ if ok:\r
+ hr.maybe()\r
+ push(msg)\r
+ for name, kind, homecls, value in ok:\r
+ try:\r
+ value = getattr(object, name)\r
+ except Exception:\r
+ # Some descriptors may meet a failure in their __get__.\r
+ # (bug #1785)\r
+ push(self._docdescriptor(name, value, mod))\r
+ else:\r
+ push(self.document(value,\r
+ name, mod, object))\r
+ return attrs\r
+\r
+ def spilldescriptors(msg, attrs, predicate):\r
+ ok, attrs = _split_list(attrs, predicate)\r
+ if ok:\r
+ hr.maybe()\r
+ push(msg)\r
+ for name, kind, homecls, value in ok:\r
+ push(self._docdescriptor(name, value, mod))\r
+ return attrs\r
+\r
+ def spilldata(msg, attrs, predicate):\r
+ ok, attrs = _split_list(attrs, predicate)\r
+ if ok:\r
+ hr.maybe()\r
+ push(msg)\r
+ for name, kind, homecls, value in ok:\r
+ if (hasattr(value, '__call__') or\r
+ inspect.isdatadescriptor(value)):\r
+ doc = getdoc(value)\r
+ else:\r
+ doc = None\r
+ push(self.docother(getattr(object, name),\r
+ name, mod, maxlen=70, doc=doc) + '\n')\r
+ return attrs\r
+\r
+ attrs = filter(lambda data: visiblename(data[0], obj=object),\r
+ classify_class_attrs(object))\r
+ while attrs:\r
+ if mro:\r
+ thisclass = mro.popleft()\r
+ else:\r
+ thisclass = attrs[0][2]\r
+ attrs, inherited = _split_list(attrs, lambda t: t[2] is thisclass)\r
+\r
+ if thisclass is __builtin__.object:\r
+ attrs = inherited\r
+ continue\r
+ elif thisclass is object:\r
+ tag = "defined here"\r
+ else:\r
+ tag = "inherited from %s" % classname(thisclass,\r
+ object.__module__)\r
+\r
+ # Sort attrs by name.\r
+ attrs.sort()\r
+\r
+ # Pump out the attrs, segregated by kind.\r
+ attrs = spill("Methods %s:\n" % tag, attrs,\r
+ lambda t: t[1] == 'method')\r
+ attrs = spill("Class methods %s:\n" % tag, attrs,\r
+ lambda t: t[1] == 'class method')\r
+ attrs = spill("Static methods %s:\n" % tag, attrs,\r
+ lambda t: t[1] == 'static method')\r
+ attrs = spilldescriptors("Data descriptors %s:\n" % tag, attrs,\r
+ lambda t: t[1] == 'data descriptor')\r
+ attrs = spilldata("Data and other attributes %s:\n" % tag, attrs,\r
+ lambda t: t[1] == 'data')\r
+ assert attrs == []\r
+ attrs = inherited\r
+\r
+ contents = '\n'.join(contents)\r
+ if not contents:\r
+ return title + '\n'\r
+ return title + '\n' + self.indent(rstrip(contents), ' | ') + '\n'\r
+\r
+ def formatvalue(self, object):\r
+ """Format an argument default value as text."""\r
+ return '=' + self.repr(object)\r
+\r
+ def docroutine(self, object, name=None, mod=None, cl=None):\r
+ """Produce text documentation for a function or method object."""\r
+ realname = object.__name__\r
+ name = name or realname\r
+ note = ''\r
+ skipdocs = 0\r
+ if inspect.ismethod(object):\r
+ imclass = object.im_class\r
+ if cl:\r
+ if imclass is not cl:\r
+ note = ' from ' + classname(imclass, mod)\r
+ else:\r
+ if object.im_self is not None:\r
+ note = ' method of %s instance' % classname(\r
+ object.im_self.__class__, mod)\r
+ else:\r
+ note = ' unbound %s method' % classname(imclass,mod)\r
+ object = object.im_func\r
+\r
+ if name == realname:\r
+ title = self.bold(realname)\r
+ else:\r
+ if (cl and realname in cl.__dict__ and\r
+ cl.__dict__[realname] is object):\r
+ skipdocs = 1\r
+ title = self.bold(name) + ' = ' + realname\r
+ if inspect.isfunction(object):\r
+ args, varargs, varkw, defaults = inspect.getargspec(object)\r
+ argspec = inspect.formatargspec(\r
+ args, varargs, varkw, defaults, formatvalue=self.formatvalue)\r
+ if realname == '<lambda>':\r
+ title = self.bold(name) + ' lambda '\r
+ argspec = argspec[1:-1] # remove parentheses\r
+ else:\r
+ argspec = '(...)'\r
+ decl = title + argspec + note\r
+\r
+ if skipdocs:\r
+ return decl + '\n'\r
+ else:\r
+ doc = getdoc(object) or ''\r
+ return decl + '\n' + (doc and rstrip(self.indent(doc)) + '\n')\r
+\r
+ def _docdescriptor(self, name, value, mod):\r
+ results = []\r
+ push = results.append\r
+\r
+ if name:\r
+ push(self.bold(name))\r
+ push('\n')\r
+ doc = getdoc(value) or ''\r
+ if doc:\r
+ push(self.indent(doc))\r
+ push('\n')\r
+ return ''.join(results)\r
+\r
+ def docproperty(self, object, name=None, mod=None, cl=None):\r
+ """Produce text documentation for a property."""\r
+ return self._docdescriptor(name, object, mod)\r
+\r
+ def docdata(self, object, name=None, mod=None, cl=None):\r
+ """Produce text documentation for a data descriptor."""\r
+ return self._docdescriptor(name, object, mod)\r
+\r
+ def docother(self, object, name=None, mod=None, parent=None, maxlen=None, doc=None):\r
+ """Produce text documentation for a data object."""\r
+ repr = self.repr(object)\r
+ if maxlen:\r
+ line = (name and name + ' = ' or '') + repr\r
+ chop = maxlen - len(line)\r
+ if chop < 0: repr = repr[:chop] + '...'\r
+ line = (name and self.bold(name) + ' = ' or '') + repr\r
+ if doc is not None:\r
+ line += '\n' + self.indent(str(doc))\r
+ return line\r
+\r
+# --------------------------------------------------------- user interfaces\r
+\r
+def pager(text):\r
+ """The first time this is called, determine what kind of pager to use."""\r
+ global pager\r
+ pager = getpager()\r
+ pager(text)\r
+\r
+def getpager():\r
+ """Decide what method to use for paging through text."""\r
+ if type(sys.stdout) is not types.FileType:\r
+ return plainpager\r
+ if not hasattr(sys.stdin, "isatty"):\r
+ return plainpager\r
+ if not sys.stdin.isatty() or not sys.stdout.isatty():\r
+ return plainpager\r
+ if 'PAGER' in os.environ:\r
+ if sys.platform == 'win32': # pipes completely broken in Windows\r
+ return lambda text: tempfilepager(plain(text), os.environ['PAGER'])\r
+ elif os.environ.get('TERM') in ('dumb', 'emacs'):\r
+ return lambda text: pipepager(plain(text), os.environ['PAGER'])\r
+ else:\r
+ return lambda text: pipepager(text, os.environ['PAGER'])\r
+ if os.environ.get('TERM') in ('dumb', 'emacs'):\r
+ return plainpager\r
+ if sys.platform == 'win32' or sys.platform.startswith('os2'):\r
+ return lambda text: tempfilepager(plain(text), 'more <')\r
+ if hasattr(os, 'system') and os.system('(less) 2>/dev/null') == 0:\r
+ return lambda text: pipepager(text, 'less')\r
+\r
+ import tempfile\r
+ (fd, filename) = tempfile.mkstemp()\r
+ os.close(fd)\r
+ try:\r
+ if hasattr(os, 'system') and os.system('more "%s"' % filename) == 0:\r
+ return lambda text: pipepager(text, 'more')\r
+ else:\r
+ return ttypager\r
+ finally:\r
+ os.unlink(filename)\r
+\r
+def plain(text):\r
+ """Remove boldface formatting from text."""\r
+ return re.sub('.\b', '', text)\r
+\r
+def pipepager(text, cmd):\r
+ """Page through text by feeding it to another program."""\r
+ pipe = os.popen(cmd, 'w')\r
+ try:\r
+ pipe.write(_encode(text))\r
+ pipe.close()\r
+ except IOError:\r
+ pass # Ignore broken pipes caused by quitting the pager program.\r
+\r
+def tempfilepager(text, cmd):\r
+ """Page through text by invoking a program on a temporary file."""\r
+ import tempfile\r
+ filename = tempfile.mktemp()\r
+ file = open(filename, 'w')\r
+ file.write(_encode(text))\r
+ file.close()\r
+ try:\r
+ os.system(cmd + ' "' + filename + '"')\r
+ finally:\r
+ os.unlink(filename)\r
+\r
+def ttypager(text):\r
+ """Page through text on a text terminal."""\r
+ lines = plain(_encode(plain(text), getattr(sys.stdout, 'encoding', _encoding))).split('\n')\r
+ try:\r
+ import tty\r
+ fd = sys.stdin.fileno()\r
+ old = tty.tcgetattr(fd)\r
+ tty.setcbreak(fd)\r
+ getchar = lambda: sys.stdin.read(1)\r
+ except (ImportError, AttributeError):\r
+ tty = None\r
+ getchar = lambda: sys.stdin.readline()[:-1][:1]\r
+\r
+ try:\r
+ try:\r
+ h = int(os.environ.get('LINES', 0))\r
+ except ValueError:\r
+ h = 0\r
+ if h <= 1:\r
+ h = 25\r
+ r = inc = h - 1\r
+ sys.stdout.write(join(lines[:inc], '\n') + '\n')\r
+ while lines[r:]:\r
+ sys.stdout.write('-- more --')\r
+ sys.stdout.flush()\r
+ c = getchar()\r
+\r
+ if c in ('q', 'Q'):\r
+ sys.stdout.write('\r \r')\r
+ break\r
+ elif c in ('\r', '\n'):\r
+ sys.stdout.write('\r \r' + lines[r] + '\n')\r
+ r = r + 1\r
+ continue\r
+ if c in ('b', 'B', '\x1b'):\r
+ r = r - inc - inc\r
+ if r < 0: r = 0\r
+ sys.stdout.write('\n' + join(lines[r:r+inc], '\n') + '\n')\r
+ r = r + inc\r
+\r
+ finally:\r
+ if tty:\r
+ tty.tcsetattr(fd, tty.TCSAFLUSH, old)\r
+\r
+def plainpager(text):\r
+ """Simply print unformatted text. This is the ultimate fallback."""\r
+ sys.stdout.write(_encode(plain(text), getattr(sys.stdout, 'encoding', _encoding)))\r
+\r
+def describe(thing):\r
+ """Produce a short description of the given thing."""\r
+ if inspect.ismodule(thing):\r
+ if thing.__name__ in sys.builtin_module_names:\r
+ return 'built-in module ' + thing.__name__\r
+ if hasattr(thing, '__path__'):\r
+ return 'package ' + thing.__name__\r
+ else:\r
+ return 'module ' + thing.__name__\r
+ if inspect.isbuiltin(thing):\r
+ return 'built-in function ' + thing.__name__\r
+ if inspect.isgetsetdescriptor(thing):\r
+ return 'getset descriptor %s.%s.%s' % (\r
+ thing.__objclass__.__module__, thing.__objclass__.__name__,\r
+ thing.__name__)\r
+ if inspect.ismemberdescriptor(thing):\r
+ return 'member descriptor %s.%s.%s' % (\r
+ thing.__objclass__.__module__, thing.__objclass__.__name__,\r
+ thing.__name__)\r
+ if inspect.isclass(thing):\r
+ return 'class ' + thing.__name__\r
+ if inspect.isfunction(thing):\r
+ return 'function ' + thing.__name__\r
+ if inspect.ismethod(thing):\r
+ return 'method ' + thing.__name__\r
+ if type(thing) is types.InstanceType:\r
+ return 'instance of ' + thing.__class__.__name__\r
+ return type(thing).__name__\r
+\r
+def locate(path, forceload=0):\r
+ """Locate an object by name or dotted path, importing as necessary."""\r
+ parts = [part for part in split(path, '.') if part]\r
+ module, n = None, 0\r
+ while n < len(parts):\r
+ nextmodule = safeimport(join(parts[:n+1], '.'), forceload)\r
+ if nextmodule: module, n = nextmodule, n + 1\r
+ else: break\r
+ if module:\r
+ object = module\r
+ else:\r
+ object = __builtin__\r
+ for part in parts[n:]:\r
+ try:\r
+ object = getattr(object, part)\r
+ except AttributeError:\r
+ return None\r
+ return object\r
+\r
+# --------------------------------------- interactive interpreter interface\r
+\r
+text = TextDoc()\r
+html = HTMLDoc()\r
+\r
+class _OldStyleClass: pass\r
+_OLD_INSTANCE_TYPE = type(_OldStyleClass())\r
+\r
+def resolve(thing, forceload=0):\r
+ """Given an object or a path to an object, get the object and its name."""\r
+ if isinstance(thing, str):\r
+ object = locate(thing, forceload)\r
+ if object is None:\r
+ raise ImportError, 'no Python documentation found for %r' % thing\r
+ return object, thing\r
+ else:\r
+ name = getattr(thing, '__name__', None)\r
+ return thing, name if isinstance(name, str) else None\r
+\r
+def render_doc(thing, title='Python Library Documentation: %s', forceload=0):\r
+ """Render text documentation, given an object or a path to an object."""\r
+ object, name = resolve(thing, forceload)\r
+ desc = describe(object)\r
+ module = inspect.getmodule(object)\r
+ if name and '.' in name:\r
+ desc += ' in ' + name[:name.rfind('.')]\r
+ elif module and module is not object:\r
+ desc += ' in module ' + module.__name__\r
+ if type(object) is _OLD_INSTANCE_TYPE:\r
+ # If the passed object is an instance of an old-style class,\r
+ # document its available methods instead of its value.\r
+ object = object.__class__\r
+ elif not (inspect.ismodule(object) or\r
+ inspect.isclass(object) or\r
+ inspect.isroutine(object) or\r
+ inspect.isgetsetdescriptor(object) or\r
+ inspect.ismemberdescriptor(object) or\r
+ isinstance(object, property)):\r
+ # If the passed object is a piece of data or an instance,\r
+ # document its available methods instead of its value.\r
+ object = type(object)\r
+ desc += ' object'\r
+ return title % desc + '\n\n' + text.document(object, name)\r
+\r
+def doc(thing, title='Python Library Documentation: %s', forceload=0):\r
+ """Display text documentation, given an object or a path to an object."""\r
+ try:\r
+ pager(render_doc(thing, title, forceload))\r
+ except (ImportError, ErrorDuringImport), value:\r
+ print value\r
+\r
+def writedoc(thing, forceload=0):\r
+ """Write HTML documentation to a file in the current directory."""\r
+ try:\r
+ object, name = resolve(thing, forceload)\r
+ page = html.page(describe(object), html.document(object, name))\r
+ file = open(name + '.html', 'w')\r
+ file.write(page)\r
+ file.close()\r
+ print 'wrote', name + '.html'\r
+ except (ImportError, ErrorDuringImport), value:\r
+ print value\r
+\r
+def writedocs(dir, pkgpath='', done=None):\r
+ """Write out HTML documentation for all modules in a directory tree."""\r
+ if done is None: done = {}\r
+ for importer, modname, ispkg in pkgutil.walk_packages([dir], pkgpath):\r
+ writedoc(modname)\r
+ return\r
+\r
+class Helper:\r
+\r
+ # These dictionaries map a topic name to either an alias, or a tuple\r
+ # (label, seealso-items). The "label" is the label of the corresponding\r
+ # section in the .rst file under Doc/ and an index into the dictionary\r
+ # in pydoc_data/topics.py.\r
+ #\r
+ # CAUTION: if you change one of these dictionaries, be sure to adapt the\r
+ # list of needed labels in Doc/tools/pyspecific.py and\r
+ # regenerate the pydoc_data/topics.py file by running\r
+ # make pydoc-topics\r
+ # in Doc/ and copying the output file into the Lib/ directory.\r
+\r
+ keywords = {\r
+ 'and': 'BOOLEAN',\r
+ 'as': 'with',\r
+ 'assert': ('assert', ''),\r
+ 'break': ('break', 'while for'),\r
+ 'class': ('class', 'CLASSES SPECIALMETHODS'),\r
+ 'continue': ('continue', 'while for'),\r
+ 'def': ('function', ''),\r
+ 'del': ('del', 'BASICMETHODS'),\r
+ 'elif': 'if',\r
+ 'else': ('else', 'while for'),\r
+ 'except': 'try',\r
+ 'exec': ('exec', ''),\r
+ 'finally': 'try',\r
+ 'for': ('for', 'break continue while'),\r
+ 'from': 'import',\r
+ 'global': ('global', 'NAMESPACES'),\r
+ 'if': ('if', 'TRUTHVALUE'),\r
+ 'import': ('import', 'MODULES'),\r
+ 'in': ('in', 'SEQUENCEMETHODS2'),\r
+ 'is': 'COMPARISON',\r
+ 'lambda': ('lambda', 'FUNCTIONS'),\r
+ 'not': 'BOOLEAN',\r
+ 'or': 'BOOLEAN',\r
+ 'pass': ('pass', ''),\r
+ 'print': ('print', ''),\r
+ 'raise': ('raise', 'EXCEPTIONS'),\r
+ 'return': ('return', 'FUNCTIONS'),\r
+ 'try': ('try', 'EXCEPTIONS'),\r
+ 'while': ('while', 'break continue if TRUTHVALUE'),\r
+ 'with': ('with', 'CONTEXTMANAGERS EXCEPTIONS yield'),\r
+ 'yield': ('yield', ''),\r
+ }\r
+ # Either add symbols to this dictionary or to the symbols dictionary\r
+ # directly: Whichever is easier. They are merged later.\r
+ _symbols_inverse = {\r
+ 'STRINGS' : ("'", "'''", "r'", "u'", '"""', '"', 'r"', 'u"'),\r
+ 'OPERATORS' : ('+', '-', '*', '**', '/', '//', '%', '<<', '>>', '&',\r
+ '|', '^', '~', '<', '>', '<=', '>=', '==', '!=', '<>'),\r
+ 'COMPARISON' : ('<', '>', '<=', '>=', '==', '!=', '<>'),\r
+ 'UNARY' : ('-', '~'),\r
+ 'AUGMENTEDASSIGNMENT' : ('+=', '-=', '*=', '/=', '%=', '&=', '|=',\r
+ '^=', '<<=', '>>=', '**=', '//='),\r
+ 'BITWISE' : ('<<', '>>', '&', '|', '^', '~'),\r
+ 'COMPLEX' : ('j', 'J')\r
+ }\r
+ symbols = {\r
+ '%': 'OPERATORS FORMATTING',\r
+ '**': 'POWER',\r
+ ',': 'TUPLES LISTS FUNCTIONS',\r
+ '.': 'ATTRIBUTES FLOAT MODULES OBJECTS',\r
+ '...': 'ELLIPSIS',\r
+ ':': 'SLICINGS DICTIONARYLITERALS',\r
+ '@': 'def class',\r
+ '\\': 'STRINGS',\r
+ '_': 'PRIVATENAMES',\r
+ '__': 'PRIVATENAMES SPECIALMETHODS',\r
+ '`': 'BACKQUOTES',\r
+ '(': 'TUPLES FUNCTIONS CALLS',\r
+ ')': 'TUPLES FUNCTIONS CALLS',\r
+ '[': 'LISTS SUBSCRIPTS SLICINGS',\r
+ ']': 'LISTS SUBSCRIPTS SLICINGS'\r
+ }\r
+ for topic, symbols_ in _symbols_inverse.iteritems():\r
+ for symbol in symbols_:\r
+ topics = symbols.get(symbol, topic)\r
+ if topic not in topics:\r
+ topics = topics + ' ' + topic\r
+ symbols[symbol] = topics\r
+\r
+ topics = {\r
+ 'TYPES': ('types', 'STRINGS UNICODE NUMBERS SEQUENCES MAPPINGS '\r
+ 'FUNCTIONS CLASSES MODULES FILES inspect'),\r
+ 'STRINGS': ('strings', 'str UNICODE SEQUENCES STRINGMETHODS FORMATTING '\r
+ 'TYPES'),\r
+ 'STRINGMETHODS': ('string-methods', 'STRINGS FORMATTING'),\r
+ 'FORMATTING': ('formatstrings', 'OPERATORS'),\r
+ 'UNICODE': ('strings', 'encodings unicode SEQUENCES STRINGMETHODS '\r
+ 'FORMATTING TYPES'),\r
+ 'NUMBERS': ('numbers', 'INTEGER FLOAT COMPLEX TYPES'),\r
+ 'INTEGER': ('integers', 'int range'),\r
+ 'FLOAT': ('floating', 'float math'),\r
+ 'COMPLEX': ('imaginary', 'complex cmath'),\r
+ 'SEQUENCES': ('typesseq', 'STRINGMETHODS FORMATTING xrange LISTS'),\r
+ 'MAPPINGS': 'DICTIONARIES',\r
+ 'FUNCTIONS': ('typesfunctions', 'def TYPES'),\r
+ 'METHODS': ('typesmethods', 'class def CLASSES TYPES'),\r
+ 'CODEOBJECTS': ('bltin-code-objects', 'compile FUNCTIONS TYPES'),\r
+ 'TYPEOBJECTS': ('bltin-type-objects', 'types TYPES'),\r
+ 'FRAMEOBJECTS': 'TYPES',\r
+ 'TRACEBACKS': 'TYPES',\r
+ 'NONE': ('bltin-null-object', ''),\r
+ 'ELLIPSIS': ('bltin-ellipsis-object', 'SLICINGS'),\r
+ 'FILES': ('bltin-file-objects', ''),\r
+ 'SPECIALATTRIBUTES': ('specialattrs', ''),\r
+ 'CLASSES': ('types', 'class SPECIALMETHODS PRIVATENAMES'),\r
+ 'MODULES': ('typesmodules', 'import'),\r
+ 'PACKAGES': 'import',\r
+ 'EXPRESSIONS': ('operator-summary', 'lambda or and not in is BOOLEAN '\r
+ 'COMPARISON BITWISE SHIFTING BINARY FORMATTING POWER '\r
+ 'UNARY ATTRIBUTES SUBSCRIPTS SLICINGS CALLS TUPLES '\r
+ 'LISTS DICTIONARIES BACKQUOTES'),\r
+ 'OPERATORS': 'EXPRESSIONS',\r
+ 'PRECEDENCE': 'EXPRESSIONS',\r
+ 'OBJECTS': ('objects', 'TYPES'),\r
+ 'SPECIALMETHODS': ('specialnames', 'BASICMETHODS ATTRIBUTEMETHODS '\r
+ 'CALLABLEMETHODS SEQUENCEMETHODS1 MAPPINGMETHODS '\r
+ 'SEQUENCEMETHODS2 NUMBERMETHODS CLASSES'),\r
+ 'BASICMETHODS': ('customization', 'cmp hash repr str SPECIALMETHODS'),\r
+ 'ATTRIBUTEMETHODS': ('attribute-access', 'ATTRIBUTES SPECIALMETHODS'),\r
+ 'CALLABLEMETHODS': ('callable-types', 'CALLS SPECIALMETHODS'),\r
+ 'SEQUENCEMETHODS1': ('sequence-types', 'SEQUENCES SEQUENCEMETHODS2 '\r
+ 'SPECIALMETHODS'),\r
+ 'SEQUENCEMETHODS2': ('sequence-methods', 'SEQUENCES SEQUENCEMETHODS1 '\r
+ 'SPECIALMETHODS'),\r
+ 'MAPPINGMETHODS': ('sequence-types', 'MAPPINGS SPECIALMETHODS'),\r
+ 'NUMBERMETHODS': ('numeric-types', 'NUMBERS AUGMENTEDASSIGNMENT '\r
+ 'SPECIALMETHODS'),\r
+ 'EXECUTION': ('execmodel', 'NAMESPACES DYNAMICFEATURES EXCEPTIONS'),\r
+ 'NAMESPACES': ('naming', 'global ASSIGNMENT DELETION DYNAMICFEATURES'),\r
+ 'DYNAMICFEATURES': ('dynamic-features', ''),\r
+ 'SCOPING': 'NAMESPACES',\r
+ 'FRAMES': 'NAMESPACES',\r
+ 'EXCEPTIONS': ('exceptions', 'try except finally raise'),\r
+ 'COERCIONS': ('coercion-rules','CONVERSIONS'),\r
+ 'CONVERSIONS': ('conversions', 'COERCIONS'),\r
+ 'IDENTIFIERS': ('identifiers', 'keywords SPECIALIDENTIFIERS'),\r
+ 'SPECIALIDENTIFIERS': ('id-classes', ''),\r
+ 'PRIVATENAMES': ('atom-identifiers', ''),\r
+ 'LITERALS': ('atom-literals', 'STRINGS BACKQUOTES NUMBERS '\r
+ 'TUPLELITERALS LISTLITERALS DICTIONARYLITERALS'),\r
+ 'TUPLES': 'SEQUENCES',\r
+ 'TUPLELITERALS': ('exprlists', 'TUPLES LITERALS'),\r
+ 'LISTS': ('typesseq-mutable', 'LISTLITERALS'),\r
+ 'LISTLITERALS': ('lists', 'LISTS LITERALS'),\r
+ 'DICTIONARIES': ('typesmapping', 'DICTIONARYLITERALS'),\r
+ 'DICTIONARYLITERALS': ('dict', 'DICTIONARIES LITERALS'),\r
+ 'BACKQUOTES': ('string-conversions', 'repr str STRINGS LITERALS'),\r
+ 'ATTRIBUTES': ('attribute-references', 'getattr hasattr setattr '\r
+ 'ATTRIBUTEMETHODS'),\r
+ 'SUBSCRIPTS': ('subscriptions', 'SEQUENCEMETHODS1'),\r
+ 'SLICINGS': ('slicings', 'SEQUENCEMETHODS2'),\r
+ 'CALLS': ('calls', 'EXPRESSIONS'),\r
+ 'POWER': ('power', 'EXPRESSIONS'),\r
+ 'UNARY': ('unary', 'EXPRESSIONS'),\r
+ 'BINARY': ('binary', 'EXPRESSIONS'),\r
+ 'SHIFTING': ('shifting', 'EXPRESSIONS'),\r
+ 'BITWISE': ('bitwise', 'EXPRESSIONS'),\r
+ 'COMPARISON': ('comparisons', 'EXPRESSIONS BASICMETHODS'),\r
+ 'BOOLEAN': ('booleans', 'EXPRESSIONS TRUTHVALUE'),\r
+ 'ASSERTION': 'assert',\r
+ 'ASSIGNMENT': ('assignment', 'AUGMENTEDASSIGNMENT'),\r
+ 'AUGMENTEDASSIGNMENT': ('augassign', 'NUMBERMETHODS'),\r
+ 'DELETION': 'del',\r
+ 'PRINTING': 'print',\r
+ 'RETURNING': 'return',\r
+ 'IMPORTING': 'import',\r
+ 'CONDITIONAL': 'if',\r
+ 'LOOPING': ('compound', 'for while break continue'),\r
+ 'TRUTHVALUE': ('truth', 'if while and or not BASICMETHODS'),\r
+ 'DEBUGGING': ('debugger', 'pdb'),\r
+ 'CONTEXTMANAGERS': ('context-managers', 'with'),\r
+ }\r
+\r
+ def __init__(self, input=None, output=None):\r
+ self._input = input\r
+ self._output = output\r
+\r
+ input = property(lambda self: self._input or sys.stdin)\r
+ output = property(lambda self: self._output or sys.stdout)\r
+\r
+ def __repr__(self):\r
+ if inspect.stack()[1][3] == '?':\r
+ self()\r
+ return ''\r
+ return '<pydoc.Helper instance>'\r
+\r
+ _GoInteractive = object()\r
+ def __call__(self, request=_GoInteractive):\r
+ if request is not self._GoInteractive:\r
+ self.help(request)\r
+ else:\r
+ self.intro()\r
+ self.interact()\r
+ self.output.write('''\r
+You are now leaving help and returning to the Python interpreter.\r
+If you want to ask for help on a particular object directly from the\r
+interpreter, you can type "help(object)". Executing "help('string')"\r
+has the same effect as typing a particular string at the help> prompt.\r
+''')\r
+\r
+ def interact(self):\r
+ self.output.write('\n')\r
+ while True:\r
+ try:\r
+ request = self.getline('help> ')\r
+ if not request: break\r
+ except (KeyboardInterrupt, EOFError):\r
+ break\r
+ request = strip(replace(request, '"', '', "'", ''))\r
+ if lower(request) in ('q', 'quit'): break\r
+ self.help(request)\r
+\r
+ def getline(self, prompt):\r
+ """Read one line, using raw_input when available."""\r
+ if self.input is sys.stdin:\r
+ return raw_input(prompt)\r
+ else:\r
+ self.output.write(prompt)\r
+ self.output.flush()\r
+ return self.input.readline()\r
+\r
+ def help(self, request):\r
+ if type(request) is type(''):\r
+ request = request.strip()\r
+ if request == 'help': self.intro()\r
+ elif request == 'keywords': self.listkeywords()\r
+ elif request == 'symbols': self.listsymbols()\r
+ elif request == 'topics': self.listtopics()\r
+ elif request == 'modules': self.listmodules()\r
+ elif request[:8] == 'modules ':\r
+ self.listmodules(split(request)[1])\r
+ elif request in self.symbols: self.showsymbol(request)\r
+ elif request in self.keywords: self.showtopic(request)\r
+ elif request in self.topics: self.showtopic(request)\r
+ elif request: doc(request, 'Help on %s:')\r
+ elif isinstance(request, Helper): self()\r
+ else: doc(request, 'Help on %s:')\r
+ self.output.write('\n')\r
+\r
+ def intro(self):\r
+ self.output.write('''\r
+Welcome to Python %s! This is the online help utility.\r
+\r
+If this is your first time using Python, you should definitely check out\r
+the tutorial on the Internet at http://docs.python.org/%s/tutorial/.\r
+\r
+Enter the name of any module, keyword, or topic to get help on writing\r
+Python programs and using Python modules. To quit this help utility and\r
+return to the interpreter, just type "quit".\r
+\r
+To get a list of available modules, keywords, or topics, type "modules",\r
+"keywords", or "topics". Each module also comes with a one-line summary\r
+of what it does; to list the modules whose summaries contain a given word\r
+such as "spam", type "modules spam".\r
+''' % tuple([sys.version[:3]]*2))\r
+\r
+ def list(self, items, columns=4, width=80):\r
+ items = items[:]\r
+ items.sort()\r
+ colw = width / columns\r
+ rows = (len(items) + columns - 1) / columns\r
+ for row in range(rows):\r
+ for col in range(columns):\r
+ i = col * rows + row\r
+ if i < len(items):\r
+ self.output.write(items[i])\r
+ if col < columns - 1:\r
+ self.output.write(' ' + ' ' * (colw-1 - len(items[i])))\r
+ self.output.write('\n')\r
+\r
+ def listkeywords(self):\r
+ self.output.write('''\r
+Here is a list of the Python keywords. Enter any keyword to get more help.\r
+\r
+''')\r
+ self.list(self.keywords.keys())\r
+\r
+ def listsymbols(self):\r
+ self.output.write('''\r
+Here is a list of the punctuation symbols which Python assigns special meaning\r
+to. Enter any symbol to get more help.\r
+\r
+''')\r
+ self.list(self.symbols.keys())\r
+\r
+ def listtopics(self):\r
+ self.output.write('''\r
+Here is a list of available topics. Enter any topic name to get more help.\r
+\r
+''')\r
+ self.list(self.topics.keys())\r
+\r
+ def showtopic(self, topic, more_xrefs=''):\r
+ try:\r
+ import pydoc_data.topics\r
+ except ImportError:\r
+ self.output.write('''\r
+Sorry, topic and keyword documentation is not available because the\r
+module "pydoc_data.topics" could not be found.\r
+''')\r
+ return\r
+ target = self.topics.get(topic, self.keywords.get(topic))\r
+ if not target:\r
+ self.output.write('no documentation found for %s\n' % repr(topic))\r
+ return\r
+ if type(target) is type(''):\r
+ return self.showtopic(target, more_xrefs)\r
+\r
+ label, xrefs = target\r
+ try:\r
+ doc = pydoc_data.topics.topics[label]\r
+ except KeyError:\r
+ self.output.write('no documentation found for %s\n' % repr(topic))\r
+ return\r
+ pager(strip(doc) + '\n')\r
+ if more_xrefs:\r
+ xrefs = (xrefs or '') + ' ' + more_xrefs\r
+ if xrefs:\r
+ import StringIO, formatter\r
+ buffer = StringIO.StringIO()\r
+ formatter.DumbWriter(buffer).send_flowing_data(\r
+ 'Related help topics: ' + join(split(xrefs), ', ') + '\n')\r
+ self.output.write('\n%s\n' % buffer.getvalue())\r
+\r
+ def showsymbol(self, symbol):\r
+ target = self.symbols[symbol]\r
+ topic, _, xrefs = target.partition(' ')\r
+ self.showtopic(topic, xrefs)\r
+\r
+ def listmodules(self, key=''):\r
+ if key:\r
+ self.output.write('''\r
+Here is a list of matching modules. Enter any module name to get more help.\r
+\r
+''')\r
+ apropos(key)\r
+ else:\r
+ self.output.write('''\r
+Please wait a moment while I gather a list of all available modules...\r
+\r
+''')\r
+ modules = {}\r
+ def callback(path, modname, desc, modules=modules):\r
+ if modname and modname[-9:] == '.__init__':\r
+ modname = modname[:-9] + ' (package)'\r
+ if find(modname, '.') < 0:\r
+ modules[modname] = 1\r
+ def onerror(modname):\r
+ callback(None, modname, None)\r
+ ModuleScanner().run(callback, onerror=onerror)\r
+ self.list(modules.keys())\r
+ self.output.write('''\r
+Enter any module name to get more help. Or, type "modules spam" to search\r
+for modules whose descriptions contain the word "spam".\r
+''')\r
+\r
+help = Helper()\r
+\r
+class Scanner:\r
+ """A generic tree iterator."""\r
+ def __init__(self, roots, children, descendp):\r
+ self.roots = roots[:]\r
+ self.state = []\r
+ self.children = children\r
+ self.descendp = descendp\r
+\r
+ def next(self):\r
+ if not self.state:\r
+ if not self.roots:\r
+ return None\r
+ root = self.roots.pop(0)\r
+ self.state = [(root, self.children(root))]\r
+ node, children = self.state[-1]\r
+ if not children:\r
+ self.state.pop()\r
+ return self.next()\r
+ child = children.pop(0)\r
+ if self.descendp(child):\r
+ self.state.append((child, self.children(child)))\r
+ return child\r
+\r
+\r
+class ModuleScanner:\r
+ """An interruptible scanner that searches module synopses."""\r
+\r
+ def run(self, callback, key=None, completer=None, onerror=None):\r
+ if key: key = lower(key)\r
+ self.quit = False\r
+ seen = {}\r
+\r
+ for modname in sys.builtin_module_names:\r
+ if modname != '__main__':\r
+ seen[modname] = 1\r
+ if key is None:\r
+ callback(None, modname, '')\r
+ else:\r
+ desc = split(__import__(modname).__doc__ or '', '\n')[0]\r
+ if find(lower(modname + ' - ' + desc), key) >= 0:\r
+ callback(None, modname, desc)\r
+\r
+ for importer, modname, ispkg in pkgutil.walk_packages(onerror=onerror):\r
+ if self.quit:\r
+ break\r
+ if key is None:\r
+ callback(None, modname, '')\r
+ else:\r
+ loader = importer.find_module(modname)\r
+ if hasattr(loader,'get_source'):\r
+ import StringIO\r
+ desc = source_synopsis(\r
+ StringIO.StringIO(loader.get_source(modname))\r
+ ) or ''\r
+ if hasattr(loader,'get_filename'):\r
+ path = loader.get_filename(modname)\r
+ else:\r
+ path = None\r
+ else:\r
+ module = loader.load_module(modname)\r
+ desc = module.__doc__.splitlines()[0] if module.__doc__ else ''\r
+ path = getattr(module,'__file__',None)\r
+ if find(lower(modname + ' - ' + desc), key) >= 0:\r
+ callback(path, modname, desc)\r
+\r
+ if completer:\r
+ completer()\r
+\r
+def apropos(key):\r
+ """Print all the one-line module summaries that contain a substring."""\r
+ def callback(path, modname, desc):\r
+ if modname[-9:] == '.__init__':\r
+ modname = modname[:-9] + ' (package)'\r
+ print modname, desc and '- ' + desc\r
+ def onerror(modname):\r
+ pass\r
+ with warnings.catch_warnings():\r
+ warnings.filterwarnings('ignore') # ignore problems during import\r
+ ModuleScanner().run(callback, key, onerror=onerror)\r
+\r
+# --------------------------------------------------- web browser interface\r
+\r
+def serve(port, callback=None, completer=None):\r
+ import BaseHTTPServer, mimetools, select\r
+\r
+ # Patch up mimetools.Message so it doesn't break if rfc822 is reloaded.\r
+ class Message(mimetools.Message):\r
+ def __init__(self, fp, seekable=1):\r
+ Message = self.__class__\r
+ Message.__bases__[0].__bases__[0].__init__(self, fp, seekable)\r
+ self.encodingheader = self.getheader('content-transfer-encoding')\r
+ self.typeheader = self.getheader('content-type')\r
+ self.parsetype()\r
+ self.parseplist()\r
+\r
+ class DocHandler(BaseHTTPServer.BaseHTTPRequestHandler):\r
+ def send_document(self, title, contents):\r
+ try:\r
+ self.send_response(200)\r
+ self.send_header('Content-Type', 'text/html')\r
+ self.end_headers()\r
+ self.wfile.write(html.page(title, contents))\r
+ except IOError: pass\r
+\r
+ def do_GET(self):\r
+ path = self.path\r
+ if path[-5:] == '.html': path = path[:-5]\r
+ if path[:1] == '/': path = path[1:]\r
+ if path and path != '.':\r
+ try:\r
+ obj = locate(path, forceload=1)\r
+ except ErrorDuringImport, value:\r
+ self.send_document(path, html.escape(str(value)))\r
+ return\r
+ if obj:\r
+ self.send_document(describe(obj), html.document(obj, path))\r
+ else:\r
+ self.send_document(path,\r
+'no Python documentation found for %s' % repr(path))\r
+ else:\r
+ heading = html.heading(\r
+'<big><big><strong>Python: Index of Modules</strong></big></big>',\r
+'#ffffff', '#7799ee')\r
+ def bltinlink(name):\r
+ return '<a href="%s.html">%s</a>' % (name, name)\r
+ names = filter(lambda x: x != '__main__',\r
+ sys.builtin_module_names)\r
+ contents = html.multicolumn(names, bltinlink)\r
+ indices = ['<p>' + html.bigsection(\r
+ 'Built-in Modules', '#ffffff', '#ee77aa', contents)]\r
+\r
+ seen = {}\r
+ for dir in sys.path:\r
+ indices.append(html.index(dir, seen))\r
+ contents = heading + join(indices) + '''<p align=right>\r
+<font color="#909090" face="helvetica, arial"><strong>\r
+pydoc</strong> by Ka-Ping Yee <ping@lfw.org></font>'''\r
+ self.send_document('Index of Modules', contents)\r
+\r
+ def log_message(self, *args): pass\r
+\r
+ class DocServer(BaseHTTPServer.HTTPServer):\r
+ def __init__(self, port, callback):\r
+ host = 'localhost'\r
+ self.address = (host, port)\r
+ self.callback = callback\r
+ self.base.__init__(self, self.address, self.handler)\r
+\r
+ def serve_until_quit(self):\r
+ import select\r
+ self.quit = False\r
+ while not self.quit:\r
+ rd, wr, ex = select.select([self.socket.fileno()], [], [], 1)\r
+ if rd: self.handle_request()\r
+\r
+ def server_activate(self):\r
+ self.base.server_activate(self)\r
+ self.url = 'http://%s:%d/' % (self.address[0], self.server_port)\r
+ if self.callback: self.callback(self)\r
+\r
+ DocServer.base = BaseHTTPServer.HTTPServer\r
+ DocServer.handler = DocHandler\r
+ DocHandler.MessageClass = Message\r
+ try:\r
+ try:\r
+ DocServer(port, callback).serve_until_quit()\r
+ except (KeyboardInterrupt, select.error):\r
+ pass\r
+ finally:\r
+ if completer: completer()\r
+\r
+# ----------------------------------------------------- graphical interface\r
+\r
+def gui():\r
+ """Graphical interface (starts web server and pops up a control window)."""\r
+ class GUI:\r
+ def __init__(self, window, port=7464):\r
+ self.window = window\r
+ self.server = None\r
+ self.scanner = None\r
+\r
+ import Tkinter\r
+ self.server_frm = Tkinter.Frame(window)\r
+ self.title_lbl = Tkinter.Label(self.server_frm,\r
+ text='Starting server...\n ')\r
+ self.open_btn = Tkinter.Button(self.server_frm,\r
+ text='open browser', command=self.open, state='disabled')\r
+ self.quit_btn = Tkinter.Button(self.server_frm,\r
+ text='quit serving', command=self.quit, state='disabled')\r
+\r
+ self.search_frm = Tkinter.Frame(window)\r
+ self.search_lbl = Tkinter.Label(self.search_frm, text='Search for')\r
+ self.search_ent = Tkinter.Entry(self.search_frm)\r
+ self.search_ent.bind('<Return>', self.search)\r
+ self.stop_btn = Tkinter.Button(self.search_frm,\r
+ text='stop', pady=0, command=self.stop, state='disabled')\r
+ if sys.platform == 'win32':\r
+ # Trying to hide and show this button crashes under Windows.\r
+ self.stop_btn.pack(side='right')\r
+\r
+ self.window.title('pydoc')\r
+ self.window.protocol('WM_DELETE_WINDOW', self.quit)\r
+ self.title_lbl.pack(side='top', fill='x')\r
+ self.open_btn.pack(side='left', fill='x', expand=1)\r
+ self.quit_btn.pack(side='right', fill='x', expand=1)\r
+ self.server_frm.pack(side='top', fill='x')\r
+\r
+ self.search_lbl.pack(side='left')\r
+ self.search_ent.pack(side='right', fill='x', expand=1)\r
+ self.search_frm.pack(side='top', fill='x')\r
+ self.search_ent.focus_set()\r
+\r
+ font = ('helvetica', sys.platform == 'win32' and 8 or 10)\r
+ self.result_lst = Tkinter.Listbox(window, font=font, height=6)\r
+ self.result_lst.bind('<Button-1>', self.select)\r
+ self.result_lst.bind('<Double-Button-1>', self.goto)\r
+ self.result_scr = Tkinter.Scrollbar(window,\r
+ orient='vertical', command=self.result_lst.yview)\r
+ self.result_lst.config(yscrollcommand=self.result_scr.set)\r
+\r
+ self.result_frm = Tkinter.Frame(window)\r
+ self.goto_btn = Tkinter.Button(self.result_frm,\r
+ text='go to selected', command=self.goto)\r
+ self.hide_btn = Tkinter.Button(self.result_frm,\r
+ text='hide results', command=self.hide)\r
+ self.goto_btn.pack(side='left', fill='x', expand=1)\r
+ self.hide_btn.pack(side='right', fill='x', expand=1)\r
+\r
+ self.window.update()\r
+ self.minwidth = self.window.winfo_width()\r
+ self.minheight = self.window.winfo_height()\r
+ self.bigminheight = (self.server_frm.winfo_reqheight() +\r
+ self.search_frm.winfo_reqheight() +\r
+ self.result_lst.winfo_reqheight() +\r
+ self.result_frm.winfo_reqheight())\r
+ self.bigwidth, self.bigheight = self.minwidth, self.bigminheight\r
+ self.expanded = 0\r
+ self.window.wm_geometry('%dx%d' % (self.minwidth, self.minheight))\r
+ self.window.wm_minsize(self.minwidth, self.minheight)\r
+ self.window.tk.willdispatch()\r
+\r
+ import threading\r
+ threading.Thread(\r
+ target=serve, args=(port, self.ready, self.quit)).start()\r
+\r
+ def ready(self, server):\r
+ self.server = server\r
+ self.title_lbl.config(\r
+ text='Python documentation server at\n' + server.url)\r
+ self.open_btn.config(state='normal')\r
+ self.quit_btn.config(state='normal')\r
+\r
+ def open(self, event=None, url=None):\r
+ url = url or self.server.url\r
+ try:\r
+ import webbrowser\r
+ webbrowser.open(url)\r
+ except ImportError: # pre-webbrowser.py compatibility\r
+ if sys.platform == 'win32':\r
+ os.system('start "%s"' % url)\r
+ else:\r
+ rc = os.system('netscape -remote "openURL(%s)" &' % url)\r
+ if rc: os.system('netscape "%s" &' % url)\r
+\r
+ def quit(self, event=None):\r
+ if self.server:\r
+ self.server.quit = 1\r
+ self.window.quit()\r
+\r
+ def search(self, event=None):\r
+ key = self.search_ent.get()\r
+ self.stop_btn.pack(side='right')\r
+ self.stop_btn.config(state='normal')\r
+ self.search_lbl.config(text='Searching for "%s"...' % key)\r
+ self.search_ent.forget()\r
+ self.search_lbl.pack(side='left')\r
+ self.result_lst.delete(0, 'end')\r
+ self.goto_btn.config(state='disabled')\r
+ self.expand()\r
+\r
+ import threading\r
+ if self.scanner:\r
+ self.scanner.quit = 1\r
+ self.scanner = ModuleScanner()\r
+ threading.Thread(target=self.scanner.run,\r
+ args=(self.update, key, self.done)).start()\r
+\r
+ def update(self, path, modname, desc):\r
+ if modname[-9:] == '.__init__':\r
+ modname = modname[:-9] + ' (package)'\r
+ self.result_lst.insert('end',\r
+ modname + ' - ' + (desc or '(no description)'))\r
+\r
+ def stop(self, event=None):\r
+ if self.scanner:\r
+ self.scanner.quit = 1\r
+ self.scanner = None\r
+\r
+ def done(self):\r
+ self.scanner = None\r
+ self.search_lbl.config(text='Search for')\r
+ self.search_lbl.pack(side='left')\r
+ self.search_ent.pack(side='right', fill='x', expand=1)\r
+ if sys.platform != 'win32': self.stop_btn.forget()\r
+ self.stop_btn.config(state='disabled')\r
+\r
+ def select(self, event=None):\r
+ self.goto_btn.config(state='normal')\r
+\r
+ def goto(self, event=None):\r
+ selection = self.result_lst.curselection()\r
+ if selection:\r
+ modname = split(self.result_lst.get(selection[0]))[0]\r
+ self.open(url=self.server.url + modname + '.html')\r
+\r
+ def collapse(self):\r
+ if not self.expanded: return\r
+ self.result_frm.forget()\r
+ self.result_scr.forget()\r
+ self.result_lst.forget()\r
+ self.bigwidth = self.window.winfo_width()\r
+ self.bigheight = self.window.winfo_height()\r
+ self.window.wm_geometry('%dx%d' % (self.minwidth, self.minheight))\r
+ self.window.wm_minsize(self.minwidth, self.minheight)\r
+ self.expanded = 0\r
+\r
+ def expand(self):\r
+ if self.expanded: return\r
+ self.result_frm.pack(side='bottom', fill='x')\r
+ self.result_scr.pack(side='right', fill='y')\r
+ self.result_lst.pack(side='top', fill='both', expand=1)\r
+ self.window.wm_geometry('%dx%d' % (self.bigwidth, self.bigheight))\r
+ self.window.wm_minsize(self.minwidth, self.bigminheight)\r
+ self.expanded = 1\r
+\r
+ def hide(self, event=None):\r
+ self.stop()\r
+ self.collapse()\r
+\r
+ import Tkinter\r
+ try:\r
+ root = Tkinter.Tk()\r
+ # Tk will crash if pythonw.exe has an XP .manifest\r
+ # file and the root has is not destroyed explicitly.\r
+ # If the problem is ever fixed in Tk, the explicit\r
+ # destroy can go.\r
+ try:\r
+ gui = GUI(root)\r
+ root.mainloop()\r
+ finally:\r
+ root.destroy()\r
+ except KeyboardInterrupt:\r
+ pass\r
+\r
+# -------------------------------------------------- command-line interface\r
+\r
+def ispath(x):\r
+ return isinstance(x, str) and find(x, os.sep) >= 0\r
+\r
+def cli():\r
+ """Command-line interface (looks at sys.argv to decide what to do)."""\r
+ import getopt\r
+ class BadUsage: pass\r
+\r
+ # Scripts don't get the current directory in their path by default\r
+ # unless they are run with the '-m' switch\r
+ if '' not in sys.path:\r
+ scriptdir = os.path.dirname(sys.argv[0])\r
+ if scriptdir in sys.path:\r
+ sys.path.remove(scriptdir)\r
+ sys.path.insert(0, '.')\r
+\r
+ try:\r
+ opts, args = getopt.getopt(sys.argv[1:], 'gk:p:w')\r
+ writing = 0\r
+\r
+ for opt, val in opts:\r
+ if opt == '-g':\r
+ gui()\r
+ return\r
+ if opt == '-k':\r
+ apropos(val)\r
+ return\r
+ if opt == '-p':\r
+ try:\r
+ port = int(val)\r
+ except ValueError:\r
+ raise BadUsage\r
+ def ready(server):\r
+ print 'pydoc server ready at %s' % server.url\r
+ def stopped():\r
+ print 'pydoc server stopped'\r
+ serve(port, ready, stopped)\r
+ return\r
+ if opt == '-w':\r
+ writing = 1\r
+\r
+ if not args: raise BadUsage\r
+ for arg in args:\r
+ if ispath(arg) and not os.path.exists(arg):\r
+ print 'file %r does not exist' % arg\r
+ break\r
+ try:\r
+ if ispath(arg) and os.path.isfile(arg):\r
+ arg = importfile(arg)\r
+ if writing:\r
+ if ispath(arg) and os.path.isdir(arg):\r
+ writedocs(arg)\r
+ else:\r
+ writedoc(arg)\r
+ else:\r
+ help.help(arg)\r
+ except ErrorDuringImport, value:\r
+ print value\r
+\r
+ except (getopt.error, BadUsage):\r
+ cmd = os.path.basename(sys.argv[0])\r
+ print """pydoc - the Python documentation tool\r
+\r
+%s <name> ...\r
+ Show text documentation on something. <name> may be the name of a\r
+ Python keyword, topic, function, module, or package, or a dotted\r
+ reference to a class or function within a module or module in a\r
+ package. If <name> contains a '%s', it is used as the path to a\r
+ Python source file to document. If name is 'keywords', 'topics',\r
+ or 'modules', a listing of these things is displayed.\r
+\r
+%s -k <keyword>\r
+ Search for a keyword in the synopsis lines of all available modules.\r
+\r
+%s -p <port>\r
+ Start an HTTP server on the given port on the local machine. Port\r
+ number 0 can be used to get an arbitrary unused port.\r
+\r
+%s -g\r
+ Pop up a graphical interface for finding and serving documentation.\r
+\r
+%s -w <name> ...\r
+ Write out the HTML documentation for a module to a file in the current\r
+ directory. If <name> contains a '%s', it is treated as a filename; if\r
+ it names a directory, documentation is written for all the contents.\r
+""" % (cmd, os.sep, cmd, cmd, cmd, cmd, os.sep)\r
+\r
+if __name__ == '__main__': cli()\r
--- /dev/null
+"""Append module search paths for third-party packages to sys.path.\r
+\r
+****************************************************************\r
+* This module is automatically imported during initialization. *\r
+****************************************************************\r
+\r
+In earlier versions of Python (up to 1.5a3), scripts or modules that\r
+needed to use site-specific modules would place ``import site''\r
+somewhere near the top of their code. Because of the automatic\r
+import, this is no longer necessary (but code that does it still\r
+works).\r
+\r
+This will append site-specific paths to the module search path. On\r
+Unix (including Mac OSX), it starts with sys.prefix and\r
+sys.exec_prefix (if different) and appends\r
+lib/python<version>/site-packages as well as lib/site-python.\r
+On other platforms (such as Windows), it tries each of the\r
+prefixes directly, as well as with lib/site-packages appended. The\r
+resulting directories, if they exist, are appended to sys.path, and\r
+also inspected for path configuration files.\r
+\r
+A path configuration file is a file whose name has the form\r
+<package>.pth; its contents are additional directories (one per line)\r
+to be added to sys.path. Non-existing directories (or\r
+non-directories) are never added to sys.path; no directory is added to\r
+sys.path more than once. Blank lines and lines beginning with\r
+'#' are skipped. Lines starting with 'import' are executed.\r
+\r
+For example, suppose sys.prefix and sys.exec_prefix are set to\r
+/usr/local and there is a directory /usr/local/lib/python2.5/site-packages\r
+with three subdirectories, foo, bar and spam, and two path\r
+configuration files, foo.pth and bar.pth. Assume foo.pth contains the\r
+following:\r
+\r
+ # foo package configuration\r
+ foo\r
+ bar\r
+ bletch\r
+\r
+and bar.pth contains:\r
+\r
+ # bar package configuration\r
+ bar\r
+\r
+Then the following directories are added to sys.path, in this order:\r
+\r
+ /usr/local/lib/python2.5/site-packages/bar\r
+ /usr/local/lib/python2.5/site-packages/foo\r
+\r
+Note that bletch is omitted because it doesn't exist; bar precedes foo\r
+because bar.pth comes alphabetically before foo.pth; and spam is\r
+omitted because it is not mentioned in either path configuration file.\r
+\r
+After these path manipulations, an attempt is made to import a module\r
+named sitecustomize, which can perform arbitrary additional\r
+site-specific customizations. If this import fails with an\r
+ImportError exception, it is silently ignored.\r
+\r
+"""\r
+\r
+import sys\r
+import os\r
+import __builtin__\r
+import traceback\r
+\r
+# Prefixes for site-packages; add additional prefixes like /usr/local here\r
+PREFIXES = [sys.prefix, sys.exec_prefix]\r
+# Enable per user site-packages directory\r
+# set it to False to disable the feature or True to force the feature\r
+ENABLE_USER_SITE = None\r
+\r
+# for distutils.commands.install\r
+# These values are initialized by the getuserbase() and getusersitepackages()\r
+# functions, through the main() function when Python starts.\r
+USER_SITE = None\r
+USER_BASE = None\r
+\r
+\r
+def makepath(*paths):\r
+ dir = os.path.join(*paths)\r
+ try:\r
+ dir = os.path.abspath(dir)\r
+ except OSError:\r
+ pass\r
+ return dir, os.path.normcase(dir)\r
+\r
+\r
+def abs__file__():\r
+ """Set all module' __file__ attribute to an absolute path"""\r
+ for m in sys.modules.values():\r
+ if hasattr(m, '__loader__'):\r
+ continue # don't mess with a PEP 302-supplied __file__\r
+ try:\r
+ m.__file__ = os.path.abspath(m.__file__)\r
+ except (AttributeError, OSError):\r
+ pass\r
+\r
+\r
+def removeduppaths():\r
+ """ Remove duplicate entries from sys.path along with making them\r
+ absolute"""\r
+ # This ensures that the initial path provided by the interpreter contains\r
+ # only absolute pathnames, even if we're running from the build directory.\r
+ L = []\r
+ known_paths = set()\r
+ for dir in sys.path:\r
+ # Filter out duplicate paths (on case-insensitive file systems also\r
+ # if they only differ in case); turn relative paths into absolute\r
+ # paths.\r
+ dir, dircase = makepath(dir)\r
+ if not dircase in known_paths:\r
+ L.append(dir)\r
+ known_paths.add(dircase)\r
+ sys.path[:] = L\r
+ return known_paths\r
+\r
+\r
+def _init_pathinfo():\r
+ """Return a set containing all existing directory entries from sys.path"""\r
+ d = set()\r
+ for dir in sys.path:\r
+ try:\r
+ if os.path.isdir(dir):\r
+ dir, dircase = makepath(dir)\r
+ d.add(dircase)\r
+ except TypeError:\r
+ continue\r
+ return d\r
+\r
+\r
+def addpackage(sitedir, name, known_paths):\r
+ """Process a .pth file within the site-packages directory:\r
+ For each line in the file, either combine it with sitedir to a path\r
+ and add that to known_paths, or execute it if it starts with 'import '.\r
+ """\r
+ if known_paths is None:\r
+ _init_pathinfo()\r
+ reset = 1\r
+ else:\r
+ reset = 0\r
+ fullname = os.path.join(sitedir, name)\r
+ try:\r
+ f = open(fullname, "rU")\r
+ except IOError:\r
+ return\r
+ with f:\r
+ for n, line in enumerate(f):\r
+ if line.startswith("#"):\r
+ continue\r
+ try:\r
+ if line.startswith(("import ", "import\t")):\r
+ exec line\r
+ continue\r
+ line = line.rstrip()\r
+ dir, dircase = makepath(sitedir, line)\r
+ if not dircase in known_paths and os.path.exists(dir):\r
+ sys.path.append(dir)\r
+ known_paths.add(dircase)\r
+ except Exception as err:\r
+ print >>sys.stderr, "Error processing line {:d} of {}:\n".format(\r
+ n+1, fullname)\r
+ for record in traceback.format_exception(*sys.exc_info()):\r
+ for line in record.splitlines():\r
+ print >>sys.stderr, ' '+line\r
+ print >>sys.stderr, "\nRemainder of file ignored"\r
+ break\r
+ if reset:\r
+ known_paths = None\r
+ return known_paths\r
+\r
+\r
+def addsitedir(sitedir, known_paths=None):\r
+ """Add 'sitedir' argument to sys.path if missing and handle .pth files in\r
+ 'sitedir'"""\r
+ if known_paths is None:\r
+ known_paths = _init_pathinfo()\r
+ reset = 1\r
+ else:\r
+ reset = 0\r
+ sitedir, sitedircase = makepath(sitedir)\r
+ if not sitedircase in known_paths:\r
+ sys.path.append(sitedir) # Add path component\r
+ try:\r
+ names = os.listdir(sitedir)\r
+ except os.error:\r
+ return\r
+ dotpth = os.extsep + "pth"\r
+ names = [name for name in names if name.endswith(dotpth)]\r
+ for name in sorted(names):\r
+ addpackage(sitedir, name, known_paths)\r
+ if reset:\r
+ known_paths = None\r
+ return known_paths\r
+\r
+\r
+def check_enableusersite():\r
+ """Check if user site directory is safe for inclusion\r
+\r
+ The function tests for the command line flag (including environment var),\r
+ process uid/gid equal to effective uid/gid.\r
+\r
+ None: Disabled for security reasons\r
+ False: Disabled by user (command line option)\r
+ True: Safe and enabled\r
+ """\r
+ if sys.flags.no_user_site:\r
+ return False\r
+\r
+ if hasattr(os, "getuid") and hasattr(os, "geteuid"):\r
+ # check process uid == effective uid\r
+ if os.geteuid() != os.getuid():\r
+ return None\r
+ if hasattr(os, "getgid") and hasattr(os, "getegid"):\r
+ # check process gid == effective gid\r
+ if os.getegid() != os.getgid():\r
+ return None\r
+\r
+ return True\r
+\r
+def getuserbase():\r
+ """Returns the `user base` directory path.\r
+\r
+ The `user base` directory can be used to store data. If the global\r
+ variable ``USER_BASE`` is not initialized yet, this function will also set\r
+ it.\r
+ """\r
+ global USER_BASE\r
+ if USER_BASE is not None:\r
+ return USER_BASE\r
+ from sysconfig import get_config_var\r
+ USER_BASE = get_config_var('userbase')\r
+ return USER_BASE\r
+\r
+def getusersitepackages():\r
+ """Returns the user-specific site-packages directory path.\r
+\r
+ If the global variable ``USER_SITE`` is not initialized yet, this\r
+ function will also set it.\r
+ """\r
+ global USER_SITE\r
+ user_base = getuserbase() # this will also set USER_BASE\r
+\r
+ if USER_SITE is not None:\r
+ return USER_SITE\r
+\r
+ from sysconfig import get_path\r
+ import os\r
+\r
+ if sys.platform == 'darwin':\r
+ from sysconfig import get_config_var\r
+ if get_config_var('PYTHONFRAMEWORK'):\r
+ USER_SITE = get_path('purelib', 'osx_framework_user')\r
+ return USER_SITE\r
+\r
+ USER_SITE = get_path('purelib', '%s_user' % os.name)\r
+ return USER_SITE\r
+\r
+def addusersitepackages(known_paths):\r
+ """Add a per user site-package to sys.path\r
+\r
+ Each user has its own python directory with site-packages in the\r
+ home directory.\r
+ """\r
+ # get the per user site-package path\r
+ # this call will also make sure USER_BASE and USER_SITE are set\r
+ user_site = getusersitepackages()\r
+\r
+ if ENABLE_USER_SITE and os.path.isdir(user_site):\r
+ addsitedir(user_site, known_paths)\r
+ return known_paths\r
+\r
+def getsitepackages():\r
+ """Returns a list containing all global site-packages directories\r
+ (and possibly site-python).\r
+\r
+ For each directory present in the global ``PREFIXES``, this function\r
+ will find its `site-packages` subdirectory depending on the system\r
+ environment, and will return a list of full paths.\r
+ """\r
+ sitepackages = []\r
+ seen = set()\r
+\r
+ for prefix in PREFIXES:\r
+ if not prefix or prefix in seen:\r
+ continue\r
+ seen.add(prefix)\r
+\r
+ if sys.platform in ('os2emx', 'riscos'):\r
+ sitepackages.append(os.path.join(prefix, "Lib", "site-packages"))\r
+ elif os.sep == '/':\r
+ sitepackages.append(os.path.join(prefix, "lib",\r
+ "python" + sys.version[:3],\r
+ "site-packages"))\r
+ sitepackages.append(os.path.join(prefix, "lib", "site-python"))\r
+ else:\r
+ sitepackages.append(prefix)\r
+ sitepackages.append(os.path.join(prefix, "lib", "site-packages"))\r
+ if sys.platform == "darwin":\r
+ # for framework builds *only* we add the standard Apple\r
+ # locations.\r
+ from sysconfig import get_config_var\r
+ framework = get_config_var("PYTHONFRAMEWORK")\r
+ if framework:\r
+ sitepackages.append(\r
+ os.path.join("/Library", framework,\r
+ sys.version[:3], "site-packages"))\r
+ return sitepackages\r
+\r
+def addsitepackages(known_paths):\r
+ """Add site-packages (and possibly site-python) to sys.path"""\r
+ for sitedir in getsitepackages():\r
+ if os.path.isdir(sitedir):\r
+ addsitedir(sitedir, known_paths)\r
+\r
+ return known_paths\r
+\r
+def setBEGINLIBPATH():\r
+ """The OS/2 EMX port has optional extension modules that do double duty\r
+ as DLLs (and must use the .DLL file extension) for other extensions.\r
+ The library search path needs to be amended so these will be found\r
+ during module import. Use BEGINLIBPATH so that these are at the start\r
+ of the library search path.\r
+\r
+ """\r
+ dllpath = os.path.join(sys.prefix, "Lib", "lib-dynload")\r
+ libpath = os.environ['BEGINLIBPATH'].split(';')\r
+ if libpath[-1]:\r
+ libpath.append(dllpath)\r
+ else:\r
+ libpath[-1] = dllpath\r
+ os.environ['BEGINLIBPATH'] = ';'.join(libpath)\r
+\r
+\r
+def setquit():\r
+ """Define new builtins 'quit' and 'exit'.\r
+\r
+ These are objects which make the interpreter exit when called.\r
+ The repr of each object contains a hint at how it works.\r
+\r
+ """\r
+ if os.sep == ':':\r
+ eof = 'Cmd-Q'\r
+ elif os.sep == '\\':\r
+ eof = 'Ctrl-Z plus Return'\r
+ else:\r
+ eof = 'Ctrl-D (i.e. EOF)'\r
+\r
+ class Quitter(object):\r
+ def __init__(self, name):\r
+ self.name = name\r
+ def __repr__(self):\r
+ return 'Use %s() or %s to exit' % (self.name, eof)\r
+ def __call__(self, code=None):\r
+ # Shells like IDLE catch the SystemExit, but listen when their\r
+ # stdin wrapper is closed.\r
+ try:\r
+ sys.stdin.close()\r
+ except:\r
+ pass\r
+ raise SystemExit(code)\r
+ __builtin__.quit = Quitter('quit')\r
+ __builtin__.exit = Quitter('exit')\r
+\r
+\r
+class _Printer(object):\r
+ """interactive prompt objects for printing the license text, a list of\r
+ contributors and the copyright notice."""\r
+\r
+ MAXLINES = 23\r
+\r
+ def __init__(self, name, data, files=(), dirs=()):\r
+ self.__name = name\r
+ self.__data = data\r
+ self.__files = files\r
+ self.__dirs = dirs\r
+ self.__lines = None\r
+\r
+ def __setup(self):\r
+ if self.__lines:\r
+ return\r
+ data = None\r
+ for dir in self.__dirs:\r
+ for filename in self.__files:\r
+ filename = os.path.join(dir, filename)\r
+ try:\r
+ fp = file(filename, "rU")\r
+ data = fp.read()\r
+ fp.close()\r
+ break\r
+ except IOError:\r
+ pass\r
+ if data:\r
+ break\r
+ if not data:\r
+ data = self.__data\r
+ self.__lines = data.split('\n')\r
+ self.__linecnt = len(self.__lines)\r
+\r
+ def __repr__(self):\r
+ self.__setup()\r
+ if len(self.__lines) <= self.MAXLINES:\r
+ return "\n".join(self.__lines)\r
+ else:\r
+ return "Type %s() to see the full %s text" % ((self.__name,)*2)\r
+\r
+ def __call__(self):\r
+ self.__setup()\r
+ prompt = 'Hit Return for more, or q (and Return) to quit: '\r
+ lineno = 0\r
+ while 1:\r
+ try:\r
+ for i in range(lineno, lineno + self.MAXLINES):\r
+ print self.__lines[i]\r
+ except IndexError:\r
+ break\r
+ else:\r
+ lineno += self.MAXLINES\r
+ key = None\r
+ while key is None:\r
+ key = raw_input(prompt)\r
+ if key not in ('', 'q'):\r
+ key = None\r
+ if key == 'q':\r
+ break\r
+\r
+def setcopyright():\r
+ """Set 'copyright' and 'credits' in __builtin__"""\r
+ __builtin__.copyright = _Printer("copyright", sys.copyright)\r
+ if sys.platform[:4] == 'java':\r
+ __builtin__.credits = _Printer(\r
+ "credits",\r
+ "Jython is maintained by the Jython developers (www.jython.org).")\r
+ else:\r
+ __builtin__.credits = _Printer("credits", """\\r
+ Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands\r
+ for supporting Python development. See www.python.org for more information.""")\r
+ here = os.path.dirname(os.__file__)\r
+ __builtin__.license = _Printer(\r
+ "license", "See https://www.python.org/psf/license/",\r
+ ["LICENSE.txt", "LICENSE"],\r
+ [os.path.join(here, os.pardir), here, os.curdir])\r
+\r
+\r
+class _Helper(object):\r
+ """Define the builtin 'help'.\r
+ This is a wrapper around pydoc.help (with a twist).\r
+\r
+ """\r
+\r
+ def __repr__(self):\r
+ return "Type help() for interactive help, " \\r
+ "or help(object) for help about object."\r
+ def __call__(self, *args, **kwds):\r
+ import pydoc\r
+ return pydoc.help(*args, **kwds)\r
+\r
+def sethelper():\r
+ __builtin__.help = _Helper()\r
+\r
+def aliasmbcs():\r
+ """On Windows, some default encodings are not provided by Python,\r
+ while they are always available as "mbcs" in each locale. Make\r
+ them usable by aliasing to "mbcs" in such a case."""\r
+ if sys.platform == 'win32':\r
+ import locale, codecs\r
+ enc = locale.getdefaultlocale()[1]\r
+ if enc.startswith('cp'): # "cp***" ?\r
+ try:\r
+ codecs.lookup(enc)\r
+ except LookupError:\r
+ import encodings\r
+ encodings._cache[enc] = encodings._unknown\r
+ encodings.aliases.aliases[enc] = 'mbcs'\r
+\r
+def setencoding():\r
+ """Set the string encoding used by the Unicode implementation. The\r
+ default is 'ascii', but if you're willing to experiment, you can\r
+ change this."""\r
+ encoding = "ascii" # Default value set by _PyUnicode_Init()\r
+ if 0:\r
+ # Enable to support locale aware default string encodings.\r
+ import locale\r
+ loc = locale.getdefaultlocale()\r
+ if loc[1]:\r
+ encoding = loc[1]\r
+ if 0:\r
+ # Enable to switch off string to Unicode coercion and implicit\r
+ # Unicode to string conversion.\r
+ encoding = "undefined"\r
+ if encoding != "ascii":\r
+ # On Non-Unicode builds this will raise an AttributeError...\r
+ sys.setdefaultencoding(encoding) # Needs Python Unicode build !\r
+\r
+\r
+def execsitecustomize():\r
+ """Run custom site specific code, if available."""\r
+ try:\r
+ import sitecustomize\r
+ except ImportError:\r
+ pass\r
+ except Exception:\r
+ if sys.flags.verbose:\r
+ sys.excepthook(*sys.exc_info())\r
+ else:\r
+ print >>sys.stderr, \\r
+ "'import sitecustomize' failed; use -v for traceback"\r
+\r
+\r
+def execusercustomize():\r
+ """Run custom user specific code, if available."""\r
+ try:\r
+ import usercustomize\r
+ except ImportError:\r
+ pass\r
+ except Exception:\r
+ if sys.flags.verbose:\r
+ sys.excepthook(*sys.exc_info())\r
+ else:\r
+ print>>sys.stderr, \\r
+ "'import usercustomize' failed; use -v for traceback"\r
+\r
+\r
+def main():\r
+ global ENABLE_USER_SITE\r
+\r
+ abs__file__()\r
+ known_paths = removeduppaths()\r
+ if ENABLE_USER_SITE is None:\r
+ ENABLE_USER_SITE = check_enableusersite()\r
+ known_paths = addusersitepackages(known_paths)\r
+ known_paths = addsitepackages(known_paths)\r
+ if sys.platform == 'os2emx':\r
+ setBEGINLIBPATH()\r
+ setquit()\r
+ setcopyright()\r
+ sethelper()\r
+ aliasmbcs()\r
+ setencoding()\r
+ execsitecustomize()\r
+ if ENABLE_USER_SITE:\r
+ execusercustomize()\r
+ # Remove sys.setdefaultencoding() so that users cannot change the\r
+ # encoding after initialization. The test for presence is needed when\r
+ # this module is run as a script, because this code is executed twice.\r
+ if hasattr(sys, "setdefaultencoding"):\r
+ del sys.setdefaultencoding\r
+\r
+main()\r
+\r
+def _script():\r
+ help = """\\r
+ %s [--user-base] [--user-site]\r
+\r
+ Without arguments print some useful information\r
+ With arguments print the value of USER_BASE and/or USER_SITE separated\r
+ by '%s'.\r
+\r
+ Exit codes with --user-base or --user-site:\r
+ 0 - user site directory is enabled\r
+ 1 - user site directory is disabled by user\r
+ 2 - uses site directory is disabled by super user\r
+ or for security reasons\r
+ >2 - unknown error\r
+ """\r
+ args = sys.argv[1:]\r
+ if not args:\r
+ print "sys.path = ["\r
+ for dir in sys.path:\r
+ print " %r," % (dir,)\r
+ print "]"\r
+ print "USER_BASE: %r (%s)" % (USER_BASE,\r
+ "exists" if os.path.isdir(USER_BASE) else "doesn't exist")\r
+ print "USER_SITE: %r (%s)" % (USER_SITE,\r
+ "exists" if os.path.isdir(USER_SITE) else "doesn't exist")\r
+ print "ENABLE_USER_SITE: %r" % ENABLE_USER_SITE\r
+ sys.exit(0)\r
+\r
+ buffer = []\r
+ if '--user-base' in args:\r
+ buffer.append(USER_BASE)\r
+ if '--user-site' in args:\r
+ buffer.append(USER_SITE)\r
+\r
+ if buffer:\r
+ print os.pathsep.join(buffer)\r
+ if ENABLE_USER_SITE:\r
+ sys.exit(0)\r
+ elif ENABLE_USER_SITE is False:\r
+ sys.exit(1)\r
+ elif ENABLE_USER_SITE is None:\r
+ sys.exit(2)\r
+ else:\r
+ sys.exit(3)\r
+ else:\r
+ import textwrap\r
+ print textwrap.dedent(help % (sys.argv[0], os.pathsep))\r
+ sys.exit(10)\r
+\r
+if __name__ == '__main__':\r
+ _script()\r
--- /dev/null
+/*\r
+ * Secret Labs' Regular Expression Engine\r
+ *\r
+ * regular expression matching engine\r
+ *\r
+ * partial history:\r
+ * 1999-10-24 fl created (based on existing template matcher code)\r
+ * 2000-03-06 fl first alpha, sort of\r
+ * 2000-08-01 fl fixes for 1.6b1\r
+ * 2000-08-07 fl use PyOS_CheckStack() if available\r
+ * 2000-09-20 fl added expand method\r
+ * 2001-03-20 fl lots of fixes for 2.1b2\r
+ * 2001-04-15 fl export copyright as Python attribute, not global\r
+ * 2001-04-28 fl added __copy__ methods (work in progress)\r
+ * 2001-05-14 fl fixes for 1.5.2 compatibility\r
+ * 2001-07-01 fl added BIGCHARSET support (from Martin von Loewis)\r
+ * 2001-10-18 fl fixed group reset issue (from Matthew Mueller)\r
+ * 2001-10-20 fl added split primitive; reenable unicode for 1.6/2.0/2.1\r
+ * 2001-10-21 fl added sub/subn primitive\r
+ * 2001-10-24 fl added finditer primitive (for 2.2 only)\r
+ * 2001-12-07 fl fixed memory leak in sub/subn (Guido van Rossum)\r
+ * 2002-11-09 fl fixed empty sub/subn return type\r
+ * 2003-04-18 mvl fully support 4-byte codes\r
+ * 2003-10-17 gn implemented non recursive scheme\r
+ *\r
+ * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved.\r
+ *\r
+ * This version of the SRE library can be redistributed under CNRI's\r
+ * Python 1.6 license. For any other use, please contact Secret Labs\r
+ * AB (info@pythonware.com).\r
+ *\r
+ * Portions of this engine have been developed in cooperation with\r
+ * CNRI. Hewlett-Packard provided funding for 1.6 integration and\r
+ * other compatibility work.\r
+ */\r
+\r
+#ifndef SRE_RECURSIVE\r
+\r
+static char copyright[] =\r
+ " SRE 2.2.2 Copyright (c) 1997-2002 by Secret Labs AB ";\r
+\r
+#define PY_SSIZE_T_CLEAN\r
+\r
+#include "Python.h"\r
+#include "structmember.h" /* offsetof */\r
+\r
+#include "sre.h"\r
+\r
+#include <ctype.h>\r
+\r
+/* name of this module, minus the leading underscore */\r
+#if !defined(SRE_MODULE)\r
+#define SRE_MODULE "sre"\r
+#endif\r
+\r
+#define SRE_PY_MODULE "re"\r
+\r
+/* defining this one enables tracing */\r
+#undef VERBOSE\r
+\r
+#if PY_VERSION_HEX >= 0x01060000\r
+#if PY_VERSION_HEX < 0x02020000 || defined(Py_USING_UNICODE)\r
+/* defining this enables unicode support (default under 1.6a1 and later) */\r
+#define HAVE_UNICODE\r
+#endif\r
+#endif\r
+\r
+/* -------------------------------------------------------------------- */\r
+/* optional features */\r
+\r
+/* enables fast searching */\r
+#define USE_FAST_SEARCH\r
+\r
+/* enables aggressive inlining (always on for Visual C) */\r
+#undef USE_INLINE\r
+\r
+/* enables copy/deepcopy handling (work in progress) */\r
+#undef USE_BUILTIN_COPY\r
+\r
+#if PY_VERSION_HEX < 0x01060000\r
+#define PyObject_DEL(op) PyMem_DEL((op))\r
+#endif\r
+\r
+/* -------------------------------------------------------------------- */\r
+\r
+#if defined(_MSC_VER)\r
+#pragma optimize("agtw", on) /* doesn't seem to make much difference... */\r
+#pragma warning(disable: 4710) /* who cares if functions are not inlined ;-) */\r
+/* fastest possible local call under MSVC */\r
+#define LOCAL(type) static __inline type __fastcall\r
+#elif defined(USE_INLINE)\r
+#define LOCAL(type) static inline type\r
+#else\r
+#define LOCAL(type) static type\r
+#endif\r
+\r
+/* error codes */\r
+#define SRE_ERROR_ILLEGAL -1 /* illegal opcode */\r
+#define SRE_ERROR_STATE -2 /* illegal state */\r
+#define SRE_ERROR_RECURSION_LIMIT -3 /* runaway recursion */\r
+#define SRE_ERROR_MEMORY -9 /* out of memory */\r
+#define SRE_ERROR_INTERRUPTED -10 /* signal handler raised exception */\r
+\r
+#if defined(VERBOSE)\r
+#define TRACE(v) printf v\r
+#else\r
+#define TRACE(v)\r
+#endif\r
+\r
+/* -------------------------------------------------------------------- */\r
+/* search engine state */\r
+\r
+/* default character predicates (run sre_chars.py to regenerate tables) */\r
+\r
+#define SRE_DIGIT_MASK 1\r
+#define SRE_SPACE_MASK 2\r
+#define SRE_LINEBREAK_MASK 4\r
+#define SRE_ALNUM_MASK 8\r
+#define SRE_WORD_MASK 16\r
+\r
+/* FIXME: this assumes ASCII. create tables in init_sre() instead */\r
+\r
+static char sre_char_info[128] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 2,\r
+2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0,\r
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25,\r
+25, 25, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\r
+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0,\r
+0, 0, 16, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\r
+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0 };\r
+\r
+static char sre_char_lower[128] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,\r
+10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,\r
+27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,\r
+44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,\r
+61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107,\r
+108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,\r
+122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,\r
+106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,\r
+120, 121, 122, 123, 124, 125, 126, 127 };\r
+\r
+#define SRE_IS_DIGIT(ch)\\r
+ ((ch) < 128 ? (sre_char_info[(ch)] & SRE_DIGIT_MASK) : 0)\r
+#define SRE_IS_SPACE(ch)\\r
+ ((ch) < 128 ? (sre_char_info[(ch)] & SRE_SPACE_MASK) : 0)\r
+#define SRE_IS_LINEBREAK(ch)\\r
+ ((ch) < 128 ? (sre_char_info[(ch)] & SRE_LINEBREAK_MASK) : 0)\r
+#define SRE_IS_ALNUM(ch)\\r
+ ((ch) < 128 ? (sre_char_info[(ch)] & SRE_ALNUM_MASK) : 0)\r
+#define SRE_IS_WORD(ch)\\r
+ ((ch) < 128 ? (sre_char_info[(ch)] & SRE_WORD_MASK) : 0)\r
+\r
+static unsigned int sre_lower(unsigned int ch)\r
+{\r
+ return ((ch) < 128 ? (unsigned int)sre_char_lower[ch] : ch);\r
+}\r
+\r
+/* locale-specific character predicates */\r
+/* !(c & ~N) == (c < N+1) for any unsigned c, this avoids\r
+ * warnings when c's type supports only numbers < N+1 */\r
+#define SRE_LOC_IS_DIGIT(ch) (!((ch) & ~255) ? isdigit((ch)) : 0)\r
+#define SRE_LOC_IS_SPACE(ch) (!((ch) & ~255) ? isspace((ch)) : 0)\r
+#define SRE_LOC_IS_LINEBREAK(ch) ((ch) == '\n')\r
+#define SRE_LOC_IS_ALNUM(ch) (!((ch) & ~255) ? isalnum((ch)) : 0)\r
+#define SRE_LOC_IS_WORD(ch) (SRE_LOC_IS_ALNUM((ch)) || (ch) == '_')\r
+\r
+static unsigned int sre_lower_locale(unsigned int ch)\r
+{\r
+ return ((ch) < 256 ? (unsigned int)tolower((ch)) : ch);\r
+}\r
+\r
+/* unicode-specific character predicates */\r
+\r
+#if defined(HAVE_UNICODE)\r
+\r
+#define SRE_UNI_IS_DIGIT(ch) Py_UNICODE_ISDECIMAL((Py_UNICODE)(ch))\r
+#define SRE_UNI_IS_SPACE(ch) Py_UNICODE_ISSPACE((Py_UNICODE)(ch))\r
+#define SRE_UNI_IS_LINEBREAK(ch) Py_UNICODE_ISLINEBREAK((Py_UNICODE)(ch))\r
+#define SRE_UNI_IS_ALNUM(ch) Py_UNICODE_ISALNUM((Py_UNICODE)(ch))\r
+#define SRE_UNI_IS_WORD(ch) (SRE_UNI_IS_ALNUM((ch)) || (ch) == '_')\r
+\r
+static unsigned int sre_lower_unicode(unsigned int ch)\r
+{\r
+ return (unsigned int) Py_UNICODE_TOLOWER((Py_UNICODE)(ch));\r
+}\r
+\r
+#endif\r
+\r
+LOCAL(int)\r
+sre_category(SRE_CODE category, unsigned int ch)\r
+{\r
+ switch (category) {\r
+\r
+ case SRE_CATEGORY_DIGIT:\r
+ return SRE_IS_DIGIT(ch);\r
+ case SRE_CATEGORY_NOT_DIGIT:\r
+ return !SRE_IS_DIGIT(ch);\r
+ case SRE_CATEGORY_SPACE:\r
+ return SRE_IS_SPACE(ch);\r
+ case SRE_CATEGORY_NOT_SPACE:\r
+ return !SRE_IS_SPACE(ch);\r
+ case SRE_CATEGORY_WORD:\r
+ return SRE_IS_WORD(ch);\r
+ case SRE_CATEGORY_NOT_WORD:\r
+ return !SRE_IS_WORD(ch);\r
+ case SRE_CATEGORY_LINEBREAK:\r
+ return SRE_IS_LINEBREAK(ch);\r
+ case SRE_CATEGORY_NOT_LINEBREAK:\r
+ return !SRE_IS_LINEBREAK(ch);\r
+\r
+ case SRE_CATEGORY_LOC_WORD:\r
+ return SRE_LOC_IS_WORD(ch);\r
+ case SRE_CATEGORY_LOC_NOT_WORD:\r
+ return !SRE_LOC_IS_WORD(ch);\r
+\r
+#if defined(HAVE_UNICODE)\r
+ case SRE_CATEGORY_UNI_DIGIT:\r
+ return SRE_UNI_IS_DIGIT(ch);\r
+ case SRE_CATEGORY_UNI_NOT_DIGIT:\r
+ return !SRE_UNI_IS_DIGIT(ch);\r
+ case SRE_CATEGORY_UNI_SPACE:\r
+ return SRE_UNI_IS_SPACE(ch);\r
+ case SRE_CATEGORY_UNI_NOT_SPACE:\r
+ return !SRE_UNI_IS_SPACE(ch);\r
+ case SRE_CATEGORY_UNI_WORD:\r
+ return SRE_UNI_IS_WORD(ch);\r
+ case SRE_CATEGORY_UNI_NOT_WORD:\r
+ return !SRE_UNI_IS_WORD(ch);\r
+ case SRE_CATEGORY_UNI_LINEBREAK:\r
+ return SRE_UNI_IS_LINEBREAK(ch);\r
+ case SRE_CATEGORY_UNI_NOT_LINEBREAK:\r
+ return !SRE_UNI_IS_LINEBREAK(ch);\r
+#else\r
+ case SRE_CATEGORY_UNI_DIGIT:\r
+ return SRE_IS_DIGIT(ch);\r
+ case SRE_CATEGORY_UNI_NOT_DIGIT:\r
+ return !SRE_IS_DIGIT(ch);\r
+ case SRE_CATEGORY_UNI_SPACE:\r
+ return SRE_IS_SPACE(ch);\r
+ case SRE_CATEGORY_UNI_NOT_SPACE:\r
+ return !SRE_IS_SPACE(ch);\r
+ case SRE_CATEGORY_UNI_WORD:\r
+ return SRE_LOC_IS_WORD(ch);\r
+ case SRE_CATEGORY_UNI_NOT_WORD:\r
+ return !SRE_LOC_IS_WORD(ch);\r
+ case SRE_CATEGORY_UNI_LINEBREAK:\r
+ return SRE_IS_LINEBREAK(ch);\r
+ case SRE_CATEGORY_UNI_NOT_LINEBREAK:\r
+ return !SRE_IS_LINEBREAK(ch);\r
+#endif\r
+ }\r
+ return 0;\r
+}\r
+\r
+/* helpers */\r
+\r
+static void\r
+data_stack_dealloc(SRE_STATE* state)\r
+{\r
+ if (state->data_stack) {\r
+ PyMem_FREE(state->data_stack);\r
+ state->data_stack = NULL;\r
+ }\r
+ state->data_stack_size = state->data_stack_base = 0;\r
+}\r
+\r
+static int\r
+data_stack_grow(SRE_STATE* state, Py_ssize_t size)\r
+{\r
+ Py_ssize_t minsize, cursize;\r
+ minsize = state->data_stack_base+size;\r
+ cursize = state->data_stack_size;\r
+ if (cursize < minsize) {\r
+ void* stack;\r
+ cursize = minsize+minsize/4+1024;\r
+ TRACE(("allocate/grow stack %" PY_FORMAT_SIZE_T "d\n", cursize));\r
+ stack = PyMem_REALLOC(state->data_stack, cursize);\r
+ if (!stack) {\r
+ data_stack_dealloc(state);\r
+ return SRE_ERROR_MEMORY;\r
+ }\r
+ state->data_stack = (char *)stack;\r
+ state->data_stack_size = cursize;\r
+ }\r
+ return 0;\r
+}\r
+\r
+/* generate 8-bit version */\r
+\r
+#define SRE_CHAR unsigned char\r
+#define SRE_AT sre_at\r
+#define SRE_COUNT sre_count\r
+#define SRE_CHARSET sre_charset\r
+#define SRE_INFO sre_info\r
+#define SRE_MATCH sre_match\r
+#define SRE_MATCH_CONTEXT sre_match_context\r
+#define SRE_SEARCH sre_search\r
+#define SRE_LITERAL_TEMPLATE sre_literal_template\r
+\r
+#if defined(HAVE_UNICODE)\r
+\r
+#define SRE_RECURSIVE\r
+#include "_sre.c"\r
+#undef SRE_RECURSIVE\r
+\r
+#undef SRE_LITERAL_TEMPLATE\r
+#undef SRE_SEARCH\r
+#undef SRE_MATCH\r
+#undef SRE_MATCH_CONTEXT\r
+#undef SRE_INFO\r
+#undef SRE_CHARSET\r
+#undef SRE_COUNT\r
+#undef SRE_AT\r
+#undef SRE_CHAR\r
+\r
+/* generate 16-bit unicode version */\r
+\r
+#define SRE_CHAR Py_UNICODE\r
+#define SRE_AT sre_uat\r
+#define SRE_COUNT sre_ucount\r
+#define SRE_CHARSET sre_ucharset\r
+#define SRE_INFO sre_uinfo\r
+#define SRE_MATCH sre_umatch\r
+#define SRE_MATCH_CONTEXT sre_umatch_context\r
+#define SRE_SEARCH sre_usearch\r
+#define SRE_LITERAL_TEMPLATE sre_uliteral_template\r
+#endif\r
+\r
+#endif /* SRE_RECURSIVE */\r
+\r
+/* -------------------------------------------------------------------- */\r
+/* String matching engine */\r
+\r
+/* the following section is compiled twice, with different character\r
+ settings */\r
+\r
+LOCAL(int)\r
+SRE_AT(SRE_STATE* state, SRE_CHAR* ptr, SRE_CODE at)\r
+{\r
+ /* check if pointer is at given position */\r
+\r
+ Py_ssize_t thisp, thatp;\r
+\r
+ switch (at) {\r
+\r
+ case SRE_AT_BEGINNING:\r
+ case SRE_AT_BEGINNING_STRING:\r
+ return ((void*) ptr == state->beginning);\r
+\r
+ case SRE_AT_BEGINNING_LINE:\r
+ return ((void*) ptr == state->beginning ||\r
+ SRE_IS_LINEBREAK((int) ptr[-1]));\r
+\r
+ case SRE_AT_END:\r
+ return (((void*) (ptr+1) == state->end &&\r
+ SRE_IS_LINEBREAK((int) ptr[0])) ||\r
+ ((void*) ptr == state->end));\r
+\r
+ case SRE_AT_END_LINE:\r
+ return ((void*) ptr == state->end ||\r
+ SRE_IS_LINEBREAK((int) ptr[0]));\r
+\r
+ case SRE_AT_END_STRING:\r
+ return ((void*) ptr == state->end);\r
+\r
+ case SRE_AT_BOUNDARY:\r
+ if (state->beginning == state->end)\r
+ return 0;\r
+ thatp = ((void*) ptr > state->beginning) ?\r
+ SRE_IS_WORD((int) ptr[-1]) : 0;\r
+ thisp = ((void*) ptr < state->end) ?\r
+ SRE_IS_WORD((int) ptr[0]) : 0;\r
+ return thisp != thatp;\r
+\r
+ case SRE_AT_NON_BOUNDARY:\r
+ if (state->beginning == state->end)\r
+ return 0;\r
+ thatp = ((void*) ptr > state->beginning) ?\r
+ SRE_IS_WORD((int) ptr[-1]) : 0;\r
+ thisp = ((void*) ptr < state->end) ?\r
+ SRE_IS_WORD((int) ptr[0]) : 0;\r
+ return thisp == thatp;\r
+\r
+ case SRE_AT_LOC_BOUNDARY:\r
+ if (state->beginning == state->end)\r
+ return 0;\r
+ thatp = ((void*) ptr > state->beginning) ?\r
+ SRE_LOC_IS_WORD((int) ptr[-1]) : 0;\r
+ thisp = ((void*) ptr < state->end) ?\r
+ SRE_LOC_IS_WORD((int) ptr[0]) : 0;\r
+ return thisp != thatp;\r
+\r
+ case SRE_AT_LOC_NON_BOUNDARY:\r
+ if (state->beginning == state->end)\r
+ return 0;\r
+ thatp = ((void*) ptr > state->beginning) ?\r
+ SRE_LOC_IS_WORD((int) ptr[-1]) : 0;\r
+ thisp = ((void*) ptr < state->end) ?\r
+ SRE_LOC_IS_WORD((int) ptr[0]) : 0;\r
+ return thisp == thatp;\r
+\r
+#if defined(HAVE_UNICODE)\r
+ case SRE_AT_UNI_BOUNDARY:\r
+ if (state->beginning == state->end)\r
+ return 0;\r
+ thatp = ((void*) ptr > state->beginning) ?\r
+ SRE_UNI_IS_WORD((int) ptr[-1]) : 0;\r
+ thisp = ((void*) ptr < state->end) ?\r
+ SRE_UNI_IS_WORD((int) ptr[0]) : 0;\r
+ return thisp != thatp;\r
+\r
+ case SRE_AT_UNI_NON_BOUNDARY:\r
+ if (state->beginning == state->end)\r
+ return 0;\r
+ thatp = ((void*) ptr > state->beginning) ?\r
+ SRE_UNI_IS_WORD((int) ptr[-1]) : 0;\r
+ thisp = ((void*) ptr < state->end) ?\r
+ SRE_UNI_IS_WORD((int) ptr[0]) : 0;\r
+ return thisp == thatp;\r
+#endif\r
+\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+LOCAL(int)\r
+SRE_CHARSET(SRE_CODE* set, SRE_CODE ch)\r
+{\r
+ /* check if character is a member of the given set */\r
+\r
+ int ok = 1;\r
+\r
+ for (;;) {\r
+ switch (*set++) {\r
+\r
+ case SRE_OP_FAILURE:\r
+ return !ok;\r
+\r
+ case SRE_OP_LITERAL:\r
+ /* <LITERAL> <code> */\r
+ if (ch == set[0])\r
+ return ok;\r
+ set++;\r
+ break;\r
+\r
+ case SRE_OP_CATEGORY:\r
+ /* <CATEGORY> <code> */\r
+ if (sre_category(set[0], (int) ch))\r
+ return ok;\r
+ set += 1;\r
+ break;\r
+\r
+ case SRE_OP_CHARSET:\r
+ if (sizeof(SRE_CODE) == 2) {\r
+ /* <CHARSET> <bitmap> (16 bits per code word) */\r
+ if (ch < 256 && (set[ch >> 4] & (1 << (ch & 15))))\r
+ return ok;\r
+ set += 16;\r
+ }\r
+ else {\r
+ /* <CHARSET> <bitmap> (32 bits per code word) */\r
+ if (ch < 256 && (set[ch >> 5] & (1u << (ch & 31))))\r
+ return ok;\r
+ set += 8;\r
+ }\r
+ break;\r
+\r
+ case SRE_OP_RANGE:\r
+ /* <RANGE> <lower> <upper> */\r
+ if (set[0] <= ch && ch <= set[1])\r
+ return ok;\r
+ set += 2;\r
+ break;\r
+\r
+ case SRE_OP_NEGATE:\r
+ ok = !ok;\r
+ break;\r
+\r
+ case SRE_OP_BIGCHARSET:\r
+ /* <BIGCHARSET> <blockcount> <256 blockindices> <blocks> */\r
+ {\r
+ Py_ssize_t count, block;\r
+ count = *(set++);\r
+\r
+ if (sizeof(SRE_CODE) == 2) {\r
+ block = ((unsigned char*)set)[ch >> 8];\r
+ set += 128;\r
+ if (set[block*16 + ((ch & 255)>>4)] & (1 << (ch & 15)))\r
+ return ok;\r
+ set += count*16;\r
+ }\r
+ else {\r
+ /* !(c & ~N) == (c < N+1) for any unsigned c, this avoids\r
+ * warnings when c's type supports only numbers < N+1 */\r
+ if (!(ch & ~65535))\r
+ block = ((unsigned char*)set)[ch >> 8];\r
+ else\r
+ block = -1;\r
+ set += 64;\r
+ if (block >=0 &&\r
+ (set[block*8 + ((ch & 255)>>5)] & (1u << (ch & 31))))\r
+ return ok;\r
+ set += count*8;\r
+ }\r
+ break;\r
+ }\r
+\r
+ default:\r
+ /* internal error -- there's not much we can do about it\r
+ here, so let's just pretend it didn't match... */\r
+ return 0;\r
+ }\r
+ }\r
+}\r
+\r
+LOCAL(Py_ssize_t) SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern);\r
+\r
+LOCAL(Py_ssize_t)\r
+SRE_COUNT(SRE_STATE* state, SRE_CODE* pattern, Py_ssize_t maxcount)\r
+{\r
+ SRE_CODE chr;\r
+ SRE_CHAR* ptr = (SRE_CHAR *)state->ptr;\r
+ SRE_CHAR* end = (SRE_CHAR *)state->end;\r
+ Py_ssize_t i;\r
+\r
+ /* adjust end */\r
+ if (maxcount < end - ptr && maxcount != SRE_MAXREPEAT)\r
+ end = ptr + maxcount;\r
+\r
+ switch (pattern[0]) {\r
+\r
+ case SRE_OP_IN:\r
+ /* repeated set */\r
+ TRACE(("|%p|%p|COUNT IN\n", pattern, ptr));\r
+ while (ptr < end && SRE_CHARSET(pattern + 2, *ptr))\r
+ ptr++;\r
+ break;\r
+\r
+ case SRE_OP_ANY:\r
+ /* repeated dot wildcard. */\r
+ TRACE(("|%p|%p|COUNT ANY\n", pattern, ptr));\r
+ while (ptr < end && !SRE_IS_LINEBREAK(*ptr))\r
+ ptr++;\r
+ break;\r
+\r
+ case SRE_OP_ANY_ALL:\r
+ /* repeated dot wildcard. skip to the end of the target\r
+ string, and backtrack from there */\r
+ TRACE(("|%p|%p|COUNT ANY_ALL\n", pattern, ptr));\r
+ ptr = end;\r
+ break;\r
+\r
+ case SRE_OP_LITERAL:\r
+ /* repeated literal */\r
+ chr = pattern[1];\r
+ TRACE(("|%p|%p|COUNT LITERAL %d\n", pattern, ptr, chr));\r
+ while (ptr < end && (SRE_CODE) *ptr == chr)\r
+ ptr++;\r
+ break;\r
+\r
+ case SRE_OP_LITERAL_IGNORE:\r
+ /* repeated literal */\r
+ chr = pattern[1];\r
+ TRACE(("|%p|%p|COUNT LITERAL_IGNORE %d\n", pattern, ptr, chr));\r
+ while (ptr < end && (SRE_CODE) state->lower(*ptr) == chr)\r
+ ptr++;\r
+ break;\r
+\r
+ case SRE_OP_NOT_LITERAL:\r
+ /* repeated non-literal */\r
+ chr = pattern[1];\r
+ TRACE(("|%p|%p|COUNT NOT_LITERAL %d\n", pattern, ptr, chr));\r
+ while (ptr < end && (SRE_CODE) *ptr != chr)\r
+ ptr++;\r
+ break;\r
+\r
+ case SRE_OP_NOT_LITERAL_IGNORE:\r
+ /* repeated non-literal */\r
+ chr = pattern[1];\r
+ TRACE(("|%p|%p|COUNT NOT_LITERAL_IGNORE %d\n", pattern, ptr, chr));\r
+ while (ptr < end && (SRE_CODE) state->lower(*ptr) != chr)\r
+ ptr++;\r
+ break;\r
+\r
+ default:\r
+ /* repeated single character pattern */\r
+ TRACE(("|%p|%p|COUNT SUBPATTERN\n", pattern, ptr));\r
+ while ((SRE_CHAR*) state->ptr < end) {\r
+ i = SRE_MATCH(state, pattern);\r
+ if (i < 0)\r
+ return i;\r
+ if (!i)\r
+ break;\r
+ }\r
+ TRACE(("|%p|%p|COUNT %" PY_FORMAT_SIZE_T "d\n", pattern, ptr,\r
+ (SRE_CHAR*) state->ptr - ptr));\r
+ return (SRE_CHAR*) state->ptr - ptr;\r
+ }\r
+\r
+ TRACE(("|%p|%p|COUNT %" PY_FORMAT_SIZE_T "d\n", pattern, ptr,\r
+ ptr - (SRE_CHAR*) state->ptr));\r
+ return ptr - (SRE_CHAR*) state->ptr;\r
+}\r
+\r
+#if 0 /* not used in this release */\r
+LOCAL(int)\r
+SRE_INFO(SRE_STATE* state, SRE_CODE* pattern)\r
+{\r
+ /* check if an SRE_OP_INFO block matches at the current position.\r
+ returns the number of SRE_CODE objects to skip if successful, 0\r
+ if no match */\r
+\r
+ SRE_CHAR* end = state->end;\r
+ SRE_CHAR* ptr = state->ptr;\r
+ Py_ssize_t i;\r
+\r
+ /* check minimal length */\r
+ if (pattern[3] && (end - ptr) < pattern[3])\r
+ return 0;\r
+\r
+ /* check known prefix */\r
+ if (pattern[2] & SRE_INFO_PREFIX && pattern[5] > 1) {\r
+ /* <length> <skip> <prefix data> <overlap data> */\r
+ for (i = 0; i < pattern[5]; i++)\r
+ if ((SRE_CODE) ptr[i] != pattern[7 + i])\r
+ return 0;\r
+ return pattern[0] + 2 * pattern[6];\r
+ }\r
+ return pattern[0];\r
+}\r
+#endif\r
+\r
+/* The macros below should be used to protect recursive SRE_MATCH()\r
+ * calls that *failed* and do *not* return immediately (IOW, those\r
+ * that will backtrack). Explaining:\r
+ *\r
+ * - Recursive SRE_MATCH() returned true: that's usually a success\r
+ * (besides atypical cases like ASSERT_NOT), therefore there's no\r
+ * reason to restore lastmark;\r
+ *\r
+ * - Recursive SRE_MATCH() returned false but the current SRE_MATCH()\r
+ * is returning to the caller: If the current SRE_MATCH() is the\r
+ * top function of the recursion, returning false will be a matching\r
+ * failure, and it doesn't matter where lastmark is pointing to.\r
+ * If it's *not* the top function, it will be a recursive SRE_MATCH()\r
+ * failure by itself, and the calling SRE_MATCH() will have to deal\r
+ * with the failure by the same rules explained here (it will restore\r
+ * lastmark by itself if necessary);\r
+ *\r
+ * - Recursive SRE_MATCH() returned false, and will continue the\r
+ * outside 'for' loop: must be protected when breaking, since the next\r
+ * OP could potentially depend on lastmark;\r
+ *\r
+ * - Recursive SRE_MATCH() returned false, and will be called again\r
+ * inside a local for/while loop: must be protected between each\r
+ * loop iteration, since the recursive SRE_MATCH() could do anything,\r
+ * and could potentially depend on lastmark.\r
+ *\r
+ * For more information, check the discussion at SF patch #712900.\r
+ */\r
+#define LASTMARK_SAVE() \\r
+ do { \\r
+ ctx->lastmark = state->lastmark; \\r
+ ctx->lastindex = state->lastindex; \\r
+ } while (0)\r
+#define LASTMARK_RESTORE() \\r
+ do { \\r
+ state->lastmark = ctx->lastmark; \\r
+ state->lastindex = ctx->lastindex; \\r
+ } while (0)\r
+\r
+#define RETURN_ERROR(i) do { return i; } while(0)\r
+#define RETURN_FAILURE do { ret = 0; goto exit; } while(0)\r
+#define RETURN_SUCCESS do { ret = 1; goto exit; } while(0)\r
+\r
+#define RETURN_ON_ERROR(i) \\r
+ do { if (i < 0) RETURN_ERROR(i); } while (0)\r
+#define RETURN_ON_SUCCESS(i) \\r
+ do { RETURN_ON_ERROR(i); if (i > 0) RETURN_SUCCESS; } while (0)\r
+#define RETURN_ON_FAILURE(i) \\r
+ do { RETURN_ON_ERROR(i); if (i == 0) RETURN_FAILURE; } while (0)\r
+\r
+#define SFY(x) #x\r
+\r
+#define DATA_STACK_ALLOC(state, type, ptr) \\r
+do { \\r
+ alloc_pos = state->data_stack_base; \\r
+ TRACE(("allocating %s in %" PY_FORMAT_SIZE_T "d " \\r
+ "(%" PY_FORMAT_SIZE_T "d)\n", \\r
+ SFY(type), alloc_pos, sizeof(type))); \\r
+ if (sizeof(type) > state->data_stack_size - alloc_pos) { \\r
+ int j = data_stack_grow(state, sizeof(type)); \\r
+ if (j < 0) return j; \\r
+ if (ctx_pos != -1) \\r
+ DATA_STACK_LOOKUP_AT(state, SRE_MATCH_CONTEXT, ctx, ctx_pos); \\r
+ } \\r
+ ptr = (type*)(state->data_stack+alloc_pos); \\r
+ state->data_stack_base += sizeof(type); \\r
+} while (0)\r
+\r
+#define DATA_STACK_LOOKUP_AT(state, type, ptr, pos) \\r
+do { \\r
+ TRACE(("looking up %s at %" PY_FORMAT_SIZE_T "d\n", SFY(type), pos)); \\r
+ ptr = (type*)(state->data_stack+pos); \\r
+} while (0)\r
+\r
+#define DATA_STACK_PUSH(state, data, size) \\r
+do { \\r
+ TRACE(("copy data in %p to %" PY_FORMAT_SIZE_T "d " \\r
+ "(%" PY_FORMAT_SIZE_T "d)\n", \\r
+ data, state->data_stack_base, size)); \\r
+ if (size > state->data_stack_size - state->data_stack_base) { \\r
+ int j = data_stack_grow(state, size); \\r
+ if (j < 0) return j; \\r
+ if (ctx_pos != -1) \\r
+ DATA_STACK_LOOKUP_AT(state, SRE_MATCH_CONTEXT, ctx, ctx_pos); \\r
+ } \\r
+ memcpy(state->data_stack+state->data_stack_base, data, size); \\r
+ state->data_stack_base += size; \\r
+} while (0)\r
+\r
+#define DATA_STACK_POP(state, data, size, discard) \\r
+do { \\r
+ TRACE(("copy data to %p from %" PY_FORMAT_SIZE_T "d " \\r
+ "(%" PY_FORMAT_SIZE_T "d)\n", \\r
+ data, state->data_stack_base-size, size)); \\r
+ memcpy(data, state->data_stack+state->data_stack_base-size, size); \\r
+ if (discard) \\r
+ state->data_stack_base -= size; \\r
+} while (0)\r
+\r
+#define DATA_STACK_POP_DISCARD(state, size) \\r
+do { \\r
+ TRACE(("discard data from %" PY_FORMAT_SIZE_T "d " \\r
+ "(%" PY_FORMAT_SIZE_T "d)\n", \\r
+ state->data_stack_base-size, size)); \\r
+ state->data_stack_base -= size; \\r
+} while(0)\r
+\r
+#define DATA_PUSH(x) \\r
+ DATA_STACK_PUSH(state, (x), sizeof(*(x)))\r
+#define DATA_POP(x) \\r
+ DATA_STACK_POP(state, (x), sizeof(*(x)), 1)\r
+#define DATA_POP_DISCARD(x) \\r
+ DATA_STACK_POP_DISCARD(state, sizeof(*(x)))\r
+#define DATA_ALLOC(t,p) \\r
+ DATA_STACK_ALLOC(state, t, p)\r
+#define DATA_LOOKUP_AT(t,p,pos) \\r
+ DATA_STACK_LOOKUP_AT(state,t,p,pos)\r
+\r
+#define MARK_PUSH(lastmark) \\r
+ do if (lastmark > 0) { \\r
+ i = lastmark; /* ctx->lastmark may change if reallocated */ \\r
+ DATA_STACK_PUSH(state, state->mark, (i+1)*sizeof(void*)); \\r
+ } while (0)\r
+#define MARK_POP(lastmark) \\r
+ do if (lastmark > 0) { \\r
+ DATA_STACK_POP(state, state->mark, (lastmark+1)*sizeof(void*), 1); \\r
+ } while (0)\r
+#define MARK_POP_KEEP(lastmark) \\r
+ do if (lastmark > 0) { \\r
+ DATA_STACK_POP(state, state->mark, (lastmark+1)*sizeof(void*), 0); \\r
+ } while (0)\r
+#define MARK_POP_DISCARD(lastmark) \\r
+ do if (lastmark > 0) { \\r
+ DATA_STACK_POP_DISCARD(state, (lastmark+1)*sizeof(void*)); \\r
+ } while (0)\r
+\r
+#define JUMP_NONE 0\r
+#define JUMP_MAX_UNTIL_1 1\r
+#define JUMP_MAX_UNTIL_2 2\r
+#define JUMP_MAX_UNTIL_3 3\r
+#define JUMP_MIN_UNTIL_1 4\r
+#define JUMP_MIN_UNTIL_2 5\r
+#define JUMP_MIN_UNTIL_3 6\r
+#define JUMP_REPEAT 7\r
+#define JUMP_REPEAT_ONE_1 8\r
+#define JUMP_REPEAT_ONE_2 9\r
+#define JUMP_MIN_REPEAT_ONE 10\r
+#define JUMP_BRANCH 11\r
+#define JUMP_ASSERT 12\r
+#define JUMP_ASSERT_NOT 13\r
+\r
+#define DO_JUMP(jumpvalue, jumplabel, nextpattern) \\r
+ DATA_ALLOC(SRE_MATCH_CONTEXT, nextctx); \\r
+ nextctx->last_ctx_pos = ctx_pos; \\r
+ nextctx->jump = jumpvalue; \\r
+ nextctx->pattern = nextpattern; \\r
+ ctx_pos = alloc_pos; \\r
+ ctx = nextctx; \\r
+ goto entrance; \\r
+ jumplabel: \\r
+ while (0) /* gcc doesn't like labels at end of scopes */ \\r
+\r
+typedef struct {\r
+ Py_ssize_t last_ctx_pos;\r
+ Py_ssize_t jump;\r
+ SRE_CHAR* ptr;\r
+ SRE_CODE* pattern;\r
+ Py_ssize_t count;\r
+ Py_ssize_t lastmark;\r
+ Py_ssize_t lastindex;\r
+ union {\r
+ SRE_CODE chr;\r
+ SRE_REPEAT* rep;\r
+ } u;\r
+} SRE_MATCH_CONTEXT;\r
+\r
+/* check if string matches the given pattern. returns <0 for\r
+ error, 0 for failure, and 1 for success */\r
+LOCAL(Py_ssize_t)\r
+SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern)\r
+{\r
+ SRE_CHAR* end = (SRE_CHAR *)state->end;\r
+ Py_ssize_t alloc_pos, ctx_pos = -1;\r
+ Py_ssize_t i, ret = 0;\r
+ Py_ssize_t jump;\r
+ unsigned int sigcount=0;\r
+\r
+ SRE_MATCH_CONTEXT* ctx;\r
+ SRE_MATCH_CONTEXT* nextctx;\r
+\r
+ TRACE(("|%p|%p|ENTER\n", pattern, state->ptr));\r
+\r
+ DATA_ALLOC(SRE_MATCH_CONTEXT, ctx);\r
+ ctx->last_ctx_pos = -1;\r
+ ctx->jump = JUMP_NONE;\r
+ ctx->pattern = pattern;\r
+ ctx_pos = alloc_pos;\r
+\r
+entrance:\r
+\r
+ ctx->ptr = (SRE_CHAR *)state->ptr;\r
+\r
+ if (ctx->pattern[0] == SRE_OP_INFO) {\r
+ /* optimization info block */\r
+ /* <INFO> <1=skip> <2=flags> <3=min> ... */\r
+ if (ctx->pattern[3] && (end - ctx->ptr) < ctx->pattern[3]) {\r
+ TRACE(("reject (got %" PY_FORMAT_SIZE_T "d chars, "\r
+ "need %" PY_FORMAT_SIZE_T "d)\n",\r
+ (end - ctx->ptr), (Py_ssize_t) ctx->pattern[3]));\r
+ RETURN_FAILURE;\r
+ }\r
+ ctx->pattern += ctx->pattern[1] + 1;\r
+ }\r
+\r
+ for (;;) {\r
+ ++sigcount;\r
+ if ((0 == (sigcount & 0xfff)) && PyErr_CheckSignals())\r
+ RETURN_ERROR(SRE_ERROR_INTERRUPTED);\r
+\r
+ switch (*ctx->pattern++) {\r
+\r
+ case SRE_OP_MARK:\r
+ /* set mark */\r
+ /* <MARK> <gid> */\r
+ TRACE(("|%p|%p|MARK %d\n", ctx->pattern,\r
+ ctx->ptr, ctx->pattern[0]));\r
+ i = ctx->pattern[0];\r
+ if (i & 1)\r
+ state->lastindex = i/2 + 1;\r
+ if (i > state->lastmark) {\r
+ /* state->lastmark is the highest valid index in the\r
+ state->mark array. If it is increased by more than 1,\r
+ the intervening marks must be set to NULL to signal\r
+ that these marks have not been encountered. */\r
+ Py_ssize_t j = state->lastmark + 1;\r
+ while (j < i)\r
+ state->mark[j++] = NULL;\r
+ state->lastmark = i;\r
+ }\r
+ state->mark[i] = ctx->ptr;\r
+ ctx->pattern++;\r
+ break;\r
+\r
+ case SRE_OP_LITERAL:\r
+ /* match literal string */\r
+ /* <LITERAL> <code> */\r
+ TRACE(("|%p|%p|LITERAL %d\n", ctx->pattern,\r
+ ctx->ptr, *ctx->pattern));\r
+ if (ctx->ptr >= end || (SRE_CODE) ctx->ptr[0] != ctx->pattern[0])\r
+ RETURN_FAILURE;\r
+ ctx->pattern++;\r
+ ctx->ptr++;\r
+ break;\r
+\r
+ case SRE_OP_NOT_LITERAL:\r
+ /* match anything that is not literal character */\r
+ /* <NOT_LITERAL> <code> */\r
+ TRACE(("|%p|%p|NOT_LITERAL %d\n", ctx->pattern,\r
+ ctx->ptr, *ctx->pattern));\r
+ if (ctx->ptr >= end || (SRE_CODE) ctx->ptr[0] == ctx->pattern[0])\r
+ RETURN_FAILURE;\r
+ ctx->pattern++;\r
+ ctx->ptr++;\r
+ break;\r
+\r
+ case SRE_OP_SUCCESS:\r
+ /* end of pattern */\r
+ TRACE(("|%p|%p|SUCCESS\n", ctx->pattern, ctx->ptr));\r
+ state->ptr = ctx->ptr;\r
+ RETURN_SUCCESS;\r
+\r
+ case SRE_OP_AT:\r
+ /* match at given position */\r
+ /* <AT> <code> */\r
+ TRACE(("|%p|%p|AT %d\n", ctx->pattern, ctx->ptr, *ctx->pattern));\r
+ if (!SRE_AT(state, ctx->ptr, *ctx->pattern))\r
+ RETURN_FAILURE;\r
+ ctx->pattern++;\r
+ break;\r
+\r
+ case SRE_OP_CATEGORY:\r
+ /* match at given category */\r
+ /* <CATEGORY> <code> */\r
+ TRACE(("|%p|%p|CATEGORY %d\n", ctx->pattern,\r
+ ctx->ptr, *ctx->pattern));\r
+ if (ctx->ptr >= end || !sre_category(ctx->pattern[0], ctx->ptr[0]))\r
+ RETURN_FAILURE;\r
+ ctx->pattern++;\r
+ ctx->ptr++;\r
+ break;\r
+\r
+ case SRE_OP_ANY:\r
+ /* match anything (except a newline) */\r
+ /* <ANY> */\r
+ TRACE(("|%p|%p|ANY\n", ctx->pattern, ctx->ptr));\r
+ if (ctx->ptr >= end || SRE_IS_LINEBREAK(ctx->ptr[0]))\r
+ RETURN_FAILURE;\r
+ ctx->ptr++;\r
+ break;\r
+\r
+ case SRE_OP_ANY_ALL:\r
+ /* match anything */\r
+ /* <ANY_ALL> */\r
+ TRACE(("|%p|%p|ANY_ALL\n", ctx->pattern, ctx->ptr));\r
+ if (ctx->ptr >= end)\r
+ RETURN_FAILURE;\r
+ ctx->ptr++;\r
+ break;\r
+\r
+ case SRE_OP_IN:\r
+ /* match set member (or non_member) */\r
+ /* <IN> <skip> <set> */\r
+ TRACE(("|%p|%p|IN\n", ctx->pattern, ctx->ptr));\r
+ if (ctx->ptr >= end || !SRE_CHARSET(ctx->pattern + 1, *ctx->ptr))\r
+ RETURN_FAILURE;\r
+ ctx->pattern += ctx->pattern[0];\r
+ ctx->ptr++;\r
+ break;\r
+\r
+ case SRE_OP_LITERAL_IGNORE:\r
+ TRACE(("|%p|%p|LITERAL_IGNORE %d\n",\r
+ ctx->pattern, ctx->ptr, ctx->pattern[0]));\r
+ if (ctx->ptr >= end ||\r
+ state->lower(*ctx->ptr) != state->lower(*ctx->pattern))\r
+ RETURN_FAILURE;\r
+ ctx->pattern++;\r
+ ctx->ptr++;\r
+ break;\r
+\r
+ case SRE_OP_NOT_LITERAL_IGNORE:\r
+ TRACE(("|%p|%p|NOT_LITERAL_IGNORE %d\n",\r
+ ctx->pattern, ctx->ptr, *ctx->pattern));\r
+ if (ctx->ptr >= end ||\r
+ state->lower(*ctx->ptr) == state->lower(*ctx->pattern))\r
+ RETURN_FAILURE;\r
+ ctx->pattern++;\r
+ ctx->ptr++;\r
+ break;\r
+\r
+ case SRE_OP_IN_IGNORE:\r
+ TRACE(("|%p|%p|IN_IGNORE\n", ctx->pattern, ctx->ptr));\r
+ if (ctx->ptr >= end\r
+ || !SRE_CHARSET(ctx->pattern+1,\r
+ (SRE_CODE)state->lower(*ctx->ptr)))\r
+ RETURN_FAILURE;\r
+ ctx->pattern += ctx->pattern[0];\r
+ ctx->ptr++;\r
+ break;\r
+\r
+ case SRE_OP_JUMP:\r
+ case SRE_OP_INFO:\r
+ /* jump forward */\r
+ /* <JUMP> <offset> */\r
+ TRACE(("|%p|%p|JUMP %d\n", ctx->pattern,\r
+ ctx->ptr, ctx->pattern[0]));\r
+ ctx->pattern += ctx->pattern[0];\r
+ break;\r
+\r
+ case SRE_OP_BRANCH:\r
+ /* alternation */\r
+ /* <BRANCH> <0=skip> code <JUMP> ... <NULL> */\r
+ TRACE(("|%p|%p|BRANCH\n", ctx->pattern, ctx->ptr));\r
+ LASTMARK_SAVE();\r
+ ctx->u.rep = state->repeat;\r
+ if (ctx->u.rep)\r
+ MARK_PUSH(ctx->lastmark);\r
+ for (; ctx->pattern[0]; ctx->pattern += ctx->pattern[0]) {\r
+ if (ctx->pattern[1] == SRE_OP_LITERAL &&\r
+ (ctx->ptr >= end ||\r
+ (SRE_CODE) *ctx->ptr != ctx->pattern[2]))\r
+ continue;\r
+ if (ctx->pattern[1] == SRE_OP_IN &&\r
+ (ctx->ptr >= end ||\r
+ !SRE_CHARSET(ctx->pattern + 3, (SRE_CODE) *ctx->ptr)))\r
+ continue;\r
+ state->ptr = ctx->ptr;\r
+ DO_JUMP(JUMP_BRANCH, jump_branch, ctx->pattern+1);\r
+ if (ret) {\r
+ if (ctx->u.rep)\r
+ MARK_POP_DISCARD(ctx->lastmark);\r
+ RETURN_ON_ERROR(ret);\r
+ RETURN_SUCCESS;\r
+ }\r
+ if (ctx->u.rep)\r
+ MARK_POP_KEEP(ctx->lastmark);\r
+ LASTMARK_RESTORE();\r
+ }\r
+ if (ctx->u.rep)\r
+ MARK_POP_DISCARD(ctx->lastmark);\r
+ RETURN_FAILURE;\r
+\r
+ case SRE_OP_REPEAT_ONE:\r
+ /* match repeated sequence (maximizing regexp) */\r
+\r
+ /* this operator only works if the repeated item is\r
+ exactly one character wide, and we're not already\r
+ collecting backtracking points. for other cases,\r
+ use the MAX_REPEAT operator */\r
+\r
+ /* <REPEAT_ONE> <skip> <1=min> <2=max> item <SUCCESS> tail */\r
+\r
+ TRACE(("|%p|%p|REPEAT_ONE %d %d\n", ctx->pattern, ctx->ptr,\r
+ ctx->pattern[1], ctx->pattern[2]));\r
+\r
+ if ((Py_ssize_t) ctx->pattern[1] > end - ctx->ptr)\r
+ RETURN_FAILURE; /* cannot match */\r
+\r
+ state->ptr = ctx->ptr;\r
+\r
+ ret = SRE_COUNT(state, ctx->pattern+3, ctx->pattern[2]);\r
+ RETURN_ON_ERROR(ret);\r
+ DATA_LOOKUP_AT(SRE_MATCH_CONTEXT, ctx, ctx_pos);\r
+ ctx->count = ret;\r
+ ctx->ptr += ctx->count;\r
+\r
+ /* when we arrive here, count contains the number of\r
+ matches, and ctx->ptr points to the tail of the target\r
+ string. check if the rest of the pattern matches,\r
+ and backtrack if not. */\r
+\r
+ if (ctx->count < (Py_ssize_t) ctx->pattern[1])\r
+ RETURN_FAILURE;\r
+\r
+ if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS) {\r
+ /* tail is empty. we're finished */\r
+ state->ptr = ctx->ptr;\r
+ RETURN_SUCCESS;\r
+ }\r
+\r
+ LASTMARK_SAVE();\r
+\r
+ if (ctx->pattern[ctx->pattern[0]] == SRE_OP_LITERAL) {\r
+ /* tail starts with a literal. skip positions where\r
+ the rest of the pattern cannot possibly match */\r
+ ctx->u.chr = ctx->pattern[ctx->pattern[0]+1];\r
+ for (;;) {\r
+ while (ctx->count >= (Py_ssize_t) ctx->pattern[1] &&\r
+ (ctx->ptr >= end || *ctx->ptr != ctx->u.chr)) {\r
+ ctx->ptr--;\r
+ ctx->count--;\r
+ }\r
+ if (ctx->count < (Py_ssize_t) ctx->pattern[1])\r
+ break;\r
+ state->ptr = ctx->ptr;\r
+ DO_JUMP(JUMP_REPEAT_ONE_1, jump_repeat_one_1,\r
+ ctx->pattern+ctx->pattern[0]);\r
+ if (ret) {\r
+ RETURN_ON_ERROR(ret);\r
+ RETURN_SUCCESS;\r
+ }\r
+\r
+ LASTMARK_RESTORE();\r
+\r
+ ctx->ptr--;\r
+ ctx->count--;\r
+ }\r
+\r
+ } else {\r
+ /* general case */\r
+ while (ctx->count >= (Py_ssize_t) ctx->pattern[1]) {\r
+ state->ptr = ctx->ptr;\r
+ DO_JUMP(JUMP_REPEAT_ONE_2, jump_repeat_one_2,\r
+ ctx->pattern+ctx->pattern[0]);\r
+ if (ret) {\r
+ RETURN_ON_ERROR(ret);\r
+ RETURN_SUCCESS;\r
+ }\r
+ ctx->ptr--;\r
+ ctx->count--;\r
+ LASTMARK_RESTORE();\r
+ }\r
+ }\r
+ RETURN_FAILURE;\r
+\r
+ case SRE_OP_MIN_REPEAT_ONE:\r
+ /* match repeated sequence (minimizing regexp) */\r
+\r
+ /* this operator only works if the repeated item is\r
+ exactly one character wide, and we're not already\r
+ collecting backtracking points. for other cases,\r
+ use the MIN_REPEAT operator */\r
+\r
+ /* <MIN_REPEAT_ONE> <skip> <1=min> <2=max> item <SUCCESS> tail */\r
+\r
+ TRACE(("|%p|%p|MIN_REPEAT_ONE %d %d\n", ctx->pattern, ctx->ptr,\r
+ ctx->pattern[1], ctx->pattern[2]));\r
+\r
+ if ((Py_ssize_t) ctx->pattern[1] > end - ctx->ptr)\r
+ RETURN_FAILURE; /* cannot match */\r
+\r
+ state->ptr = ctx->ptr;\r
+\r
+ if (ctx->pattern[1] == 0)\r
+ ctx->count = 0;\r
+ else {\r
+ /* count using pattern min as the maximum */\r
+ ret = SRE_COUNT(state, ctx->pattern+3, ctx->pattern[1]);\r
+ RETURN_ON_ERROR(ret);\r
+ DATA_LOOKUP_AT(SRE_MATCH_CONTEXT, ctx, ctx_pos);\r
+ if (ret < (Py_ssize_t) ctx->pattern[1])\r
+ /* didn't match minimum number of times */\r
+ RETURN_FAILURE;\r
+ /* advance past minimum matches of repeat */\r
+ ctx->count = ret;\r
+ ctx->ptr += ctx->count;\r
+ }\r
+\r
+ if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS) {\r
+ /* tail is empty. we're finished */\r
+ state->ptr = ctx->ptr;\r
+ RETURN_SUCCESS;\r
+\r
+ } else {\r
+ /* general case */\r
+ LASTMARK_SAVE();\r
+ while ((Py_ssize_t)ctx->pattern[2] == SRE_MAXREPEAT\r
+ || ctx->count <= (Py_ssize_t)ctx->pattern[2]) {\r
+ state->ptr = ctx->ptr;\r
+ DO_JUMP(JUMP_MIN_REPEAT_ONE,jump_min_repeat_one,\r
+ ctx->pattern+ctx->pattern[0]);\r
+ if (ret) {\r
+ RETURN_ON_ERROR(ret);\r
+ RETURN_SUCCESS;\r
+ }\r
+ state->ptr = ctx->ptr;\r
+ ret = SRE_COUNT(state, ctx->pattern+3, 1);\r
+ RETURN_ON_ERROR(ret);\r
+ DATA_LOOKUP_AT(SRE_MATCH_CONTEXT, ctx, ctx_pos);\r
+ if (ret == 0)\r
+ break;\r
+ assert(ret == 1);\r
+ ctx->ptr++;\r
+ ctx->count++;\r
+ LASTMARK_RESTORE();\r
+ }\r
+ }\r
+ RETURN_FAILURE;\r
+\r
+ case SRE_OP_REPEAT:\r
+ /* create repeat context. all the hard work is done\r
+ by the UNTIL operator (MAX_UNTIL, MIN_UNTIL) */\r
+ /* <REPEAT> <skip> <1=min> <2=max> item <UNTIL> tail */\r
+ TRACE(("|%p|%p|REPEAT %d %d\n", ctx->pattern, ctx->ptr,\r
+ ctx->pattern[1], ctx->pattern[2]));\r
+\r
+ /* install new repeat context */\r
+ ctx->u.rep = (SRE_REPEAT*) PyObject_MALLOC(sizeof(*ctx->u.rep));\r
+ if (!ctx->u.rep) {\r
+ PyErr_NoMemory();\r
+ RETURN_FAILURE;\r
+ }\r
+ ctx->u.rep->count = -1;\r
+ ctx->u.rep->pattern = ctx->pattern;\r
+ ctx->u.rep->prev = state->repeat;\r
+ ctx->u.rep->last_ptr = NULL;\r
+ state->repeat = ctx->u.rep;\r
+\r
+ state->ptr = ctx->ptr;\r
+ DO_JUMP(JUMP_REPEAT, jump_repeat, ctx->pattern+ctx->pattern[0]);\r
+ state->repeat = ctx->u.rep->prev;\r
+ PyObject_FREE(ctx->u.rep);\r
+\r
+ if (ret) {\r
+ RETURN_ON_ERROR(ret);\r
+ RETURN_SUCCESS;\r
+ }\r
+ RETURN_FAILURE;\r
+\r
+ case SRE_OP_MAX_UNTIL:\r
+ /* maximizing repeat */\r
+ /* <REPEAT> <skip> <1=min> <2=max> item <MAX_UNTIL> tail */\r
+\r
+ /* FIXME: we probably need to deal with zero-width\r
+ matches in here... */\r
+\r
+ ctx->u.rep = state->repeat;\r
+ if (!ctx->u.rep)\r
+ RETURN_ERROR(SRE_ERROR_STATE);\r
+\r
+ state->ptr = ctx->ptr;\r
+\r
+ ctx->count = ctx->u.rep->count+1;\r
+\r
+ TRACE(("|%p|%p|MAX_UNTIL %" PY_FORMAT_SIZE_T "d\n", ctx->pattern,\r
+ ctx->ptr, ctx->count));\r
+\r
+ if (ctx->count < (Py_ssize_t) ctx->u.rep->pattern[1]) {\r
+ /* not enough matches */\r
+ ctx->u.rep->count = ctx->count;\r
+ DO_JUMP(JUMP_MAX_UNTIL_1, jump_max_until_1,\r
+ ctx->u.rep->pattern+3);\r
+ if (ret) {\r
+ RETURN_ON_ERROR(ret);\r
+ RETURN_SUCCESS;\r
+ }\r
+ ctx->u.rep->count = ctx->count-1;\r
+ state->ptr = ctx->ptr;\r
+ RETURN_FAILURE;\r
+ }\r
+\r
+ if ((ctx->count < (Py_ssize_t) ctx->u.rep->pattern[2] ||\r
+ ctx->u.rep->pattern[2] == SRE_MAXREPEAT) &&\r
+ state->ptr != ctx->u.rep->last_ptr) {\r
+ /* we may have enough matches, but if we can\r
+ match another item, do so */\r
+ ctx->u.rep->count = ctx->count;\r
+ LASTMARK_SAVE();\r
+ MARK_PUSH(ctx->lastmark);\r
+ /* zero-width match protection */\r
+ DATA_PUSH(&ctx->u.rep->last_ptr);\r
+ ctx->u.rep->last_ptr = state->ptr;\r
+ DO_JUMP(JUMP_MAX_UNTIL_2, jump_max_until_2,\r
+ ctx->u.rep->pattern+3);\r
+ DATA_POP(&ctx->u.rep->last_ptr);\r
+ if (ret) {\r
+ MARK_POP_DISCARD(ctx->lastmark);\r
+ RETURN_ON_ERROR(ret);\r
+ RETURN_SUCCESS;\r
+ }\r
+ MARK_POP(ctx->lastmark);\r
+ LASTMARK_RESTORE();\r
+ ctx->u.rep->count = ctx->count-1;\r
+ state->ptr = ctx->ptr;\r
+ }\r
+\r
+ /* cannot match more repeated items here. make sure the\r
+ tail matches */\r
+ state->repeat = ctx->u.rep->prev;\r
+ DO_JUMP(JUMP_MAX_UNTIL_3, jump_max_until_3, ctx->pattern);\r
+ RETURN_ON_SUCCESS(ret);\r
+ state->repeat = ctx->u.rep;\r
+ state->ptr = ctx->ptr;\r
+ RETURN_FAILURE;\r
+\r
+ case SRE_OP_MIN_UNTIL:\r
+ /* minimizing repeat */\r
+ /* <REPEAT> <skip> <1=min> <2=max> item <MIN_UNTIL> tail */\r
+\r
+ ctx->u.rep = state->repeat;\r
+ if (!ctx->u.rep)\r
+ RETURN_ERROR(SRE_ERROR_STATE);\r
+\r
+ state->ptr = ctx->ptr;\r
+\r
+ ctx->count = ctx->u.rep->count+1;\r
+\r
+ TRACE(("|%p|%p|MIN_UNTIL %" PY_FORMAT_SIZE_T "d %p\n", ctx->pattern,\r
+ ctx->ptr, ctx->count, ctx->u.rep->pattern));\r
+\r
+ if (ctx->count < (Py_ssize_t) ctx->u.rep->pattern[1]) {\r
+ /* not enough matches */\r
+ ctx->u.rep->count = ctx->count;\r
+ DO_JUMP(JUMP_MIN_UNTIL_1, jump_min_until_1,\r
+ ctx->u.rep->pattern+3);\r
+ if (ret) {\r
+ RETURN_ON_ERROR(ret);\r
+ RETURN_SUCCESS;\r
+ }\r
+ ctx->u.rep->count = ctx->count-1;\r
+ state->ptr = ctx->ptr;\r
+ RETURN_FAILURE;\r
+ }\r
+\r
+ LASTMARK_SAVE();\r
+\r
+ /* see if the tail matches */\r
+ state->repeat = ctx->u.rep->prev;\r
+ DO_JUMP(JUMP_MIN_UNTIL_2, jump_min_until_2, ctx->pattern);\r
+ if (ret) {\r
+ RETURN_ON_ERROR(ret);\r
+ RETURN_SUCCESS;\r
+ }\r
+\r
+ state->repeat = ctx->u.rep;\r
+ state->ptr = ctx->ptr;\r
+\r
+ LASTMARK_RESTORE();\r
+\r
+ if ((ctx->count >= (Py_ssize_t) ctx->u.rep->pattern[2]\r
+ && ctx->u.rep->pattern[2] != SRE_MAXREPEAT) ||\r
+ state->ptr == ctx->u.rep->last_ptr)\r
+ RETURN_FAILURE;\r
+\r
+ ctx->u.rep->count = ctx->count;\r
+ /* zero-width match protection */\r
+ DATA_PUSH(&ctx->u.rep->last_ptr);\r
+ ctx->u.rep->last_ptr = state->ptr;\r
+ DO_JUMP(JUMP_MIN_UNTIL_3,jump_min_until_3,\r
+ ctx->u.rep->pattern+3);\r
+ DATA_POP(&ctx->u.rep->last_ptr);\r
+ if (ret) {\r
+ RETURN_ON_ERROR(ret);\r
+ RETURN_SUCCESS;\r
+ }\r
+ ctx->u.rep->count = ctx->count-1;\r
+ state->ptr = ctx->ptr;\r
+ RETURN_FAILURE;\r
+\r
+ case SRE_OP_GROUPREF:\r
+ /* match backreference */\r
+ TRACE(("|%p|%p|GROUPREF %d\n", ctx->pattern,\r
+ ctx->ptr, ctx->pattern[0]));\r
+ i = ctx->pattern[0];\r
+ {\r
+ Py_ssize_t groupref = i+i;\r
+ if (groupref >= state->lastmark) {\r
+ RETURN_FAILURE;\r
+ } else {\r
+ SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];\r
+ SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];\r
+ if (!p || !e || e < p)\r
+ RETURN_FAILURE;\r
+ while (p < e) {\r
+ if (ctx->ptr >= end || *ctx->ptr != *p)\r
+ RETURN_FAILURE;\r
+ p++; ctx->ptr++;\r
+ }\r
+ }\r
+ }\r
+ ctx->pattern++;\r
+ break;\r
+\r
+ case SRE_OP_GROUPREF_IGNORE:\r
+ /* match backreference */\r
+ TRACE(("|%p|%p|GROUPREF_IGNORE %d\n", ctx->pattern,\r
+ ctx->ptr, ctx->pattern[0]));\r
+ i = ctx->pattern[0];\r
+ {\r
+ Py_ssize_t groupref = i+i;\r
+ if (groupref >= state->lastmark) {\r
+ RETURN_FAILURE;\r
+ } else {\r
+ SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];\r
+ SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];\r
+ if (!p || !e || e < p)\r
+ RETURN_FAILURE;\r
+ while (p < e) {\r
+ if (ctx->ptr >= end ||\r
+ state->lower(*ctx->ptr) != state->lower(*p))\r
+ RETURN_FAILURE;\r
+ p++; ctx->ptr++;\r
+ }\r
+ }\r
+ }\r
+ ctx->pattern++;\r
+ break;\r
+\r
+ case SRE_OP_GROUPREF_EXISTS:\r
+ TRACE(("|%p|%p|GROUPREF_EXISTS %d\n", ctx->pattern,\r
+ ctx->ptr, ctx->pattern[0]));\r
+ /* <GROUPREF_EXISTS> <group> <skip> codeyes <JUMP> codeno ... */\r
+ i = ctx->pattern[0];\r
+ {\r
+ Py_ssize_t groupref = i+i;\r
+ if (groupref >= state->lastmark) {\r
+ ctx->pattern += ctx->pattern[1];\r
+ break;\r
+ } else {\r
+ SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];\r
+ SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];\r
+ if (!p || !e || e < p) {\r
+ ctx->pattern += ctx->pattern[1];\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ ctx->pattern += 2;\r
+ break;\r
+\r
+ case SRE_OP_ASSERT:\r
+ /* assert subpattern */\r
+ /* <ASSERT> <skip> <back> <pattern> */\r
+ TRACE(("|%p|%p|ASSERT %d\n", ctx->pattern,\r
+ ctx->ptr, ctx->pattern[1]));\r
+ state->ptr = ctx->ptr - ctx->pattern[1];\r
+ if (state->ptr < state->beginning)\r
+ RETURN_FAILURE;\r
+ DO_JUMP(JUMP_ASSERT, jump_assert, ctx->pattern+2);\r
+ RETURN_ON_FAILURE(ret);\r
+ ctx->pattern += ctx->pattern[0];\r
+ break;\r
+\r
+ case SRE_OP_ASSERT_NOT:\r
+ /* assert not subpattern */\r
+ /* <ASSERT_NOT> <skip> <back> <pattern> */\r
+ TRACE(("|%p|%p|ASSERT_NOT %d\n", ctx->pattern,\r
+ ctx->ptr, ctx->pattern[1]));\r
+ state->ptr = ctx->ptr - ctx->pattern[1];\r
+ if (state->ptr >= state->beginning) {\r
+ DO_JUMP(JUMP_ASSERT_NOT, jump_assert_not, ctx->pattern+2);\r
+ if (ret) {\r
+ RETURN_ON_ERROR(ret);\r
+ RETURN_FAILURE;\r
+ }\r
+ }\r
+ ctx->pattern += ctx->pattern[0];\r
+ break;\r
+\r
+ case SRE_OP_FAILURE:\r
+ /* immediate failure */\r
+ TRACE(("|%p|%p|FAILURE\n", ctx->pattern, ctx->ptr));\r
+ RETURN_FAILURE;\r
+\r
+ default:\r
+ TRACE(("|%p|%p|UNKNOWN %d\n", ctx->pattern, ctx->ptr,\r
+ ctx->pattern[-1]));\r
+ RETURN_ERROR(SRE_ERROR_ILLEGAL);\r
+ }\r
+ }\r
+\r
+exit:\r
+ ctx_pos = ctx->last_ctx_pos;\r
+ jump = ctx->jump;\r
+ DATA_POP_DISCARD(ctx);\r
+ if (ctx_pos == -1)\r
+ return ret;\r
+ DATA_LOOKUP_AT(SRE_MATCH_CONTEXT, ctx, ctx_pos);\r
+\r
+ switch (jump) {\r
+ case JUMP_MAX_UNTIL_2:\r
+ TRACE(("|%p|%p|JUMP_MAX_UNTIL_2\n", ctx->pattern, ctx->ptr));\r
+ goto jump_max_until_2;\r
+ case JUMP_MAX_UNTIL_3:\r
+ TRACE(("|%p|%p|JUMP_MAX_UNTIL_3\n", ctx->pattern, ctx->ptr));\r
+ goto jump_max_until_3;\r
+ case JUMP_MIN_UNTIL_2:\r
+ TRACE(("|%p|%p|JUMP_MIN_UNTIL_2\n", ctx->pattern, ctx->ptr));\r
+ goto jump_min_until_2;\r
+ case JUMP_MIN_UNTIL_3:\r
+ TRACE(("|%p|%p|JUMP_MIN_UNTIL_3\n", ctx->pattern, ctx->ptr));\r
+ goto jump_min_until_3;\r
+ case JUMP_BRANCH:\r
+ TRACE(("|%p|%p|JUMP_BRANCH\n", ctx->pattern, ctx->ptr));\r
+ goto jump_branch;\r
+ case JUMP_MAX_UNTIL_1:\r
+ TRACE(("|%p|%p|JUMP_MAX_UNTIL_1\n", ctx->pattern, ctx->ptr));\r
+ goto jump_max_until_1;\r
+ case JUMP_MIN_UNTIL_1:\r
+ TRACE(("|%p|%p|JUMP_MIN_UNTIL_1\n", ctx->pattern, ctx->ptr));\r
+ goto jump_min_until_1;\r
+ case JUMP_REPEAT:\r
+ TRACE(("|%p|%p|JUMP_REPEAT\n", ctx->pattern, ctx->ptr));\r
+ goto jump_repeat;\r
+ case JUMP_REPEAT_ONE_1:\r
+ TRACE(("|%p|%p|JUMP_REPEAT_ONE_1\n", ctx->pattern, ctx->ptr));\r
+ goto jump_repeat_one_1;\r
+ case JUMP_REPEAT_ONE_2:\r
+ TRACE(("|%p|%p|JUMP_REPEAT_ONE_2\n", ctx->pattern, ctx->ptr));\r
+ goto jump_repeat_one_2;\r
+ case JUMP_MIN_REPEAT_ONE:\r
+ TRACE(("|%p|%p|JUMP_MIN_REPEAT_ONE\n", ctx->pattern, ctx->ptr));\r
+ goto jump_min_repeat_one;\r
+ case JUMP_ASSERT:\r
+ TRACE(("|%p|%p|JUMP_ASSERT\n", ctx->pattern, ctx->ptr));\r
+ goto jump_assert;\r
+ case JUMP_ASSERT_NOT:\r
+ TRACE(("|%p|%p|JUMP_ASSERT_NOT\n", ctx->pattern, ctx->ptr));\r
+ goto jump_assert_not;\r
+ case JUMP_NONE:\r
+ TRACE(("|%p|%p|RETURN %" PY_FORMAT_SIZE_T "d\n", ctx->pattern,\r
+ ctx->ptr, ret));\r
+ break;\r
+ }\r
+\r
+ return ret; /* should never get here */\r
+}\r
+\r
+LOCAL(Py_ssize_t)\r
+SRE_SEARCH(SRE_STATE* state, SRE_CODE* pattern)\r
+{\r
+ SRE_CHAR* ptr = (SRE_CHAR *)state->start;\r
+ SRE_CHAR* end = (SRE_CHAR *)state->end;\r
+ Py_ssize_t status = 0;\r
+ Py_ssize_t prefix_len = 0;\r
+ Py_ssize_t prefix_skip = 0;\r
+ SRE_CODE* prefix = NULL;\r
+ SRE_CODE* charset = NULL;\r
+ SRE_CODE* overlap = NULL;\r
+ int flags = 0;\r
+\r
+ if (pattern[0] == SRE_OP_INFO) {\r
+ /* optimization info block */\r
+ /* <INFO> <1=skip> <2=flags> <3=min> <4=max> <5=prefix info> */\r
+\r
+ flags = pattern[2];\r
+\r
+ if (pattern[3] > 1) {\r
+ /* adjust end point (but make sure we leave at least one\r
+ character in there, so literal search will work) */\r
+ end -= pattern[3]-1;\r
+ if (end <= ptr)\r
+ end = ptr+1;\r
+ }\r
+\r
+ if (flags & SRE_INFO_PREFIX) {\r
+ /* pattern starts with a known prefix */\r
+ /* <length> <skip> <prefix data> <overlap data> */\r
+ prefix_len = pattern[5];\r
+ prefix_skip = pattern[6];\r
+ prefix = pattern + 7;\r
+ overlap = prefix + prefix_len - 1;\r
+ } else if (flags & SRE_INFO_CHARSET)\r
+ /* pattern starts with a character from a known set */\r
+ /* <charset> */\r
+ charset = pattern + 5;\r
+\r
+ pattern += 1 + pattern[1];\r
+ }\r
+\r
+ TRACE(("prefix = %p %" PY_FORMAT_SIZE_T "d %" PY_FORMAT_SIZE_T "d\n",\r
+ prefix, prefix_len, prefix_skip));\r
+ TRACE(("charset = %p\n", charset));\r
+\r
+#if defined(USE_FAST_SEARCH)\r
+ if (prefix_len > 1) {\r
+ /* pattern starts with a known prefix. use the overlap\r
+ table to skip forward as fast as we possibly can */\r
+ Py_ssize_t i = 0;\r
+ end = (SRE_CHAR *)state->end;\r
+ while (ptr < end) {\r
+ for (;;) {\r
+ if ((SRE_CODE) ptr[0] != prefix[i]) {\r
+ if (!i)\r
+ break;\r
+ else\r
+ i = overlap[i];\r
+ } else {\r
+ if (++i == prefix_len) {\r
+ /* found a potential match */\r
+ TRACE(("|%p|%p|SEARCH SCAN\n", pattern, ptr));\r
+ state->start = ptr + 1 - prefix_len;\r
+ state->ptr = ptr + 1 - prefix_len + prefix_skip;\r
+ if (flags & SRE_INFO_LITERAL)\r
+ return 1; /* we got all of it */\r
+ status = SRE_MATCH(state, pattern + 2*prefix_skip);\r
+ if (status != 0)\r
+ return status;\r
+ /* close but no cigar -- try again */\r
+ i = overlap[i];\r
+ }\r
+ break;\r
+ }\r
+ }\r
+ ptr++;\r
+ }\r
+ return 0;\r
+ }\r
+#endif\r
+\r
+ if (pattern[0] == SRE_OP_LITERAL) {\r
+ /* pattern starts with a literal character. this is used\r
+ for short prefixes, and if fast search is disabled */\r
+ SRE_CODE chr = pattern[1];\r
+ end = (SRE_CHAR *)state->end;\r
+ for (;;) {\r
+ while (ptr < end && (SRE_CODE) ptr[0] != chr)\r
+ ptr++;\r
+ if (ptr >= end)\r
+ return 0;\r
+ TRACE(("|%p|%p|SEARCH LITERAL\n", pattern, ptr));\r
+ state->start = ptr;\r
+ state->ptr = ++ptr;\r
+ if (flags & SRE_INFO_LITERAL)\r
+ return 1; /* we got all of it */\r
+ status = SRE_MATCH(state, pattern + 2);\r
+ if (status != 0)\r
+ break;\r
+ }\r
+ } else if (charset) {\r
+ /* pattern starts with a character from a known set */\r
+ end = (SRE_CHAR *)state->end;\r
+ for (;;) {\r
+ while (ptr < end && !SRE_CHARSET(charset, ptr[0]))\r
+ ptr++;\r
+ if (ptr >= end)\r
+ return 0;\r
+ TRACE(("|%p|%p|SEARCH CHARSET\n", pattern, ptr));\r
+ state->start = ptr;\r
+ state->ptr = ptr;\r
+ status = SRE_MATCH(state, pattern);\r
+ if (status != 0)\r
+ break;\r
+ ptr++;\r
+ }\r
+ } else\r
+ /* general case */\r
+ while (ptr <= end) {\r
+ TRACE(("|%p|%p|SEARCH\n", pattern, ptr));\r
+ state->start = state->ptr = ptr++;\r
+ status = SRE_MATCH(state, pattern);\r
+ if (status != 0)\r
+ break;\r
+ }\r
+\r
+ return status;\r
+}\r
+\r
+LOCAL(int)\r
+SRE_LITERAL_TEMPLATE(SRE_CHAR* ptr, Py_ssize_t len)\r
+{\r
+ /* check if given string is a literal template (i.e. no escapes) */\r
+ while (len-- > 0)\r
+ if (*ptr++ == '\\')\r
+ return 0;\r
+ return 1;\r
+}\r
+\r
+#if !defined(SRE_RECURSIVE)\r
+\r
+/* -------------------------------------------------------------------- */\r
+/* factories and destructors */\r
+\r
+/* see sre.h for object declarations */\r
+static PyObject*pattern_new_match(PatternObject*, SRE_STATE*, int);\r
+static PyObject*pattern_scanner(PatternObject*, PyObject*);\r
+\r
+static PyObject *\r
+sre_codesize(PyObject* self, PyObject *unused)\r
+{\r
+ return PyInt_FromSize_t(sizeof(SRE_CODE));\r
+}\r
+\r
+static PyObject *\r
+sre_getlower(PyObject* self, PyObject* args)\r
+{\r
+ int character, flags;\r
+ if (!PyArg_ParseTuple(args, "ii", &character, &flags))\r
+ return NULL;\r
+ if (flags & SRE_FLAG_LOCALE)\r
+ return Py_BuildValue("i", sre_lower_locale(character));\r
+ if (flags & SRE_FLAG_UNICODE)\r
+#if defined(HAVE_UNICODE)\r
+ return Py_BuildValue("i", sre_lower_unicode(character));\r
+#else\r
+ return Py_BuildValue("i", sre_lower_locale(character));\r
+#endif\r
+ return Py_BuildValue("i", sre_lower(character));\r
+}\r
+\r
+LOCAL(void)\r
+state_reset(SRE_STATE* state)\r
+{\r
+ /* FIXME: dynamic! */\r
+ /*memset(state->mark, 0, sizeof(*state->mark) * SRE_MARK_SIZE);*/\r
+\r
+ state->lastmark = -1;\r
+ state->lastindex = -1;\r
+\r
+ state->repeat = NULL;\r
+\r
+ data_stack_dealloc(state);\r
+}\r
+\r
+static void*\r
+getstring(PyObject* string, Py_ssize_t* p_length, int* p_charsize)\r
+{\r
+ /* given a python object, return a data pointer, a length (in\r
+ characters), and a character size. return NULL if the object\r
+ is not a string (or not compatible) */\r
+\r
+ PyBufferProcs *buffer;\r
+ Py_ssize_t size, bytes;\r
+ int charsize;\r
+ void* ptr;\r
+\r
+#if defined(HAVE_UNICODE)\r
+ if (PyUnicode_Check(string)) {\r
+ /* unicode strings doesn't always support the buffer interface */\r
+ ptr = (void*) PyUnicode_AS_DATA(string);\r
+ /* bytes = PyUnicode_GET_DATA_SIZE(string); */\r
+ size = PyUnicode_GET_SIZE(string);\r
+ charsize = sizeof(Py_UNICODE);\r
+\r
+ } else {\r
+#endif\r
+\r
+ /* get pointer to string buffer */\r
+ buffer = Py_TYPE(string)->tp_as_buffer;\r
+ if (!buffer || !buffer->bf_getreadbuffer || !buffer->bf_getsegcount ||\r
+ buffer->bf_getsegcount(string, NULL) != 1) {\r
+ PyErr_SetString(PyExc_TypeError, "expected string or buffer");\r
+ return NULL;\r
+ }\r
+\r
+ /* determine buffer size */\r
+ bytes = buffer->bf_getreadbuffer(string, 0, &ptr);\r
+ if (bytes < 0) {\r
+ PyErr_SetString(PyExc_TypeError, "buffer has negative size");\r
+ return NULL;\r
+ }\r
+\r
+ /* determine character size */\r
+#if PY_VERSION_HEX >= 0x01060000\r
+ size = PyObject_Size(string);\r
+#else\r
+ size = PyObject_Length(string);\r
+#endif\r
+\r
+ if (PyString_Check(string) || bytes == size)\r
+ charsize = 1;\r
+#if defined(HAVE_UNICODE)\r
+ else if (bytes == (Py_ssize_t) (size * sizeof(Py_UNICODE)))\r
+ charsize = sizeof(Py_UNICODE);\r
+#endif\r
+ else {\r
+ PyErr_SetString(PyExc_TypeError, "buffer size mismatch");\r
+ return NULL;\r
+ }\r
+\r
+#if defined(HAVE_UNICODE)\r
+ }\r
+#endif\r
+\r
+ *p_length = size;\r
+ *p_charsize = charsize;\r
+\r
+ return ptr;\r
+}\r
+\r
+LOCAL(PyObject*)\r
+state_init(SRE_STATE* state, PatternObject* pattern, PyObject* string,\r
+ Py_ssize_t start, Py_ssize_t end)\r
+{\r
+ /* prepare state object */\r
+\r
+ Py_ssize_t length;\r
+ int charsize;\r
+ void* ptr;\r
+\r
+ memset(state, 0, sizeof(SRE_STATE));\r
+\r
+ state->lastmark = -1;\r
+ state->lastindex = -1;\r
+\r
+ ptr = getstring(string, &length, &charsize);\r
+ if (!ptr)\r
+ return NULL;\r
+\r
+ /* adjust boundaries */\r
+ if (start < 0)\r
+ start = 0;\r
+ else if (start > length)\r
+ start = length;\r
+\r
+ if (end < 0)\r
+ end = 0;\r
+ else if (end > length)\r
+ end = length;\r
+\r
+ state->charsize = charsize;\r
+\r
+ state->beginning = ptr;\r
+\r
+ state->start = (void*) ((char*) ptr + start * state->charsize);\r
+ state->end = (void*) ((char*) ptr + end * state->charsize);\r
+\r
+ Py_INCREF(string);\r
+ state->string = string;\r
+ state->pos = start;\r
+ state->endpos = end;\r
+\r
+ if (pattern->flags & SRE_FLAG_LOCALE)\r
+ state->lower = sre_lower_locale;\r
+ else if (pattern->flags & SRE_FLAG_UNICODE)\r
+#if defined(HAVE_UNICODE)\r
+ state->lower = sre_lower_unicode;\r
+#else\r
+ state->lower = sre_lower_locale;\r
+#endif\r
+ else\r
+ state->lower = sre_lower;\r
+\r
+ return string;\r
+}\r
+\r
+LOCAL(void)\r
+state_fini(SRE_STATE* state)\r
+{\r
+ Py_XDECREF(state->string);\r
+ data_stack_dealloc(state);\r
+}\r
+\r
+/* calculate offset from start of string */\r
+#define STATE_OFFSET(state, member)\\r
+ (((char*)(member) - (char*)(state)->beginning) / (state)->charsize)\r
+\r
+LOCAL(PyObject*)\r
+state_getslice(SRE_STATE* state, Py_ssize_t index, PyObject* string, int empty)\r
+{\r
+ Py_ssize_t i, j;\r
+\r
+ index = (index - 1) * 2;\r
+\r
+ if (string == Py_None || index >= state->lastmark || !state->mark[index] || !state->mark[index+1]) {\r
+ if (empty)\r
+ /* want empty string */\r
+ i = j = 0;\r
+ else {\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+ }\r
+ } else {\r
+ i = STATE_OFFSET(state, state->mark[index]);\r
+ j = STATE_OFFSET(state, state->mark[index+1]);\r
+ }\r
+\r
+ return PySequence_GetSlice(string, i, j);\r
+}\r
+\r
+static void\r
+pattern_error(int status)\r
+{\r
+ switch (status) {\r
+ case SRE_ERROR_RECURSION_LIMIT:\r
+ PyErr_SetString(\r
+ PyExc_RuntimeError,\r
+ "maximum recursion limit exceeded"\r
+ );\r
+ break;\r
+ case SRE_ERROR_MEMORY:\r
+ PyErr_NoMemory();\r
+ break;\r
+ case SRE_ERROR_INTERRUPTED:\r
+ /* An exception has already been raised, so let it fly */\r
+ break;\r
+ default:\r
+ /* other error codes indicate compiler/engine bugs */\r
+ PyErr_SetString(\r
+ PyExc_RuntimeError,\r
+ "internal error in regular expression engine"\r
+ );\r
+ }\r
+}\r
+\r
+static void\r
+pattern_dealloc(PatternObject* self)\r
+{\r
+ if (self->weakreflist != NULL)\r
+ PyObject_ClearWeakRefs((PyObject *) self);\r
+ Py_XDECREF(self->pattern);\r
+ Py_XDECREF(self->groupindex);\r
+ Py_XDECREF(self->indexgroup);\r
+ PyObject_DEL(self);\r
+}\r
+\r
+static int\r
+check_args_size(const char *name, PyObject* args, PyObject* kw, int n)\r
+{\r
+ Py_ssize_t m = PyTuple_GET_SIZE(args) + (kw ? PyDict_Size(kw) : 0);\r
+ if (m <= n)\r
+ return 1;\r
+ PyErr_Format(PyExc_TypeError,\r
+ "%s() takes at most %d positional arguments (%zd given)",\r
+ name, n, m);\r
+ return 0;\r
+}\r
+\r
+static PyObject*\r
+fix_string_param(PyObject *string, PyObject *string2, const char *oldname)\r
+{\r
+ if (string2 != NULL) {\r
+ char buf[100];\r
+ if (string != NULL) {\r
+ PyErr_Format(PyExc_TypeError,\r
+ "Argument given by name ('%s') and position (1)",\r
+ oldname);\r
+ return NULL;\r
+ }\r
+ sprintf(buf, "The '%s' keyword parameter name is deprecated. "\r
+ "Use 'string' instead.", oldname);\r
+ if (PyErr_Warn(PyExc_DeprecationWarning, buf) < 0)\r
+ return NULL;\r
+ return string2;\r
+ }\r
+ if (string == NULL) {\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "Required argument 'string' (pos 1) not found");\r
+ return NULL;\r
+ }\r
+ return string;\r
+}\r
+\r
+static PyObject*\r
+pattern_match(PatternObject* self, PyObject* args, PyObject* kw)\r
+{\r
+ SRE_STATE state;\r
+ int status;\r
+\r
+ PyObject *string = NULL, *string2 = NULL;\r
+ Py_ssize_t start = 0;\r
+ Py_ssize_t end = PY_SSIZE_T_MAX;\r
+ static char* kwlist[] = { "string", "pos", "endpos", "pattern", NULL };\r
+ if (!check_args_size("match", args, kw, 3))\r
+ return NULL;\r
+\r
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "|OnnO:match", kwlist,\r
+ &string, &start, &end, &string2))\r
+ return NULL;\r
+\r
+ string = fix_string_param(string, string2, "pattern");\r
+ if (!string)\r
+ return NULL;\r
+\r
+ string = state_init(&state, self, string, start, end);\r
+ if (!string)\r
+ return NULL;\r
+\r
+ state.ptr = state.start;\r
+\r
+ TRACE(("|%p|%p|MATCH\n", PatternObject_GetCode(self), state.ptr));\r
+\r
+ if (state.charsize == 1) {\r
+ status = sre_match(&state, PatternObject_GetCode(self));\r
+ } else {\r
+#if defined(HAVE_UNICODE)\r
+ status = sre_umatch(&state, PatternObject_GetCode(self));\r
+#endif\r
+ }\r
+\r
+ TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr));\r
+ if (PyErr_Occurred())\r
+ return NULL;\r
+\r
+ state_fini(&state);\r
+\r
+ return pattern_new_match(self, &state, status);\r
+}\r
+\r
+static PyObject*\r
+pattern_search(PatternObject* self, PyObject* args, PyObject* kw)\r
+{\r
+ SRE_STATE state;\r
+ int status;\r
+\r
+ PyObject *string = NULL, *string2 = NULL;\r
+ Py_ssize_t start = 0;\r
+ Py_ssize_t end = PY_SSIZE_T_MAX;\r
+ static char* kwlist[] = { "string", "pos", "endpos", "pattern", NULL };\r
+ if (!check_args_size("search", args, kw, 3))\r
+ return NULL;\r
+\r
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "|OnnO:search", kwlist,\r
+ &string, &start, &end, &string2))\r
+ return NULL;\r
+\r
+ string = fix_string_param(string, string2, "pattern");\r
+ if (!string)\r
+ return NULL;\r
+\r
+ string = state_init(&state, self, string, start, end);\r
+ if (!string)\r
+ return NULL;\r
+\r
+ TRACE(("|%p|%p|SEARCH\n", PatternObject_GetCode(self), state.ptr));\r
+\r
+ if (state.charsize == 1) {\r
+ status = sre_search(&state, PatternObject_GetCode(self));\r
+ } else {\r
+#if defined(HAVE_UNICODE)\r
+ status = sre_usearch(&state, PatternObject_GetCode(self));\r
+#endif\r
+ }\r
+\r
+ TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr));\r
+\r
+ state_fini(&state);\r
+\r
+ if (PyErr_Occurred())\r
+ return NULL;\r
+\r
+ return pattern_new_match(self, &state, status);\r
+}\r
+\r
+static PyObject*\r
+call(char* module, char* function, PyObject* args)\r
+{\r
+ PyObject* name;\r
+ PyObject* mod;\r
+ PyObject* func;\r
+ PyObject* result;\r
+\r
+ if (!args)\r
+ return NULL;\r
+ name = PyString_FromString(module);\r
+ if (!name)\r
+ return NULL;\r
+ mod = PyImport_Import(name);\r
+ Py_DECREF(name);\r
+ if (!mod)\r
+ return NULL;\r
+ func = PyObject_GetAttrString(mod, function);\r
+ Py_DECREF(mod);\r
+ if (!func)\r
+ return NULL;\r
+ result = PyObject_CallObject(func, args);\r
+ Py_DECREF(func);\r
+ Py_DECREF(args);\r
+ return result;\r
+}\r
+\r
+#ifdef USE_BUILTIN_COPY\r
+static int\r
+deepcopy(PyObject** object, PyObject* memo)\r
+{\r
+ PyObject* copy;\r
+\r
+ copy = call(\r
+ "copy", "deepcopy",\r
+ PyTuple_Pack(2, *object, memo)\r
+ );\r
+ if (!copy)\r
+ return 0;\r
+\r
+ Py_DECREF(*object);\r
+ *object = copy;\r
+\r
+ return 1; /* success */\r
+}\r
+#endif\r
+\r
+static PyObject*\r
+join_list(PyObject* list, PyObject* string)\r
+{\r
+ /* join list elements */\r
+\r
+ PyObject* joiner;\r
+#if PY_VERSION_HEX >= 0x01060000\r
+ PyObject* function;\r
+ PyObject* args;\r
+#endif\r
+ PyObject* result;\r
+\r
+ joiner = PySequence_GetSlice(string, 0, 0);\r
+ if (!joiner)\r
+ return NULL;\r
+\r
+ if (PyList_GET_SIZE(list) == 0) {\r
+ Py_DECREF(list);\r
+ return joiner;\r
+ }\r
+\r
+#if PY_VERSION_HEX >= 0x01060000\r
+ function = PyObject_GetAttrString(joiner, "join");\r
+ if (!function) {\r
+ Py_DECREF(joiner);\r
+ return NULL;\r
+ }\r
+ args = PyTuple_New(1);\r
+ if (!args) {\r
+ Py_DECREF(function);\r
+ Py_DECREF(joiner);\r
+ return NULL;\r
+ }\r
+ PyTuple_SET_ITEM(args, 0, list);\r
+ result = PyObject_CallObject(function, args);\r
+ Py_DECREF(args); /* also removes list */\r
+ Py_DECREF(function);\r
+#else\r
+ result = call(\r
+ "string", "join",\r
+ PyTuple_Pack(2, list, joiner)\r
+ );\r
+#endif\r
+ Py_DECREF(joiner);\r
+\r
+ return result;\r
+}\r
+\r
+static PyObject*\r
+pattern_findall(PatternObject* self, PyObject* args, PyObject* kw)\r
+{\r
+ SRE_STATE state;\r
+ PyObject* list;\r
+ int status;\r
+ Py_ssize_t i, b, e;\r
+\r
+ PyObject *string = NULL, *string2 = NULL;\r
+ Py_ssize_t start = 0;\r
+ Py_ssize_t end = PY_SSIZE_T_MAX;\r
+ static char* kwlist[] = { "string", "pos", "endpos", "source", NULL };\r
+ if (!check_args_size("findall", args, kw, 3))\r
+ return NULL;\r
+\r
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "|OnnO:findall", kwlist,\r
+ &string, &start, &end, &string2))\r
+ return NULL;\r
+\r
+ string = fix_string_param(string, string2, "source");\r
+ if (!string)\r
+ return NULL;\r
+\r
+ string = state_init(&state, self, string, start, end);\r
+ if (!string)\r
+ return NULL;\r
+\r
+ list = PyList_New(0);\r
+ if (!list) {\r
+ state_fini(&state);\r
+ return NULL;\r
+ }\r
+\r
+ while (state.start <= state.end) {\r
+\r
+ PyObject* item;\r
+\r
+ state_reset(&state);\r
+\r
+ state.ptr = state.start;\r
+\r
+ if (state.charsize == 1) {\r
+ status = sre_search(&state, PatternObject_GetCode(self));\r
+ } else {\r
+#if defined(HAVE_UNICODE)\r
+ status = sre_usearch(&state, PatternObject_GetCode(self));\r
+#endif\r
+ }\r
+\r
+ if (PyErr_Occurred())\r
+ goto error;\r
+\r
+ if (status <= 0) {\r
+ if (status == 0)\r
+ break;\r
+ pattern_error(status);\r
+ goto error;\r
+ }\r
+\r
+ /* don't bother to build a match object */\r
+ switch (self->groups) {\r
+ case 0:\r
+ b = STATE_OFFSET(&state, state.start);\r
+ e = STATE_OFFSET(&state, state.ptr);\r
+ item = PySequence_GetSlice(string, b, e);\r
+ if (!item)\r
+ goto error;\r
+ break;\r
+ case 1:\r
+ item = state_getslice(&state, 1, string, 1);\r
+ if (!item)\r
+ goto error;\r
+ break;\r
+ default:\r
+ item = PyTuple_New(self->groups);\r
+ if (!item)\r
+ goto error;\r
+ for (i = 0; i < self->groups; i++) {\r
+ PyObject* o = state_getslice(&state, i+1, string, 1);\r
+ if (!o) {\r
+ Py_DECREF(item);\r
+ goto error;\r
+ }\r
+ PyTuple_SET_ITEM(item, i, o);\r
+ }\r
+ break;\r
+ }\r
+\r
+ status = PyList_Append(list, item);\r
+ Py_DECREF(item);\r
+ if (status < 0)\r
+ goto error;\r
+\r
+ if (state.ptr == state.start)\r
+ state.start = (void*) ((char*) state.ptr + state.charsize);\r
+ else\r
+ state.start = state.ptr;\r
+\r
+ }\r
+\r
+ state_fini(&state);\r
+ return list;\r
+\r
+error:\r
+ Py_DECREF(list);\r
+ state_fini(&state);\r
+ return NULL;\r
+\r
+}\r
+\r
+#if PY_VERSION_HEX >= 0x02020000\r
+static PyObject*\r
+pattern_finditer(PatternObject* pattern, PyObject* args)\r
+{\r
+ PyObject* scanner;\r
+ PyObject* search;\r
+ PyObject* iterator;\r
+\r
+ scanner = pattern_scanner(pattern, args);\r
+ if (!scanner)\r
+ return NULL;\r
+\r
+ search = PyObject_GetAttrString(scanner, "search");\r
+ Py_DECREF(scanner);\r
+ if (!search)\r
+ return NULL;\r
+\r
+ iterator = PyCallIter_New(search, Py_None);\r
+ Py_DECREF(search);\r
+\r
+ return iterator;\r
+}\r
+#endif\r
+\r
+static PyObject*\r
+pattern_split(PatternObject* self, PyObject* args, PyObject* kw)\r
+{\r
+ SRE_STATE state;\r
+ PyObject* list;\r
+ PyObject* item;\r
+ int status;\r
+ Py_ssize_t n;\r
+ Py_ssize_t i;\r
+ void* last;\r
+\r
+ PyObject *string = NULL, *string2 = NULL;\r
+ Py_ssize_t maxsplit = 0;\r
+ static char* kwlist[] = { "string", "maxsplit", "source", NULL };\r
+ if (!check_args_size("split", args, kw, 2))\r
+ return NULL;\r
+\r
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "|OnO:split", kwlist,\r
+ &string, &maxsplit, &string2))\r
+ return NULL;\r
+\r
+ string = fix_string_param(string, string2, "source");\r
+ if (!string)\r
+ return NULL;\r
+\r
+ string = state_init(&state, self, string, 0, PY_SSIZE_T_MAX);\r
+ if (!string)\r
+ return NULL;\r
+\r
+ list = PyList_New(0);\r
+ if (!list) {\r
+ state_fini(&state);\r
+ return NULL;\r
+ }\r
+\r
+ n = 0;\r
+ last = state.start;\r
+\r
+ while (!maxsplit || n < maxsplit) {\r
+\r
+ state_reset(&state);\r
+\r
+ state.ptr = state.start;\r
+\r
+ if (state.charsize == 1) {\r
+ status = sre_search(&state, PatternObject_GetCode(self));\r
+ } else {\r
+#if defined(HAVE_UNICODE)\r
+ status = sre_usearch(&state, PatternObject_GetCode(self));\r
+#endif\r
+ }\r
+\r
+ if (PyErr_Occurred())\r
+ goto error;\r
+\r
+ if (status <= 0) {\r
+ if (status == 0)\r
+ break;\r
+ pattern_error(status);\r
+ goto error;\r
+ }\r
+\r
+ if (state.start == state.ptr) {\r
+ if (last == state.end)\r
+ break;\r
+ /* skip one character */\r
+ state.start = (void*) ((char*) state.ptr + state.charsize);\r
+ continue;\r
+ }\r
+\r
+ /* get segment before this match */\r
+ item = PySequence_GetSlice(\r
+ string, STATE_OFFSET(&state, last),\r
+ STATE_OFFSET(&state, state.start)\r
+ );\r
+ if (!item)\r
+ goto error;\r
+ status = PyList_Append(list, item);\r
+ Py_DECREF(item);\r
+ if (status < 0)\r
+ goto error;\r
+\r
+ /* add groups (if any) */\r
+ for (i = 0; i < self->groups; i++) {\r
+ item = state_getslice(&state, i+1, string, 0);\r
+ if (!item)\r
+ goto error;\r
+ status = PyList_Append(list, item);\r
+ Py_DECREF(item);\r
+ if (status < 0)\r
+ goto error;\r
+ }\r
+\r
+ n = n + 1;\r
+\r
+ last = state.start = state.ptr;\r
+\r
+ }\r
+\r
+ /* get segment following last match (even if empty) */\r
+ item = PySequence_GetSlice(\r
+ string, STATE_OFFSET(&state, last), state.endpos\r
+ );\r
+ if (!item)\r
+ goto error;\r
+ status = PyList_Append(list, item);\r
+ Py_DECREF(item);\r
+ if (status < 0)\r
+ goto error;\r
+\r
+ state_fini(&state);\r
+ return list;\r
+\r
+error:\r
+ Py_DECREF(list);\r
+ state_fini(&state);\r
+ return NULL;\r
+\r
+}\r
+\r
+static PyObject*\r
+pattern_subx(PatternObject* self, PyObject* ptemplate, PyObject* string,\r
+ Py_ssize_t count, Py_ssize_t subn)\r
+{\r
+ SRE_STATE state;\r
+ PyObject* list;\r
+ PyObject* item;\r
+ PyObject* filter;\r
+ PyObject* args;\r
+ PyObject* match;\r
+ void* ptr;\r
+ int status;\r
+ Py_ssize_t n;\r
+ Py_ssize_t i, b, e;\r
+ int bint;\r
+ int filter_is_callable;\r
+\r
+ if (PyCallable_Check(ptemplate)) {\r
+ /* sub/subn takes either a function or a template */\r
+ filter = ptemplate;\r
+ Py_INCREF(filter);\r
+ filter_is_callable = 1;\r
+ } else {\r
+ /* if not callable, check if it's a literal string */\r
+ int literal;\r
+ ptr = getstring(ptemplate, &n, &bint);\r
+ b = bint;\r
+ if (ptr) {\r
+ if (b == 1) {\r
+ literal = sre_literal_template((unsigned char *)ptr, n);\r
+ } else {\r
+#if defined(HAVE_UNICODE)\r
+ literal = sre_uliteral_template((Py_UNICODE *)ptr, n);\r
+#endif\r
+ }\r
+ } else {\r
+ PyErr_Clear();\r
+ literal = 0;\r
+ }\r
+ if (literal) {\r
+ filter = ptemplate;\r
+ Py_INCREF(filter);\r
+ filter_is_callable = 0;\r
+ } else {\r
+ /* not a literal; hand it over to the template compiler */\r
+ filter = call(\r
+ SRE_PY_MODULE, "_subx",\r
+ PyTuple_Pack(2, self, ptemplate)\r
+ );\r
+ if (!filter)\r
+ return NULL;\r
+ filter_is_callable = PyCallable_Check(filter);\r
+ }\r
+ }\r
+\r
+ string = state_init(&state, self, string, 0, PY_SSIZE_T_MAX);\r
+ if (!string) {\r
+ Py_DECREF(filter);\r
+ return NULL;\r
+ }\r
+\r
+ list = PyList_New(0);\r
+ if (!list) {\r
+ Py_DECREF(filter);\r
+ state_fini(&state);\r
+ return NULL;\r
+ }\r
+\r
+ n = i = 0;\r
+\r
+ while (!count || n < count) {\r
+\r
+ state_reset(&state);\r
+\r
+ state.ptr = state.start;\r
+\r
+ if (state.charsize == 1) {\r
+ status = sre_search(&state, PatternObject_GetCode(self));\r
+ } else {\r
+#if defined(HAVE_UNICODE)\r
+ status = sre_usearch(&state, PatternObject_GetCode(self));\r
+#endif\r
+ }\r
+\r
+ if (PyErr_Occurred())\r
+ goto error;\r
+\r
+ if (status <= 0) {\r
+ if (status == 0)\r
+ break;\r
+ pattern_error(status);\r
+ goto error;\r
+ }\r
+\r
+ b = STATE_OFFSET(&state, state.start);\r
+ e = STATE_OFFSET(&state, state.ptr);\r
+\r
+ if (i < b) {\r
+ /* get segment before this match */\r
+ item = PySequence_GetSlice(string, i, b);\r
+ if (!item)\r
+ goto error;\r
+ status = PyList_Append(list, item);\r
+ Py_DECREF(item);\r
+ if (status < 0)\r
+ goto error;\r
+\r
+ } else if (i == b && i == e && n > 0)\r
+ /* ignore empty match on latest position */\r
+ goto next;\r
+\r
+ if (filter_is_callable) {\r
+ /* pass match object through filter */\r
+ match = pattern_new_match(self, &state, 1);\r
+ if (!match)\r
+ goto error;\r
+ args = PyTuple_Pack(1, match);\r
+ if (!args) {\r
+ Py_DECREF(match);\r
+ goto error;\r
+ }\r
+ item = PyObject_CallObject(filter, args);\r
+ Py_DECREF(args);\r
+ Py_DECREF(match);\r
+ if (!item)\r
+ goto error;\r
+ } else {\r
+ /* filter is literal string */\r
+ item = filter;\r
+ Py_INCREF(item);\r
+ }\r
+\r
+ /* add to list */\r
+ if (item != Py_None) {\r
+ status = PyList_Append(list, item);\r
+ Py_DECREF(item);\r
+ if (status < 0)\r
+ goto error;\r
+ }\r
+\r
+ i = e;\r
+ n = n + 1;\r
+\r
+next:\r
+ /* move on */\r
+ if (state.ptr == state.start)\r
+ state.start = (void*) ((char*) state.ptr + state.charsize);\r
+ else\r
+ state.start = state.ptr;\r
+\r
+ }\r
+\r
+ /* get segment following last match */\r
+ if (i < state.endpos) {\r
+ item = PySequence_GetSlice(string, i, state.endpos);\r
+ if (!item)\r
+ goto error;\r
+ status = PyList_Append(list, item);\r
+ Py_DECREF(item);\r
+ if (status < 0)\r
+ goto error;\r
+ }\r
+\r
+ state_fini(&state);\r
+\r
+ Py_DECREF(filter);\r
+\r
+ /* convert list to single string (also removes list) */\r
+ item = join_list(list, string);\r
+\r
+ if (!item)\r
+ return NULL;\r
+\r
+ if (subn)\r
+ return Py_BuildValue("Nn", item, n);\r
+\r
+ return item;\r
+\r
+error:\r
+ Py_DECREF(list);\r
+ state_fini(&state);\r
+ Py_DECREF(filter);\r
+ return NULL;\r
+\r
+}\r
+\r
+static PyObject*\r
+pattern_sub(PatternObject* self, PyObject* args, PyObject* kw)\r
+{\r
+ PyObject* ptemplate;\r
+ PyObject* string;\r
+ Py_ssize_t count = 0;\r
+ static char* kwlist[] = { "repl", "string", "count", NULL };\r
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|n:sub", kwlist,\r
+ &ptemplate, &string, &count))\r
+ return NULL;\r
+\r
+ return pattern_subx(self, ptemplate, string, count, 0);\r
+}\r
+\r
+static PyObject*\r
+pattern_subn(PatternObject* self, PyObject* args, PyObject* kw)\r
+{\r
+ PyObject* ptemplate;\r
+ PyObject* string;\r
+ Py_ssize_t count = 0;\r
+ static char* kwlist[] = { "repl", "string", "count", NULL };\r
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|n:subn", kwlist,\r
+ &ptemplate, &string, &count))\r
+ return NULL;\r
+\r
+ return pattern_subx(self, ptemplate, string, count, 1);\r
+}\r
+\r
+static PyObject*\r
+pattern_copy(PatternObject* self, PyObject *unused)\r
+{\r
+#ifdef USE_BUILTIN_COPY\r
+ PatternObject* copy;\r
+ int offset;\r
+\r
+ copy = PyObject_NEW_VAR(PatternObject, &Pattern_Type, self->codesize);\r
+ if (!copy)\r
+ return NULL;\r
+\r
+ offset = offsetof(PatternObject, groups);\r
+\r
+ Py_XINCREF(self->groupindex);\r
+ Py_XINCREF(self->indexgroup);\r
+ Py_XINCREF(self->pattern);\r
+\r
+ memcpy((char*) copy + offset, (char*) self + offset,\r
+ sizeof(PatternObject) + self->codesize * sizeof(SRE_CODE) - offset);\r
+ copy->weakreflist = NULL;\r
+\r
+ return (PyObject*) copy;\r
+#else\r
+ PyErr_SetString(PyExc_TypeError, "cannot copy this pattern object");\r
+ return NULL;\r
+#endif\r
+}\r
+\r
+static PyObject*\r
+pattern_deepcopy(PatternObject* self, PyObject* memo)\r
+{\r
+#ifdef USE_BUILTIN_COPY\r
+ PatternObject* copy;\r
+\r
+ copy = (PatternObject*) pattern_copy(self);\r
+ if (!copy)\r
+ return NULL;\r
+\r
+ if (!deepcopy(©->groupindex, memo) ||\r
+ !deepcopy(©->indexgroup, memo) ||\r
+ !deepcopy(©->pattern, memo)) {\r
+ Py_DECREF(copy);\r
+ return NULL;\r
+ }\r
+\r
+#else\r
+ PyErr_SetString(PyExc_TypeError, "cannot deepcopy this pattern object");\r
+ return NULL;\r
+#endif\r
+}\r
+\r
+PyDoc_STRVAR(pattern_match_doc,\r
+"match(string[, pos[, endpos]]) --> match object or None.\n\\r
+ Matches zero or more characters at the beginning of the string");\r
+\r
+PyDoc_STRVAR(pattern_search_doc,\r
+"search(string[, pos[, endpos]]) --> match object or None.\n\\r
+ Scan through string looking for a match, and return a corresponding\n\\r
+ match object instance. Return None if no position in the string matches.");\r
+\r
+PyDoc_STRVAR(pattern_split_doc,\r
+"split(string[, maxsplit = 0]) --> list.\n\\r
+ Split string by the occurrences of pattern.");\r
+\r
+PyDoc_STRVAR(pattern_findall_doc,\r
+"findall(string[, pos[, endpos]]) --> list.\n\\r
+ Return a list of all non-overlapping matches of pattern in string.");\r
+\r
+PyDoc_STRVAR(pattern_finditer_doc,\r
+"finditer(string[, pos[, endpos]]) --> iterator.\n\\r
+ Return an iterator over all non-overlapping matches for the \n\\r
+ RE pattern in string. For each match, the iterator returns a\n\\r
+ match object.");\r
+\r
+PyDoc_STRVAR(pattern_sub_doc,\r
+"sub(repl, string[, count = 0]) --> newstring\n\\r
+ Return the string obtained by replacing the leftmost non-overlapping\n\\r
+ occurrences of pattern in string by the replacement repl.");\r
+\r
+PyDoc_STRVAR(pattern_subn_doc,\r
+"subn(repl, string[, count = 0]) --> (newstring, number of subs)\n\\r
+ Return the tuple (new_string, number_of_subs_made) found by replacing\n\\r
+ the leftmost non-overlapping occurrences of pattern with the\n\\r
+ replacement repl.");\r
+\r
+PyDoc_STRVAR(pattern_doc, "Compiled regular expression objects");\r
+\r
+static PyMethodDef pattern_methods[] = {\r
+ {"match", (PyCFunction) pattern_match, METH_VARARGS|METH_KEYWORDS,\r
+ pattern_match_doc},\r
+ {"search", (PyCFunction) pattern_search, METH_VARARGS|METH_KEYWORDS,\r
+ pattern_search_doc},\r
+ {"sub", (PyCFunction) pattern_sub, METH_VARARGS|METH_KEYWORDS,\r
+ pattern_sub_doc},\r
+ {"subn", (PyCFunction) pattern_subn, METH_VARARGS|METH_KEYWORDS,\r
+ pattern_subn_doc},\r
+ {"split", (PyCFunction) pattern_split, METH_VARARGS|METH_KEYWORDS,\r
+ pattern_split_doc},\r
+ {"findall", (PyCFunction) pattern_findall, METH_VARARGS|METH_KEYWORDS,\r
+ pattern_findall_doc},\r
+#if PY_VERSION_HEX >= 0x02020000\r
+ {"finditer", (PyCFunction) pattern_finditer, METH_VARARGS,\r
+ pattern_finditer_doc},\r
+#endif\r
+ {"scanner", (PyCFunction) pattern_scanner, METH_VARARGS},\r
+ {"__copy__", (PyCFunction) pattern_copy, METH_NOARGS},\r
+ {"__deepcopy__", (PyCFunction) pattern_deepcopy, METH_O},\r
+ {NULL, NULL}\r
+};\r
+\r
+#define PAT_OFF(x) offsetof(PatternObject, x)\r
+static PyMemberDef pattern_members[] = {\r
+ {"pattern", T_OBJECT, PAT_OFF(pattern), READONLY},\r
+ {"flags", T_INT, PAT_OFF(flags), READONLY},\r
+ {"groups", T_PYSSIZET, PAT_OFF(groups), READONLY},\r
+ {"groupindex", T_OBJECT, PAT_OFF(groupindex), READONLY},\r
+ {NULL} /* Sentinel */\r
+};\r
+\r
+statichere PyTypeObject Pattern_Type = {\r
+ PyObject_HEAD_INIT(NULL)\r
+ 0, "_" SRE_MODULE ".SRE_Pattern",\r
+ sizeof(PatternObject), sizeof(SRE_CODE),\r
+ (destructor)pattern_dealloc, /*tp_dealloc*/\r
+ 0, /* tp_print */\r
+ 0, /* tp_getattrn */\r
+ 0, /* tp_setattr */\r
+ 0, /* tp_compare */\r
+ 0, /* tp_repr */\r
+ 0, /* tp_as_number */\r
+ 0, /* tp_as_sequence */\r
+ 0, /* tp_as_mapping */\r
+ 0, /* tp_hash */\r
+ 0, /* tp_call */\r
+ 0, /* tp_str */\r
+ 0, /* tp_getattro */\r
+ 0, /* tp_setattro */\r
+ 0, /* tp_as_buffer */\r
+ Py_TPFLAGS_DEFAULT, /* tp_flags */\r
+ pattern_doc, /* tp_doc */\r
+ 0, /* tp_traverse */\r
+ 0, /* tp_clear */\r
+ 0, /* tp_richcompare */\r
+ offsetof(PatternObject, weakreflist), /* tp_weaklistoffset */\r
+ 0, /* tp_iter */\r
+ 0, /* tp_iternext */\r
+ pattern_methods, /* tp_methods */\r
+ pattern_members, /* tp_members */\r
+};\r
+\r
+static int _validate(PatternObject *self); /* Forward */\r
+\r
+static PyObject *\r
+_compile(PyObject* self_, PyObject* args)\r
+{\r
+ /* "compile" pattern descriptor to pattern object */\r
+\r
+ PatternObject* self;\r
+ Py_ssize_t i, n;\r
+\r
+ PyObject* pattern;\r
+ int flags = 0;\r
+ PyObject* code;\r
+ Py_ssize_t groups = 0;\r
+ PyObject* groupindex = NULL;\r
+ PyObject* indexgroup = NULL;\r
+ if (!PyArg_ParseTuple(args, "OiO!|nOO", &pattern, &flags,\r
+ &PyList_Type, &code, &groups,\r
+ &groupindex, &indexgroup))\r
+ return NULL;\r
+\r
+ n = PyList_GET_SIZE(code);\r
+ /* coverity[ampersand_in_size] */\r
+ self = PyObject_NEW_VAR(PatternObject, &Pattern_Type, n);\r
+ if (!self)\r
+ return NULL;\r
+ self->weakreflist = NULL;\r
+ self->pattern = NULL;\r
+ self->groupindex = NULL;\r
+ self->indexgroup = NULL;\r
+\r
+ self->codesize = n;\r
+\r
+ for (i = 0; i < n; i++) {\r
+ PyObject *o = PyList_GET_ITEM(code, i);\r
+ unsigned long value = PyInt_Check(o) ? (unsigned long)PyInt_AsLong(o)\r
+ : PyLong_AsUnsignedLong(o);\r
+ if (value == (unsigned long)-1 && PyErr_Occurred()) {\r
+ if (PyErr_ExceptionMatches(PyExc_OverflowError)) {\r
+ PyErr_SetString(PyExc_OverflowError,\r
+ "regular expression code size limit exceeded");\r
+ }\r
+ break;\r
+ }\r
+ self->code[i] = (SRE_CODE) value;\r
+ if ((unsigned long) self->code[i] != value) {\r
+ PyErr_SetString(PyExc_OverflowError,\r
+ "regular expression code size limit exceeded");\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (PyErr_Occurred()) {\r
+ Py_DECREF(self);\r
+ return NULL;\r
+ }\r
+\r
+ Py_INCREF(pattern);\r
+ self->pattern = pattern;\r
+\r
+ self->flags = flags;\r
+\r
+ self->groups = groups;\r
+\r
+ Py_XINCREF(groupindex);\r
+ self->groupindex = groupindex;\r
+\r
+ Py_XINCREF(indexgroup);\r
+ self->indexgroup = indexgroup;\r
+\r
+ self->weakreflist = NULL;\r
+\r
+ if (!_validate(self)) {\r
+ Py_DECREF(self);\r
+ return NULL;\r
+ }\r
+\r
+ return (PyObject*) self;\r
+}\r
+\r
+/* -------------------------------------------------------------------- */\r
+/* Code validation */\r
+\r
+/* To learn more about this code, have a look at the _compile() function in\r
+ Lib/sre_compile.py. The validation functions below checks the code array\r
+ for conformance with the code patterns generated there.\r
+\r
+ The nice thing about the generated code is that it is position-independent:\r
+ all jumps are relative jumps forward. Also, jumps don't cross each other:\r
+ the target of a later jump is always earlier than the target of an earlier\r
+ jump. IOW, this is okay:\r
+\r
+ J---------J-------T--------T\r
+ \ \_____/ /\r
+ \______________________/\r
+\r
+ but this is not:\r
+\r
+ J---------J-------T--------T\r
+ \_________\_____/ /\r
+ \____________/\r
+\r
+ It also helps that SRE_CODE is always an unsigned type.\r
+*/\r
+\r
+/* Defining this one enables tracing of the validator */\r
+#undef VVERBOSE\r
+\r
+/* Trace macro for the validator */\r
+#if defined(VVERBOSE)\r
+#define VTRACE(v) printf v\r
+#else\r
+#define VTRACE(v) do {} while(0) /* do nothing */\r
+#endif\r
+\r
+/* Report failure */\r
+#define FAIL do { VTRACE(("FAIL: %d\n", __LINE__)); return 0; } while (0)\r
+\r
+/* Extract opcode, argument, or skip count from code array */\r
+#define GET_OP \\r
+ do { \\r
+ VTRACE(("%p: ", code)); \\r
+ if (code >= end) FAIL; \\r
+ op = *code++; \\r
+ VTRACE(("%lu (op)\n", (unsigned long)op)); \\r
+ } while (0)\r
+#define GET_ARG \\r
+ do { \\r
+ VTRACE(("%p= ", code)); \\r
+ if (code >= end) FAIL; \\r
+ arg = *code++; \\r
+ VTRACE(("%lu (arg)\n", (unsigned long)arg)); \\r
+ } while (0)\r
+#define GET_SKIP_ADJ(adj) \\r
+ do { \\r
+ VTRACE(("%p= ", code)); \\r
+ if (code >= end) FAIL; \\r
+ skip = *code; \\r
+ VTRACE(("%lu (skip to %p)\n", \\r
+ (unsigned long)skip, code+skip)); \\r
+ if (skip-adj > end-code) \\r
+ FAIL; \\r
+ code++; \\r
+ } while (0)\r
+#define GET_SKIP GET_SKIP_ADJ(0)\r
+\r
+static int\r
+_validate_charset(SRE_CODE *code, SRE_CODE *end)\r
+{\r
+ /* Some variables are manipulated by the macros above */\r
+ SRE_CODE op;\r
+ SRE_CODE arg;\r
+ SRE_CODE offset;\r
+ int i;\r
+\r
+ while (code < end) {\r
+ GET_OP;\r
+ switch (op) {\r
+\r
+ case SRE_OP_NEGATE:\r
+ break;\r
+\r
+ case SRE_OP_LITERAL:\r
+ GET_ARG;\r
+ break;\r
+\r
+ case SRE_OP_RANGE:\r
+ GET_ARG;\r
+ GET_ARG;\r
+ break;\r
+\r
+ case SRE_OP_CHARSET:\r
+ offset = 32/sizeof(SRE_CODE); /* 32-byte bitmap */\r
+ if (offset > end-code)\r
+ FAIL;\r
+ code += offset;\r
+ break;\r
+\r
+ case SRE_OP_BIGCHARSET:\r
+ GET_ARG; /* Number of blocks */\r
+ offset = 256/sizeof(SRE_CODE); /* 256-byte table */\r
+ if (offset > end-code)\r
+ FAIL;\r
+ /* Make sure that each byte points to a valid block */\r
+ for (i = 0; i < 256; i++) {\r
+ if (((unsigned char *)code)[i] >= arg)\r
+ FAIL;\r
+ }\r
+ code += offset;\r
+ offset = arg * 32/sizeof(SRE_CODE); /* 32-byte bitmap times arg */\r
+ if (offset > end-code)\r
+ FAIL;\r
+ code += offset;\r
+ break;\r
+\r
+ case SRE_OP_CATEGORY:\r
+ GET_ARG;\r
+ switch (arg) {\r
+ case SRE_CATEGORY_DIGIT:\r
+ case SRE_CATEGORY_NOT_DIGIT:\r
+ case SRE_CATEGORY_SPACE:\r
+ case SRE_CATEGORY_NOT_SPACE:\r
+ case SRE_CATEGORY_WORD:\r
+ case SRE_CATEGORY_NOT_WORD:\r
+ case SRE_CATEGORY_LINEBREAK:\r
+ case SRE_CATEGORY_NOT_LINEBREAK:\r
+ case SRE_CATEGORY_LOC_WORD:\r
+ case SRE_CATEGORY_LOC_NOT_WORD:\r
+ case SRE_CATEGORY_UNI_DIGIT:\r
+ case SRE_CATEGORY_UNI_NOT_DIGIT:\r
+ case SRE_CATEGORY_UNI_SPACE:\r
+ case SRE_CATEGORY_UNI_NOT_SPACE:\r
+ case SRE_CATEGORY_UNI_WORD:\r
+ case SRE_CATEGORY_UNI_NOT_WORD:\r
+ case SRE_CATEGORY_UNI_LINEBREAK:\r
+ case SRE_CATEGORY_UNI_NOT_LINEBREAK:\r
+ break;\r
+ default:\r
+ FAIL;\r
+ }\r
+ break;\r
+\r
+ default:\r
+ FAIL;\r
+\r
+ }\r
+ }\r
+\r
+ return 1;\r
+}\r
+\r
+static int\r
+_validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups)\r
+{\r
+ /* Some variables are manipulated by the macros above */\r
+ SRE_CODE op;\r
+ SRE_CODE arg;\r
+ SRE_CODE skip;\r
+\r
+ VTRACE(("code=%p, end=%p\n", code, end));\r
+\r
+ if (code > end)\r
+ FAIL;\r
+\r
+ while (code < end) {\r
+ GET_OP;\r
+ switch (op) {\r
+\r
+ case SRE_OP_MARK:\r
+ /* We don't check whether marks are properly nested; the\r
+ sre_match() code is robust even if they don't, and the worst\r
+ you can get is nonsensical match results. */\r
+ GET_ARG;\r
+ if (arg > 2*groups+1) {\r
+ VTRACE(("arg=%d, groups=%d\n", (int)arg, (int)groups));\r
+ FAIL;\r
+ }\r
+ break;\r
+\r
+ case SRE_OP_LITERAL:\r
+ case SRE_OP_NOT_LITERAL:\r
+ case SRE_OP_LITERAL_IGNORE:\r
+ case SRE_OP_NOT_LITERAL_IGNORE:\r
+ GET_ARG;\r
+ /* The arg is just a character, nothing to check */\r
+ break;\r
+\r
+ case SRE_OP_SUCCESS:\r
+ case SRE_OP_FAILURE:\r
+ /* Nothing to check; these normally end the matching process */\r
+ break;\r
+\r
+ case SRE_OP_AT:\r
+ GET_ARG;\r
+ switch (arg) {\r
+ case SRE_AT_BEGINNING:\r
+ case SRE_AT_BEGINNING_STRING:\r
+ case SRE_AT_BEGINNING_LINE:\r
+ case SRE_AT_END:\r
+ case SRE_AT_END_LINE:\r
+ case SRE_AT_END_STRING:\r
+ case SRE_AT_BOUNDARY:\r
+ case SRE_AT_NON_BOUNDARY:\r
+ case SRE_AT_LOC_BOUNDARY:\r
+ case SRE_AT_LOC_NON_BOUNDARY:\r
+ case SRE_AT_UNI_BOUNDARY:\r
+ case SRE_AT_UNI_NON_BOUNDARY:\r
+ break;\r
+ default:\r
+ FAIL;\r
+ }\r
+ break;\r
+\r
+ case SRE_OP_ANY:\r
+ case SRE_OP_ANY_ALL:\r
+ /* These have no operands */\r
+ break;\r
+\r
+ case SRE_OP_IN:\r
+ case SRE_OP_IN_IGNORE:\r
+ GET_SKIP;\r
+ /* Stop 1 before the end; we check the FAILURE below */\r
+ if (!_validate_charset(code, code+skip-2))\r
+ FAIL;\r
+ if (code[skip-2] != SRE_OP_FAILURE)\r
+ FAIL;\r
+ code += skip-1;\r
+ break;\r
+\r
+ case SRE_OP_INFO:\r
+ {\r
+ /* A minimal info field is\r
+ <INFO> <1=skip> <2=flags> <3=min> <4=max>;\r
+ If SRE_INFO_PREFIX or SRE_INFO_CHARSET is in the flags,\r
+ more follows. */\r
+ SRE_CODE flags, i;\r
+ SRE_CODE *newcode;\r
+ GET_SKIP;\r
+ newcode = code+skip-1;\r
+ GET_ARG; flags = arg;\r
+ GET_ARG; /* min */\r
+ GET_ARG; /* max */\r
+ /* Check that only valid flags are present */\r
+ if ((flags & ~(SRE_INFO_PREFIX |\r
+ SRE_INFO_LITERAL |\r
+ SRE_INFO_CHARSET)) != 0)\r
+ FAIL;\r
+ /* PREFIX and CHARSET are mutually exclusive */\r
+ if ((flags & SRE_INFO_PREFIX) &&\r
+ (flags & SRE_INFO_CHARSET))\r
+ FAIL;\r
+ /* LITERAL implies PREFIX */\r
+ if ((flags & SRE_INFO_LITERAL) &&\r
+ !(flags & SRE_INFO_PREFIX))\r
+ FAIL;\r
+ /* Validate the prefix */\r
+ if (flags & SRE_INFO_PREFIX) {\r
+ SRE_CODE prefix_len;\r
+ GET_ARG; prefix_len = arg;\r
+ GET_ARG; /* prefix skip */\r
+ /* Here comes the prefix string */\r
+ if (prefix_len > newcode-code)\r
+ FAIL;\r
+ code += prefix_len;\r
+ /* And here comes the overlap table */\r
+ if (prefix_len > newcode-code)\r
+ FAIL;\r
+ /* Each overlap value should be < prefix_len */\r
+ for (i = 0; i < prefix_len; i++) {\r
+ if (code[i] >= prefix_len)\r
+ FAIL;\r
+ }\r
+ code += prefix_len;\r
+ }\r
+ /* Validate the charset */\r
+ if (flags & SRE_INFO_CHARSET) {\r
+ if (!_validate_charset(code, newcode-1))\r
+ FAIL;\r
+ if (newcode[-1] != SRE_OP_FAILURE)\r
+ FAIL;\r
+ code = newcode;\r
+ }\r
+ else if (code != newcode) {\r
+ VTRACE(("code=%p, newcode=%p\n", code, newcode));\r
+ FAIL;\r
+ }\r
+ }\r
+ break;\r
+\r
+ case SRE_OP_BRANCH:\r
+ {\r
+ SRE_CODE *target = NULL;\r
+ for (;;) {\r
+ GET_SKIP;\r
+ if (skip == 0)\r
+ break;\r
+ /* Stop 2 before the end; we check the JUMP below */\r
+ if (!_validate_inner(code, code+skip-3, groups))\r
+ FAIL;\r
+ code += skip-3;\r
+ /* Check that it ends with a JUMP, and that each JUMP\r
+ has the same target */\r
+ GET_OP;\r
+ if (op != SRE_OP_JUMP)\r
+ FAIL;\r
+ GET_SKIP;\r
+ if (target == NULL)\r
+ target = code+skip-1;\r
+ else if (code+skip-1 != target)\r
+ FAIL;\r
+ }\r
+ }\r
+ break;\r
+\r
+ case SRE_OP_REPEAT_ONE:\r
+ case SRE_OP_MIN_REPEAT_ONE:\r
+ {\r
+ SRE_CODE min, max;\r
+ GET_SKIP;\r
+ GET_ARG; min = arg;\r
+ GET_ARG; max = arg;\r
+ if (min > max)\r
+ FAIL;\r
+ if (max > SRE_MAXREPEAT)\r
+ FAIL;\r
+ if (!_validate_inner(code, code+skip-4, groups))\r
+ FAIL;\r
+ code += skip-4;\r
+ GET_OP;\r
+ if (op != SRE_OP_SUCCESS)\r
+ FAIL;\r
+ }\r
+ break;\r
+\r
+ case SRE_OP_REPEAT:\r
+ {\r
+ SRE_CODE min, max;\r
+ GET_SKIP;\r
+ GET_ARG; min = arg;\r
+ GET_ARG; max = arg;\r
+ if (min > max)\r
+ FAIL;\r
+ if (max > SRE_MAXREPEAT)\r
+ FAIL;\r
+ if (!_validate_inner(code, code+skip-3, groups))\r
+ FAIL;\r
+ code += skip-3;\r
+ GET_OP;\r
+ if (op != SRE_OP_MAX_UNTIL && op != SRE_OP_MIN_UNTIL)\r
+ FAIL;\r
+ }\r
+ break;\r
+\r
+ case SRE_OP_GROUPREF:\r
+ case SRE_OP_GROUPREF_IGNORE:\r
+ GET_ARG;\r
+ if (arg >= groups)\r
+ FAIL;\r
+ break;\r
+\r
+ case SRE_OP_GROUPREF_EXISTS:\r
+ /* The regex syntax for this is: '(?(group)then|else)', where\r
+ 'group' is either an integer group number or a group name,\r
+ 'then' and 'else' are sub-regexes, and 'else' is optional. */\r
+ GET_ARG;\r
+ if (arg >= groups)\r
+ FAIL;\r
+ GET_SKIP_ADJ(1);\r
+ code--; /* The skip is relative to the first arg! */\r
+ /* There are two possibilities here: if there is both a 'then'\r
+ part and an 'else' part, the generated code looks like:\r
+\r
+ GROUPREF_EXISTS\r
+ <group>\r
+ <skipyes>\r
+ ...then part...\r
+ JUMP\r
+ <skipno>\r
+ (<skipyes> jumps here)\r
+ ...else part...\r
+ (<skipno> jumps here)\r
+\r
+ If there is only a 'then' part, it looks like:\r
+\r
+ GROUPREF_EXISTS\r
+ <group>\r
+ <skip>\r
+ ...then part...\r
+ (<skip> jumps here)\r
+\r
+ There is no direct way to decide which it is, and we don't want\r
+ to allow arbitrary jumps anywhere in the code; so we just look\r
+ for a JUMP opcode preceding our skip target.\r
+ */\r
+ if (skip >= 3 && skip-3 < end-code &&\r
+ code[skip-3] == SRE_OP_JUMP)\r
+ {\r
+ VTRACE(("both then and else parts present\n"));\r
+ if (!_validate_inner(code+1, code+skip-3, groups))\r
+ FAIL;\r
+ code += skip-2; /* Position after JUMP, at <skipno> */\r
+ GET_SKIP;\r
+ if (!_validate_inner(code, code+skip-1, groups))\r
+ FAIL;\r
+ code += skip-1;\r
+ }\r
+ else {\r
+ VTRACE(("only a then part present\n"));\r
+ if (!_validate_inner(code+1, code+skip-1, groups))\r
+ FAIL;\r
+ code += skip-1;\r
+ }\r
+ break;\r
+\r
+ case SRE_OP_ASSERT:\r
+ case SRE_OP_ASSERT_NOT:\r
+ GET_SKIP;\r
+ GET_ARG; /* 0 for lookahead, width for lookbehind */\r
+ code--; /* Back up over arg to simplify math below */\r
+ if (arg & 0x80000000)\r
+ FAIL; /* Width too large */\r
+ /* Stop 1 before the end; we check the SUCCESS below */\r
+ if (!_validate_inner(code+1, code+skip-2, groups))\r
+ FAIL;\r
+ code += skip-2;\r
+ GET_OP;\r
+ if (op != SRE_OP_SUCCESS)\r
+ FAIL;\r
+ break;\r
+\r
+ default:\r
+ FAIL;\r
+\r
+ }\r
+ }\r
+\r
+ VTRACE(("okay\n"));\r
+ return 1;\r
+}\r
+\r
+static int\r
+_validate_outer(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups)\r
+{\r
+ if (groups < 0 || groups > 100 || code >= end || end[-1] != SRE_OP_SUCCESS)\r
+ FAIL;\r
+ if (groups == 0) /* fix for simplejson */\r
+ groups = 100; /* 100 groups should always be safe */\r
+ return _validate_inner(code, end-1, groups);\r
+}\r
+\r
+static int\r
+_validate(PatternObject *self)\r
+{\r
+ if (!_validate_outer(self->code, self->code+self->codesize, self->groups))\r
+ {\r
+ PyErr_SetString(PyExc_RuntimeError, "invalid SRE code");\r
+ return 0;\r
+ }\r
+ else\r
+ VTRACE(("Success!\n"));\r
+ return 1;\r
+}\r
+\r
+/* -------------------------------------------------------------------- */\r
+/* match methods */\r
+\r
+static void\r
+match_dealloc(MatchObject* self)\r
+{\r
+ Py_XDECREF(self->regs);\r
+ Py_XDECREF(self->string);\r
+ Py_DECREF(self->pattern);\r
+ PyObject_DEL(self);\r
+}\r
+\r
+static PyObject*\r
+match_getslice_by_index(MatchObject* self, Py_ssize_t index, PyObject* def)\r
+{\r
+ if (index < 0 || index >= self->groups) {\r
+ /* raise IndexError if we were given a bad group number */\r
+ PyErr_SetString(\r
+ PyExc_IndexError,\r
+ "no such group"\r
+ );\r
+ return NULL;\r
+ }\r
+\r
+ index *= 2;\r
+\r
+ if (self->string == Py_None || self->mark[index] < 0) {\r
+ /* return default value if the string or group is undefined */\r
+ Py_INCREF(def);\r
+ return def;\r
+ }\r
+\r
+ return PySequence_GetSlice(\r
+ self->string, self->mark[index], self->mark[index+1]\r
+ );\r
+}\r
+\r
+static Py_ssize_t\r
+match_getindex(MatchObject* self, PyObject* index)\r
+{\r
+ Py_ssize_t i;\r
+\r
+ if (PyInt_Check(index) || PyLong_Check(index))\r
+ return PyInt_AsSsize_t(index);\r
+\r
+ i = -1;\r
+\r
+ if (self->pattern->groupindex) {\r
+ index = PyObject_GetItem(self->pattern->groupindex, index);\r
+ if (index) {\r
+ if (PyInt_Check(index) || PyLong_Check(index))\r
+ i = PyInt_AsSsize_t(index);\r
+ Py_DECREF(index);\r
+ } else\r
+ PyErr_Clear();\r
+ }\r
+\r
+ return i;\r
+}\r
+\r
+static PyObject*\r
+match_getslice(MatchObject* self, PyObject* index, PyObject* def)\r
+{\r
+ return match_getslice_by_index(self, match_getindex(self, index), def);\r
+}\r
+\r
+static PyObject*\r
+match_expand(MatchObject* self, PyObject* ptemplate)\r
+{\r
+ /* delegate to Python code */\r
+ return call(\r
+ SRE_PY_MODULE, "_expand",\r
+ PyTuple_Pack(3, self->pattern, self, ptemplate)\r
+ );\r
+}\r
+\r
+static PyObject*\r
+match_group(MatchObject* self, PyObject* args)\r
+{\r
+ PyObject* result;\r
+ Py_ssize_t i, size;\r
+\r
+ size = PyTuple_GET_SIZE(args);\r
+\r
+ switch (size) {\r
+ case 0:\r
+ result = match_getslice(self, Py_False, Py_None);\r
+ break;\r
+ case 1:\r
+ result = match_getslice(self, PyTuple_GET_ITEM(args, 0), Py_None);\r
+ break;\r
+ default:\r
+ /* fetch multiple items */\r
+ result = PyTuple_New(size);\r
+ if (!result)\r
+ return NULL;\r
+ for (i = 0; i < size; i++) {\r
+ PyObject* item = match_getslice(\r
+ self, PyTuple_GET_ITEM(args, i), Py_None\r
+ );\r
+ if (!item) {\r
+ Py_DECREF(result);\r
+ return NULL;\r
+ }\r
+ PyTuple_SET_ITEM(result, i, item);\r
+ }\r
+ break;\r
+ }\r
+ return result;\r
+}\r
+\r
+static PyObject*\r
+match_groups(MatchObject* self, PyObject* args, PyObject* kw)\r
+{\r
+ PyObject* result;\r
+ Py_ssize_t index;\r
+\r
+ PyObject* def = Py_None;\r
+ static char* kwlist[] = { "default", NULL };\r
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "|O:groups", kwlist, &def))\r
+ return NULL;\r
+\r
+ result = PyTuple_New(self->groups-1);\r
+ if (!result)\r
+ return NULL;\r
+\r
+ for (index = 1; index < self->groups; index++) {\r
+ PyObject* item;\r
+ item = match_getslice_by_index(self, index, def);\r
+ if (!item) {\r
+ Py_DECREF(result);\r
+ return NULL;\r
+ }\r
+ PyTuple_SET_ITEM(result, index-1, item);\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+static PyObject*\r
+match_groupdict(MatchObject* self, PyObject* args, PyObject* kw)\r
+{\r
+ PyObject* result;\r
+ PyObject* keys;\r
+ Py_ssize_t index;\r
+\r
+ PyObject* def = Py_None;\r
+ static char* kwlist[] = { "default", NULL };\r
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "|O:groupdict", kwlist, &def))\r
+ return NULL;\r
+\r
+ result = PyDict_New();\r
+ if (!result || !self->pattern->groupindex)\r
+ return result;\r
+\r
+ keys = PyMapping_Keys(self->pattern->groupindex);\r
+ if (!keys)\r
+ goto failed;\r
+\r
+ for (index = 0; index < PyList_GET_SIZE(keys); index++) {\r
+ int status;\r
+ PyObject* key;\r
+ PyObject* value;\r
+ key = PyList_GET_ITEM(keys, index);\r
+ if (!key)\r
+ goto failed;\r
+ value = match_getslice(self, key, def);\r
+ if (!value) {\r
+ Py_DECREF(key);\r
+ goto failed;\r
+ }\r
+ status = PyDict_SetItem(result, key, value);\r
+ Py_DECREF(value);\r
+ if (status < 0)\r
+ goto failed;\r
+ }\r
+\r
+ Py_DECREF(keys);\r
+\r
+ return result;\r
+\r
+failed:\r
+ Py_XDECREF(keys);\r
+ Py_DECREF(result);\r
+ return NULL;\r
+}\r
+\r
+static PyObject*\r
+match_start(MatchObject* self, PyObject* args)\r
+{\r
+ Py_ssize_t index;\r
+\r
+ PyObject* index_ = Py_False; /* zero */\r
+ if (!PyArg_UnpackTuple(args, "start", 0, 1, &index_))\r
+ return NULL;\r
+\r
+ index = match_getindex(self, index_);\r
+\r
+ if (index < 0 || index >= self->groups) {\r
+ PyErr_SetString(\r
+ PyExc_IndexError,\r
+ "no such group"\r
+ );\r
+ return NULL;\r
+ }\r
+\r
+ /* mark is -1 if group is undefined */\r
+ return PyInt_FromSsize_t(self->mark[index*2]);\r
+}\r
+\r
+static PyObject*\r
+match_end(MatchObject* self, PyObject* args)\r
+{\r
+ Py_ssize_t index;\r
+\r
+ PyObject* index_ = Py_False; /* zero */\r
+ if (!PyArg_UnpackTuple(args, "end", 0, 1, &index_))\r
+ return NULL;\r
+\r
+ index = match_getindex(self, index_);\r
+\r
+ if (index < 0 || index >= self->groups) {\r
+ PyErr_SetString(\r
+ PyExc_IndexError,\r
+ "no such group"\r
+ );\r
+ return NULL;\r
+ }\r
+\r
+ /* mark is -1 if group is undefined */\r
+ return PyInt_FromSsize_t(self->mark[index*2+1]);\r
+}\r
+\r
+LOCAL(PyObject*)\r
+_pair(Py_ssize_t i1, Py_ssize_t i2)\r
+{\r
+ PyObject* pair;\r
+ PyObject* item;\r
+\r
+ pair = PyTuple_New(2);\r
+ if (!pair)\r
+ return NULL;\r
+\r
+ item = PyInt_FromSsize_t(i1);\r
+ if (!item)\r
+ goto error;\r
+ PyTuple_SET_ITEM(pair, 0, item);\r
+\r
+ item = PyInt_FromSsize_t(i2);\r
+ if (!item)\r
+ goto error;\r
+ PyTuple_SET_ITEM(pair, 1, item);\r
+\r
+ return pair;\r
+\r
+ error:\r
+ Py_DECREF(pair);\r
+ return NULL;\r
+}\r
+\r
+static PyObject*\r
+match_span(MatchObject* self, PyObject* args)\r
+{\r
+ Py_ssize_t index;\r
+\r
+ PyObject* index_ = Py_False; /* zero */\r
+ if (!PyArg_UnpackTuple(args, "span", 0, 1, &index_))\r
+ return NULL;\r
+\r
+ index = match_getindex(self, index_);\r
+\r
+ if (index < 0 || index >= self->groups) {\r
+ PyErr_SetString(\r
+ PyExc_IndexError,\r
+ "no such group"\r
+ );\r
+ return NULL;\r
+ }\r
+\r
+ /* marks are -1 if group is undefined */\r
+ return _pair(self->mark[index*2], self->mark[index*2+1]);\r
+}\r
+\r
+static PyObject*\r
+match_regs(MatchObject* self)\r
+{\r
+ PyObject* regs;\r
+ PyObject* item;\r
+ Py_ssize_t index;\r
+\r
+ regs = PyTuple_New(self->groups);\r
+ if (!regs)\r
+ return NULL;\r
+\r
+ for (index = 0; index < self->groups; index++) {\r
+ item = _pair(self->mark[index*2], self->mark[index*2+1]);\r
+ if (!item) {\r
+ Py_DECREF(regs);\r
+ return NULL;\r
+ }\r
+ PyTuple_SET_ITEM(regs, index, item);\r
+ }\r
+\r
+ Py_INCREF(regs);\r
+ self->regs = regs;\r
+\r
+ return regs;\r
+}\r
+\r
+static PyObject*\r
+match_copy(MatchObject* self, PyObject *unused)\r
+{\r
+#ifdef USE_BUILTIN_COPY\r
+ MatchObject* copy;\r
+ Py_ssize_t slots, offset;\r
+\r
+ slots = 2 * (self->pattern->groups+1);\r
+\r
+ copy = PyObject_NEW_VAR(MatchObject, &Match_Type, slots);\r
+ if (!copy)\r
+ return NULL;\r
+\r
+ /* this value a constant, but any compiler should be able to\r
+ figure that out all by itself */\r
+ offset = offsetof(MatchObject, string);\r
+\r
+ Py_XINCREF(self->pattern);\r
+ Py_XINCREF(self->string);\r
+ Py_XINCREF(self->regs);\r
+\r
+ memcpy((char*) copy + offset, (char*) self + offset,\r
+ sizeof(MatchObject) + slots * sizeof(Py_ssize_t) - offset);\r
+\r
+ return (PyObject*) copy;\r
+#else\r
+ PyErr_SetString(PyExc_TypeError, "cannot copy this match object");\r
+ return NULL;\r
+#endif\r
+}\r
+\r
+static PyObject*\r
+match_deepcopy(MatchObject* self, PyObject* memo)\r
+{\r
+#ifdef USE_BUILTIN_COPY\r
+ MatchObject* copy;\r
+\r
+ copy = (MatchObject*) match_copy(self);\r
+ if (!copy)\r
+ return NULL;\r
+\r
+ if (!deepcopy((PyObject**) ©->pattern, memo) ||\r
+ !deepcopy(©->string, memo) ||\r
+ !deepcopy(©->regs, memo)) {\r
+ Py_DECREF(copy);\r
+ return NULL;\r
+ }\r
+\r
+#else\r
+ PyErr_SetString(PyExc_TypeError, "cannot deepcopy this match object");\r
+ return NULL;\r
+#endif\r
+}\r
+\r
+PyDoc_STRVAR(match_doc,\r
+"The result of re.match() and re.search().\n\\r
+Match objects always have a boolean value of True.");\r
+\r
+PyDoc_STRVAR(match_group_doc,\r
+"group([group1, ...]) -> str or tuple.\n\\r
+ Return subgroup(s) of the match by indices or names.\n\\r
+ For 0 returns the entire match.");\r
+\r
+PyDoc_STRVAR(match_start_doc,\r
+"start([group=0]) -> int.\n\\r
+ Return index of the start of the substring matched by group.");\r
+\r
+PyDoc_STRVAR(match_end_doc,\r
+"end([group=0]) -> int.\n\\r
+ Return index of the end of the substring matched by group.");\r
+\r
+PyDoc_STRVAR(match_span_doc,\r
+"span([group]) -> tuple.\n\\r
+ For MatchObject m, return the 2-tuple (m.start(group), m.end(group)).");\r
+\r
+PyDoc_STRVAR(match_groups_doc,\r
+"groups([default=None]) -> tuple.\n\\r
+ Return a tuple containing all the subgroups of the match, from 1.\n\\r
+ The default argument is used for groups\n\\r
+ that did not participate in the match");\r
+\r
+PyDoc_STRVAR(match_groupdict_doc,\r
+"groupdict([default=None]) -> dict.\n\\r
+ Return a dictionary containing all the named subgroups of the match,\n\\r
+ keyed by the subgroup name. The default argument is used for groups\n\\r
+ that did not participate in the match");\r
+\r
+PyDoc_STRVAR(match_expand_doc,\r
+"expand(template) -> str.\n\\r
+ Return the string obtained by doing backslash substitution\n\\r
+ on the string template, as done by the sub() method.");\r
+\r
+static PyMethodDef match_methods[] = {\r
+ {"group", (PyCFunction) match_group, METH_VARARGS, match_group_doc},\r
+ {"start", (PyCFunction) match_start, METH_VARARGS, match_start_doc},\r
+ {"end", (PyCFunction) match_end, METH_VARARGS, match_end_doc},\r
+ {"span", (PyCFunction) match_span, METH_VARARGS, match_span_doc},\r
+ {"groups", (PyCFunction) match_groups, METH_VARARGS|METH_KEYWORDS,\r
+ match_groups_doc},\r
+ {"groupdict", (PyCFunction) match_groupdict, METH_VARARGS|METH_KEYWORDS,\r
+ match_groupdict_doc},\r
+ {"expand", (PyCFunction) match_expand, METH_O, match_expand_doc},\r
+ {"__copy__", (PyCFunction) match_copy, METH_NOARGS},\r
+ {"__deepcopy__", (PyCFunction) match_deepcopy, METH_O},\r
+ {NULL, NULL}\r
+};\r
+\r
+static PyObject *\r
+match_lastindex_get(MatchObject *self)\r
+{\r
+ if (self->lastindex >= 0)\r
+ return PyInt_FromSsize_t(self->lastindex);\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+\r
+static PyObject *\r
+match_lastgroup_get(MatchObject *self)\r
+{\r
+ if (self->pattern->indexgroup && self->lastindex >= 0) {\r
+ PyObject* result = PySequence_GetItem(\r
+ self->pattern->indexgroup, self->lastindex\r
+ );\r
+ if (result)\r
+ return result;\r
+ PyErr_Clear();\r
+ }\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+\r
+static PyObject *\r
+match_regs_get(MatchObject *self)\r
+{\r
+ if (self->regs) {\r
+ Py_INCREF(self->regs);\r
+ return self->regs;\r
+ } else\r
+ return match_regs(self);\r
+}\r
+\r
+static PyGetSetDef match_getset[] = {\r
+ {"lastindex", (getter)match_lastindex_get, (setter)NULL},\r
+ {"lastgroup", (getter)match_lastgroup_get, (setter)NULL},\r
+ {"regs", (getter)match_regs_get, (setter)NULL},\r
+ {NULL}\r
+};\r
+\r
+#define MATCH_OFF(x) offsetof(MatchObject, x)\r
+static PyMemberDef match_members[] = {\r
+ {"string", T_OBJECT, MATCH_OFF(string), READONLY},\r
+ {"re", T_OBJECT, MATCH_OFF(pattern), READONLY},\r
+ {"pos", T_PYSSIZET, MATCH_OFF(pos), READONLY},\r
+ {"endpos", T_PYSSIZET, MATCH_OFF(endpos), READONLY},\r
+ {NULL}\r
+};\r
+\r
+\r
+/* FIXME: implement setattr("string", None) as a special case (to\r
+ detach the associated string, if any */\r
+\r
+static PyTypeObject Match_Type = {\r
+ PyVarObject_HEAD_INIT(NULL, 0)\r
+ "_" SRE_MODULE ".SRE_Match",\r
+ sizeof(MatchObject), sizeof(Py_ssize_t),\r
+ (destructor)match_dealloc, /* tp_dealloc */\r
+ 0, /* tp_print */\r
+ 0, /* tp_getattr */\r
+ 0, /* tp_setattr */\r
+ 0, /* tp_compare */\r
+ 0, /* tp_repr */\r
+ 0, /* tp_as_number */\r
+ 0, /* tp_as_sequence */\r
+ 0, /* tp_as_mapping */\r
+ 0, /* tp_hash */\r
+ 0, /* tp_call */\r
+ 0, /* tp_str */\r
+ 0, /* tp_getattro */\r
+ 0, /* tp_setattro */\r
+ 0, /* tp_as_buffer */\r
+ Py_TPFLAGS_DEFAULT,\r
+ match_doc, /* tp_doc */\r
+ 0, /* tp_traverse */\r
+ 0, /* tp_clear */\r
+ 0, /* tp_richcompare */\r
+ 0, /* tp_weaklistoffset */\r
+ 0, /* tp_iter */\r
+ 0, /* tp_iternext */\r
+ match_methods, /* tp_methods */\r
+ match_members, /* tp_members */\r
+ match_getset, /* tp_getset */\r
+};\r
+\r
+static PyObject*\r
+pattern_new_match(PatternObject* pattern, SRE_STATE* state, int status)\r
+{\r
+ /* create match object (from state object) */\r
+\r
+ MatchObject* match;\r
+ Py_ssize_t i, j;\r
+ char* base;\r
+ int n;\r
+\r
+ if (status > 0) {\r
+\r
+ /* create match object (with room for extra group marks) */\r
+ /* coverity[ampersand_in_size] */\r
+ match = PyObject_NEW_VAR(MatchObject, &Match_Type,\r
+ 2*(pattern->groups+1));\r
+ if (!match)\r
+ return NULL;\r
+\r
+ Py_INCREF(pattern);\r
+ match->pattern = pattern;\r
+\r
+ Py_INCREF(state->string);\r
+ match->string = state->string;\r
+\r
+ match->regs = NULL;\r
+ match->groups = pattern->groups+1;\r
+\r
+ /* fill in group slices */\r
+\r
+ base = (char*) state->beginning;\r
+ n = state->charsize;\r
+\r
+ match->mark[0] = ((char*) state->start - base) / n;\r
+ match->mark[1] = ((char*) state->ptr - base) / n;\r
+\r
+ for (i = j = 0; i < pattern->groups; i++, j+=2)\r
+ if (j+1 <= state->lastmark && state->mark[j] && state->mark[j+1]) {\r
+ match->mark[j+2] = ((char*) state->mark[j] - base) / n;\r
+ match->mark[j+3] = ((char*) state->mark[j+1] - base) / n;\r
+ } else\r
+ match->mark[j+2] = match->mark[j+3] = -1; /* undefined */\r
+\r
+ match->pos = state->pos;\r
+ match->endpos = state->endpos;\r
+\r
+ match->lastindex = state->lastindex;\r
+\r
+ return (PyObject*) match;\r
+\r
+ } else if (status == 0) {\r
+\r
+ /* no match */\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+\r
+ }\r
+\r
+ /* internal error */\r
+ pattern_error(status);\r
+ return NULL;\r
+}\r
+\r
+\r
+/* -------------------------------------------------------------------- */\r
+/* scanner methods (experimental) */\r
+\r
+static void\r
+scanner_dealloc(ScannerObject* self)\r
+{\r
+ state_fini(&self->state);\r
+ Py_XDECREF(self->pattern);\r
+ PyObject_DEL(self);\r
+}\r
+\r
+static PyObject*\r
+scanner_match(ScannerObject* self, PyObject *unused)\r
+{\r
+ SRE_STATE* state = &self->state;\r
+ PyObject* match;\r
+ int status;\r
+\r
+ state_reset(state);\r
+\r
+ state->ptr = state->start;\r
+\r
+ if (state->charsize == 1) {\r
+ status = sre_match(state, PatternObject_GetCode(self->pattern));\r
+ } else {\r
+#if defined(HAVE_UNICODE)\r
+ status = sre_umatch(state, PatternObject_GetCode(self->pattern));\r
+#endif\r
+ }\r
+ if (PyErr_Occurred())\r
+ return NULL;\r
+\r
+ match = pattern_new_match((PatternObject*) self->pattern,\r
+ state, status);\r
+\r
+ if (status == 0 || state->ptr == state->start)\r
+ state->start = (void*) ((char*) state->ptr + state->charsize);\r
+ else\r
+ state->start = state->ptr;\r
+\r
+ return match;\r
+}\r
+\r
+\r
+static PyObject*\r
+scanner_search(ScannerObject* self, PyObject *unused)\r
+{\r
+ SRE_STATE* state = &self->state;\r
+ PyObject* match;\r
+ int status;\r
+\r
+ state_reset(state);\r
+\r
+ state->ptr = state->start;\r
+\r
+ if (state->charsize == 1) {\r
+ status = sre_search(state, PatternObject_GetCode(self->pattern));\r
+ } else {\r
+#if defined(HAVE_UNICODE)\r
+ status = sre_usearch(state, PatternObject_GetCode(self->pattern));\r
+#endif\r
+ }\r
+ if (PyErr_Occurred())\r
+ return NULL;\r
+\r
+ match = pattern_new_match((PatternObject*) self->pattern,\r
+ state, status);\r
+\r
+ if (status == 0 || state->ptr == state->start)\r
+ state->start = (void*) ((char*) state->ptr + state->charsize);\r
+ else\r
+ state->start = state->ptr;\r
+\r
+ return match;\r
+}\r
+\r
+static PyMethodDef scanner_methods[] = {\r
+ {"match", (PyCFunction) scanner_match, METH_NOARGS},\r
+ {"search", (PyCFunction) scanner_search, METH_NOARGS},\r
+ {NULL, NULL}\r
+};\r
+\r
+#define SCAN_OFF(x) offsetof(ScannerObject, x)\r
+static PyMemberDef scanner_members[] = {\r
+ {"pattern", T_OBJECT, SCAN_OFF(pattern), READONLY},\r
+ {NULL} /* Sentinel */\r
+};\r
+\r
+statichere PyTypeObject Scanner_Type = {\r
+ PyObject_HEAD_INIT(NULL)\r
+ 0, "_" SRE_MODULE ".SRE_Scanner",\r
+ sizeof(ScannerObject), 0,\r
+ (destructor)scanner_dealloc, /*tp_dealloc*/\r
+ 0, /* tp_print */\r
+ 0, /* tp_getattr */\r
+ 0, /* tp_setattr */\r
+ 0, /* tp_reserved */\r
+ 0, /* tp_repr */\r
+ 0, /* tp_as_number */\r
+ 0, /* tp_as_sequence */\r
+ 0, /* tp_as_mapping */\r
+ 0, /* tp_hash */\r
+ 0, /* tp_call */\r
+ 0, /* tp_str */\r
+ 0, /* tp_getattro */\r
+ 0, /* tp_setattro */\r
+ 0, /* tp_as_buffer */\r
+ Py_TPFLAGS_DEFAULT, /* tp_flags */\r
+ 0, /* tp_doc */\r
+ 0, /* tp_traverse */\r
+ 0, /* tp_clear */\r
+ 0, /* tp_richcompare */\r
+ 0, /* tp_weaklistoffset */\r
+ 0, /* tp_iter */\r
+ 0, /* tp_iternext */\r
+ scanner_methods, /* tp_methods */\r
+ scanner_members, /* tp_members */\r
+ 0, /* tp_getset */\r
+};\r
+\r
+static PyObject*\r
+pattern_scanner(PatternObject* pattern, PyObject* args)\r
+{\r
+ /* create search state object */\r
+\r
+ ScannerObject* self;\r
+\r
+ PyObject* string;\r
+ Py_ssize_t start = 0;\r
+ Py_ssize_t end = PY_SSIZE_T_MAX;\r
+ if (!PyArg_ParseTuple(args, "O|nn:scanner", &string, &start, &end))\r
+ return NULL;\r
+\r
+ /* create scanner object */\r
+ self = PyObject_NEW(ScannerObject, &Scanner_Type);\r
+ if (!self)\r
+ return NULL;\r
+ self->pattern = NULL;\r
+\r
+ string = state_init(&self->state, pattern, string, start, end);\r
+ if (!string) {\r
+ Py_DECREF(self);\r
+ return NULL;\r
+ }\r
+\r
+ Py_INCREF(pattern);\r
+ self->pattern = (PyObject*) pattern;\r
+\r
+ return (PyObject*) self;\r
+}\r
+\r
+static PyMethodDef _functions[] = {\r
+ {"compile", _compile, METH_VARARGS},\r
+ {"getcodesize", sre_codesize, METH_NOARGS},\r
+ {"getlower", sre_getlower, METH_VARARGS},\r
+ {NULL, NULL}\r
+};\r
+\r
+#if PY_VERSION_HEX < 0x02030000\r
+DL_EXPORT(void) init_sre(void)\r
+#else\r
+PyMODINIT_FUNC init_sre(void)\r
+#endif\r
+{\r
+ PyObject* m;\r
+ PyObject* d;\r
+ PyObject* x;\r
+\r
+ /* Patch object types */\r
+ if (PyType_Ready(&Pattern_Type) || PyType_Ready(&Match_Type) ||\r
+ PyType_Ready(&Scanner_Type))\r
+ return;\r
+\r
+ m = Py_InitModule("_" SRE_MODULE, _functions);\r
+ if (m == NULL)\r
+ return;\r
+ d = PyModule_GetDict(m);\r
+\r
+ x = PyInt_FromLong(SRE_MAGIC);\r
+ if (x) {\r
+ PyDict_SetItemString(d, "MAGIC", x);\r
+ Py_DECREF(x);\r
+ }\r
+\r
+ x = PyInt_FromLong(sizeof(SRE_CODE));\r
+ if (x) {\r
+ PyDict_SetItemString(d, "CODESIZE", x);\r
+ Py_DECREF(x);\r
+ }\r
+\r
+ x = PyLong_FromUnsignedLong(SRE_MAXREPEAT);\r
+ if (x) {\r
+ PyDict_SetItemString(d, "MAXREPEAT", x);\r
+ Py_DECREF(x);\r
+ }\r
+\r
+ x = PyString_FromString(copyright);\r
+ if (x) {\r
+ PyDict_SetItemString(d, "copyright", x);\r
+ Py_DECREF(x);\r
+ }\r
+}\r
+\r
+#endif /* !defined(SRE_RECURSIVE) */\r
+\r
+/* vim:ts=4:sw=4:et\r
+*/\r
--- /dev/null
+/*\r
+ * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ * 3. Neither the name of the project nor the names of its contributors\r
+ * may be used to endorse or promote products derived from this software\r
+ * without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ */\r
+\r
+#ifndef HAVE_GETADDRINFO\r
+\r
+/*\r
+ * Error return codes from getaddrinfo()\r
+ */\r
+#ifdef EAI_ADDRFAMILY\r
+/* If this is defined, there is a conflicting implementation\r
+ in the C library, which can't be used for some reason.\r
+ Make sure it won't interfere with this emulation. */\r
+\r
+#undef EAI_ADDRFAMILY\r
+#undef EAI_AGAIN\r
+#undef EAI_BADFLAGS\r
+#undef EAI_FAIL\r
+#undef EAI_FAMILY\r
+#undef EAI_MEMORY\r
+#undef EAI_NODATA\r
+#undef EAI_NONAME\r
+#undef EAI_SERVICE\r
+#undef EAI_SOCKTYPE\r
+#undef EAI_SYSTEM\r
+#undef EAI_BADHINTS\r
+#undef EAI_PROTOCOL\r
+#undef EAI_MAX\r
+#undef getaddrinfo\r
+#define getaddrinfo fake_getaddrinfo\r
+#endif /* EAI_ADDRFAMILY */\r
+\r
+#define EAI_ADDRFAMILY 1 /* address family for hostname not supported */\r
+#define EAI_AGAIN 2 /* temporary failure in name resolution */\r
+#define EAI_BADFLAGS 3 /* invalid value for ai_flags */\r
+#define EAI_FAIL 4 /* non-recoverable failure in name resolution */\r
+#define EAI_FAMILY 5 /* ai_family not supported */\r
+#define EAI_MEMORY 6 /* memory allocation failure */\r
+#define EAI_NODATA 7 /* no address associated with hostname */\r
+#define EAI_NONAME 8 /* hostname nor servname provided, or not known */\r
+#define EAI_SERVICE 9 /* servname not supported for ai_socktype */\r
+#define EAI_SOCKTYPE 10 /* ai_socktype not supported */\r
+#define EAI_SYSTEM 11 /* system error returned in errno */\r
+#define EAI_BADHINTS 12\r
+#define EAI_PROTOCOL 13\r
+#define EAI_MAX 14\r
+\r
+/*\r
+ * Flag values for getaddrinfo()\r
+ */\r
+#ifdef AI_PASSIVE\r
+#undef AI_PASSIVE\r
+#undef AI_CANONNAME\r
+#undef AI_NUMERICHOST\r
+#undef AI_MASK\r
+#undef AI_ALL\r
+#undef AI_V4MAPPED_CFG\r
+#undef AI_ADDRCONFIG\r
+#undef AI_V4MAPPED\r
+#undef AI_DEFAULT\r
+#endif /* AI_PASSIVE */\r
+\r
+#define AI_PASSIVE 0x00000001 /* get address to use bind() */\r
+#define AI_CANONNAME 0x00000002 /* fill ai_canonname */\r
+#define AI_NUMERICHOST 0x00000004 /* prevent name resolution */\r
+/* valid flags for addrinfo */\r
+#define AI_MASK (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST)\r
+\r
+#define AI_ALL 0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */\r
+#define AI_V4MAPPED_CFG 0x00000200 /* accept IPv4-mapped if kernel supports */\r
+#define AI_ADDRCONFIG 0x00000400 /* only if any address is assigned */\r
+#define AI_V4MAPPED 0x00000800 /* accept IPv4-mapped IPv6 address */\r
+/* special recommended flags for getipnodebyname */\r
+#define AI_DEFAULT (AI_V4MAPPED_CFG | AI_ADDRCONFIG)\r
+\r
+#endif /* !HAVE_GETADDRINFO */\r
+\r
+#ifndef HAVE_GETNAMEINFO\r
+\r
+/*\r
+ * Constants for getnameinfo()\r
+ */\r
+#ifndef NI_MAXHOST\r
+#define NI_MAXHOST 1025\r
+#define NI_MAXSERV 32\r
+#endif /* !NI_MAXHOST */\r
+\r
+/*\r
+ * Flag values for getnameinfo()\r
+ */\r
+#ifndef NI_NOFQDN\r
+#define NI_NOFQDN 0x00000001\r
+#define NI_NUMERICHOST 0x00000002\r
+#define NI_NAMEREQD 0x00000004\r
+#define NI_NUMERICSERV 0x00000008\r
+#define NI_DGRAM 0x00000010\r
+#endif /* !NI_NOFQDN */\r
+\r
+#endif /* !HAVE_GETNAMEINFO */\r
+\r
+#ifndef HAVE_ADDRINFO\r
+struct addrinfo {\r
+ int ai_flags; /* AI_PASSIVE, AI_CANONNAME */\r
+ int ai_family; /* PF_xxx */\r
+ int ai_socktype; /* SOCK_xxx */\r
+ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */\r
+ size_t ai_addrlen; /* length of ai_addr */\r
+ char *ai_canonname; /* canonical name for hostname */\r
+ struct sockaddr *ai_addr; /* binary address */\r
+ struct addrinfo *ai_next; /* next structure in linked list */\r
+};\r
+#endif /* !HAVE_ADDRINFO */\r
+\r
+#ifndef HAVE_SOCKADDR_STORAGE\r
+/*\r
+ * RFC 2553: protocol-independent placeholder for socket addresses\r
+ */\r
+#define _SS_MAXSIZE 128\r
+#ifdef HAVE_LONG_LONG\r
+#define _SS_ALIGNSIZE (sizeof(PY_LONG_LONG))\r
+#else\r
+#define _SS_ALIGNSIZE (sizeof(double))\r
+#endif /* HAVE_LONG_LONG */\r
+#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(u_char) * 2)\r
+#define _SS_PAD2SIZE (_SS_MAXSIZE - sizeof(u_char) * 2 - \\r
+ _SS_PAD1SIZE - _SS_ALIGNSIZE)\r
+\r
+struct sockaddr_storage {\r
+#ifdef HAVE_SOCKADDR_SA_LEN\r
+ unsigned char ss_len; /* address length */\r
+ unsigned char ss_family; /* address family */\r
+#else\r
+ unsigned short ss_family; /* address family */\r
+#endif /* HAVE_SOCKADDR_SA_LEN */\r
+ char __ss_pad1[_SS_PAD1SIZE];\r
+#ifdef HAVE_LONG_LONG\r
+ PY_LONG_LONG __ss_align; /* force desired structure storage alignment */\r
+#else\r
+ double __ss_align; /* force desired structure storage alignment */\r
+#endif /* HAVE_LONG_LONG */\r
+ char __ss_pad2[_SS_PAD2SIZE];\r
+};\r
+#endif /* !HAVE_SOCKADDR_STORAGE */\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+extern void freehostent Py_PROTO((struct hostent *));\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
--- /dev/null
+/** @file\r
+ Python Module configuration.\r
+\r
+ Copyright (c) 2011-2012, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials are licensed and made available under\r
+ the terms and conditions of the BSD License that accompanies this distribution.\r
+ The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+**/\r
+\r
+/* This file contains the table of built-in modules.\r
+ See init_builtin() in import.c. */\r
+\r
+#include "Python.h"\r
+\r
+extern void initarray(void);\r
+extern void init_ast(void);\r
+extern void initbinascii(void);\r
+extern void init_bisect(void);\r
+extern void initcmath(void);\r
+extern void init_codecs(void);\r
+extern void init_collections(void);\r
+extern void initcPickle(void);\r
+extern void initcStringIO(void);\r
+extern void init_csv(void);\r
+extern void init_ctypes(void);\r
+extern void initdatetime(void);\r
+extern void initedk2(void);\r
+extern void initerrno(void);\r
+extern void init_functools(void);\r
+extern void initfuture_builtins(void);\r
+extern void initgc(void);\r
+extern void init_heapq(void);\r
+extern void init_hotshot(void);\r
+extern void initimp(void);\r
+extern void init_io(void);\r
+extern void inititertools(void);\r
+extern void init_json(void);\r
+extern void init_lsprof(void);\r
+extern void initmath(void);\r
+extern void init_md5(void);\r
+extern void initmmap(void);\r
+extern void initoperator(void);\r
+extern void initparser(void);\r
+extern void initpyexpat(void);\r
+extern void init_random(void);\r
+extern void initselect(void);\r
+extern void init_sha(void);\r
+extern void init_sha256(void);\r
+extern void init_sha512(void);\r
+extern void initsignal(void);\r
+extern void init_socket(void);\r
+extern void init_sre(void);\r
+extern void initstrop(void);\r
+extern void init_struct(void);\r
+extern void init_subprocess(void);\r
+extern void init_symtable(void);\r
+extern void initthread(void);\r
+extern void inittime(void);\r
+extern void initunicodedata(void);\r
+extern void init_weakref(void);\r
+extern void init_winreg(void);\r
+extern void initxxsubtype(void);\r
+extern void initzipimport(void);\r
+extern void initzlib(void);\r
+\r
+extern void PyMarshal_Init(void);\r
+extern void _PyWarnings_Init(void);\r
+\r
+extern void init_multibytecodec(void);\r
+extern void init_codecs_cn(void);\r
+extern void init_codecs_hk(void);\r
+extern void init_codecs_iso2022(void);\r
+extern void init_codecs_jp(void);\r
+extern void init_codecs_kr(void);\r
+extern void init_codecs_tw(void);\r
+\r
+struct _inittab _PyImport_Inittab[] = {\r
+\r
+ //{"_ast", init_ast},\r
+ //{"_bisect", init_bisect}, /* A fast version of bisect.py */\r
+ //{"_csv", init_csv},\r
+ //{"_heapq", init_heapq}, /* A fast version of heapq.py */\r
+ //{"_io", init_io},\r
+ //{"_json", init_json},\r
+ //{"_md5", init_md5},\r
+ //{"_sha", init_sha},\r
+ //{"_sha256", init_sha256},\r
+ //{"_sha512", init_sha512},\r
+ //{"_socket", init_socket},\r
+ //{"_symtable", init_symtable},\r
+\r
+ //{"array", initarray},\r
+ //{"cmath", initcmath},\r
+ //{"cPickle", initcPickle},\r
+ //{"datetime", initdatetime},\r
+ //{"future_builtins", initfuture_builtins},\r
+ //{"parser", initparser},\r
+ //{"pyexpat", initpyexpat},\r
+ //{"select", initselect},\r
+ //{"signal", initsignal},\r
+ //{"strop", initstrop}, /* redefines some string operations that are 100-1000 times faster */\r
+ //{"unicodedata", initunicodedata},\r
+ //{"xxsubtype", initxxsubtype},\r
+ //{"zipimport", initzipimport},\r
+ //{"zlib", initzlib},\r
+\r
+ /* CJK codecs */\r
+ //{"_multibytecodec", init_multibytecodec},\r
+ //{"_codecs_cn", init_codecs_cn},\r
+ //{"_codecs_hk", init_codecs_hk},\r
+ //{"_codecs_iso2022", init_codecs_iso2022},\r
+ //{"_codecs_jp", init_codecs_jp},\r
+ //{"_codecs_kr", init_codecs_kr},\r
+ //{"_codecs_tw", init_codecs_tw},\r
+\r
+#ifdef WITH_THREAD\r
+ {"thread", initthread},\r
+#endif\r
+\r
+ /* These modules are required for the full built-in help() facility provided by pydoc. */\r
+ {"_codecs", init_codecs},\r
+ {"_collections", init_collections},\r
+ {"_functools", init_functools},\r
+ {"_random", init_random},\r
+ {"_sre", init_sre},\r
+ {"_struct", init_struct}, /* Required by the logging package. */\r
+ {"_weakref", init_weakref},\r
+ {"binascii", initbinascii},\r
+ {"cStringIO", initcStringIO}, /* Required by several modules, such as logging. */\r
+ {"gc", initgc},\r
+ {"itertools", inititertools},\r
+ {"math", initmath},\r
+ {"operator", initoperator},\r
+ {"time", inittime},\r
+\r
+ /* These four modules should always be built in. */\r
+ {"edk2", initedk2},\r
+ {"errno", initerrno},\r
+ {"imp", initimp}, /* We get this for free from Python/import.c */\r
+ {"marshal", PyMarshal_Init}, /* We get this for free from Python/marshal.c */\r
+\r
+ /* These entries are here for sys.builtin_module_names */\r
+ {"__main__", NULL},\r
+ {"__builtin__", NULL},\r
+ {"sys", NULL},\r
+ {"exceptions", NULL},\r
+ {"_warnings", _PyWarnings_Init},\r
+\r
+ /* Sentinel */\r
+ {0, 0}\r
+};\r
--- /dev/null
+/** @file\r
+ OS-specific module implementation for EDK II and UEFI.\r
+ Derived from posixmodule.c in Python 2.7.2.\r
+\r
+ Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials are licensed and made available under\r
+ the terms and conditions of the BSD License that accompanies this distribution.\r
+ The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+**/\r
+#define PY_SSIZE_T_CLEAN\r
+\r
+#include "Python.h"\r
+#include "structseq.h"\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <wchar.h>\r
+#include <sys/syslimits.h>\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+PyDoc_STRVAR(edk2__doc__,\r
+ "This module provides access to UEFI firmware functionality that is\n\\r
+ standardized by the C Standard and the POSIX standard (a thinly\n\\r
+ disguised Unix interface). Refer to the library manual and\n\\r
+ corresponding UEFI Specification entries for more information on calls.");\r
+\r
+#ifndef Py_USING_UNICODE\r
+ /* This is used in signatures of functions. */\r
+ #define Py_UNICODE void\r
+#endif\r
+\r
+#ifdef HAVE_SYS_TYPES_H\r
+ #include <sys/types.h>\r
+#endif /* HAVE_SYS_TYPES_H */\r
+\r
+#ifdef HAVE_SYS_STAT_H\r
+ #include <sys/stat.h>\r
+#endif /* HAVE_SYS_STAT_H */\r
+\r
+#ifdef HAVE_SYS_WAIT_H\r
+ #include <sys/wait.h> /* For WNOHANG */\r
+#endif\r
+\r
+#ifdef HAVE_SIGNAL_H\r
+ #include <signal.h>\r
+#endif\r
+\r
+#ifdef HAVE_FCNTL_H\r
+ #include <fcntl.h>\r
+#endif /* HAVE_FCNTL_H */\r
+\r
+#ifdef HAVE_GRP_H\r
+ #include <grp.h>\r
+#endif\r
+\r
+#ifdef HAVE_SYSEXITS_H\r
+ #include <sysexits.h>\r
+#endif /* HAVE_SYSEXITS_H */\r
+\r
+#ifdef HAVE_SYS_LOADAVG_H\r
+ #include <sys/loadavg.h>\r
+#endif\r
+\r
+#ifdef HAVE_UTIME_H\r
+ #include <utime.h>\r
+#endif /* HAVE_UTIME_H */\r
+\r
+#ifdef HAVE_SYS_UTIME_H\r
+ #include <sys/utime.h>\r
+ #define HAVE_UTIME_H /* pretend we do for the rest of this file */\r
+#endif /* HAVE_SYS_UTIME_H */\r
+\r
+#ifdef HAVE_SYS_TIMES_H\r
+ #include <sys/times.h>\r
+#endif /* HAVE_SYS_TIMES_H */\r
+\r
+#ifdef HAVE_SYS_PARAM_H\r
+ #include <sys/param.h>\r
+#endif /* HAVE_SYS_PARAM_H */\r
+\r
+#ifdef HAVE_SYS_UTSNAME_H\r
+ #include <sys/utsname.h>\r
+#endif /* HAVE_SYS_UTSNAME_H */\r
+\r
+#ifdef HAVE_DIRENT_H\r
+ #include <dirent.h>\r
+ #define NAMLEN(dirent) wcslen((dirent)->FileName)\r
+#else\r
+ #define dirent direct\r
+ #define NAMLEN(dirent) (dirent)->d_namlen\r
+ #ifdef HAVE_SYS_NDIR_H\r
+ #include <sys/ndir.h>\r
+ #endif\r
+ #ifdef HAVE_SYS_DIR_H\r
+ #include <sys/dir.h>\r
+ #endif\r
+ #ifdef HAVE_NDIR_H\r
+ #include <ndir.h>\r
+ #endif\r
+#endif\r
+\r
+#ifndef MAXPATHLEN\r
+ #if defined(PATH_MAX) && PATH_MAX > 1024\r
+ #define MAXPATHLEN PATH_MAX\r
+ #else\r
+ #define MAXPATHLEN 1024\r
+ #endif\r
+#endif /* MAXPATHLEN */\r
+\r
+#define WAIT_TYPE int\r
+#define WAIT_STATUS_INT(s) (s)\r
+\r
+/* Issue #1983: pid_t can be longer than a C long on some systems */\r
+#if !defined(SIZEOF_PID_T) || SIZEOF_PID_T == SIZEOF_INT\r
+ #define PARSE_PID "i"\r
+ #define PyLong_FromPid PyInt_FromLong\r
+ #define PyLong_AsPid PyInt_AsLong\r
+#elif SIZEOF_PID_T == SIZEOF_LONG\r
+ #define PARSE_PID "l"\r
+ #define PyLong_FromPid PyInt_FromLong\r
+ #define PyLong_AsPid PyInt_AsLong\r
+#elif defined(SIZEOF_LONG_LONG) && SIZEOF_PID_T == SIZEOF_LONG_LONG\r
+ #define PARSE_PID "L"\r
+ #define PyLong_FromPid PyLong_FromLongLong\r
+ #define PyLong_AsPid PyInt_AsLongLong\r
+#else\r
+ #error "sizeof(pid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)"\r
+#endif /* SIZEOF_PID_T */\r
+\r
+/* Don't use the "_r" form if we don't need it (also, won't have a\r
+ prototype for it, at least on Solaris -- maybe others as well?). */\r
+#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)\r
+ #define USE_CTERMID_R\r
+#endif\r
+\r
+#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)\r
+ #define USE_TMPNAM_R\r
+#endif\r
+\r
+/* choose the appropriate stat and fstat functions and return structs */\r
+#undef STAT\r
+#undef FSTAT\r
+#undef STRUCT_STAT\r
+#define STAT stat\r
+#define FSTAT fstat\r
+#define STRUCT_STAT struct stat\r
+\r
+/* dummy version. _PyVerify_fd() is already defined in fileobject.h */\r
+#define _PyVerify_fd_dup2(A, B) (1)\r
+\r
+#ifndef UEFI_C_SOURCE\r
+/* Return a dictionary corresponding to the POSIX environment table */\r
+extern char **environ;\r
+\r
+static PyObject *\r
+convertenviron(void)\r
+{\r
+ PyObject *d;\r
+ char **e;\r
+ d = PyDict_New();\r
+ if (d == NULL)\r
+ return NULL;\r
+ if (environ == NULL)\r
+ return d;\r
+ /* This part ignores errors */\r
+ for (e = environ; *e != NULL; e++) {\r
+ PyObject *k;\r
+ PyObject *v;\r
+ char *p = strchr(*e, '=');\r
+ if (p == NULL)\r
+ continue;\r
+ k = PyString_FromStringAndSize(*e, (int)(p-*e));\r
+ if (k == NULL) {\r
+ PyErr_Clear();\r
+ continue;\r
+ }\r
+ v = PyString_FromString(p+1);\r
+ if (v == NULL) {\r
+ PyErr_Clear();\r
+ Py_DECREF(k);\r
+ continue;\r
+ }\r
+ if (PyDict_GetItem(d, k) == NULL) {\r
+ if (PyDict_SetItem(d, k, v) != 0)\r
+ PyErr_Clear();\r
+ }\r
+ Py_DECREF(k);\r
+ Py_DECREF(v);\r
+ }\r
+ return d;\r
+}\r
+#endif /* UEFI_C_SOURCE */\r
+\r
+/* Set a POSIX-specific error from errno, and return NULL */\r
+\r
+static PyObject *\r
+posix_error(void)\r
+{\r
+ return PyErr_SetFromErrno(PyExc_OSError);\r
+}\r
+static PyObject *\r
+posix_error_with_filename(char* name)\r
+{\r
+ return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);\r
+}\r
+\r
+\r
+static PyObject *\r
+posix_error_with_allocated_filename(char* name)\r
+{\r
+ PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);\r
+ PyMem_Free(name);\r
+ return rc;\r
+}\r
+\r
+/* POSIX generic methods */\r
+\r
+#ifndef UEFI_C_SOURCE\r
+ static PyObject *\r
+ posix_fildes(PyObject *fdobj, int (*func)(int))\r
+ {\r
+ int fd;\r
+ int res;\r
+ fd = PyObject_AsFileDescriptor(fdobj);\r
+ if (fd < 0)\r
+ return NULL;\r
+ if (!_PyVerify_fd(fd))\r
+ return posix_error();\r
+ Py_BEGIN_ALLOW_THREADS\r
+ res = (*func)(fd);\r
+ Py_END_ALLOW_THREADS\r
+ if (res < 0)\r
+ return posix_error();\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+ }\r
+#endif /* UEFI_C_SOURCE */\r
+\r
+static PyObject *\r
+posix_1str(PyObject *args, char *format, int (*func)(const char*))\r
+{\r
+ char *path1 = NULL;\r
+ int res;\r
+ if (!PyArg_ParseTuple(args, format,\r
+ Py_FileSystemDefaultEncoding, &path1))\r
+ return NULL;\r
+ Py_BEGIN_ALLOW_THREADS\r
+ res = (*func)(path1);\r
+ Py_END_ALLOW_THREADS\r
+ if (res < 0)\r
+ return posix_error_with_allocated_filename(path1);\r
+ PyMem_Free(path1);\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+\r
+static PyObject *\r
+posix_2str(PyObject *args,\r
+ char *format,\r
+ int (*func)(const char *, const char *))\r
+{\r
+ char *path1 = NULL, *path2 = NULL;\r
+ int res;\r
+ if (!PyArg_ParseTuple(args, format,\r
+ Py_FileSystemDefaultEncoding, &path1,\r
+ Py_FileSystemDefaultEncoding, &path2))\r
+ return NULL;\r
+ Py_BEGIN_ALLOW_THREADS\r
+ res = (*func)(path1, path2);\r
+ Py_END_ALLOW_THREADS\r
+ PyMem_Free(path1);\r
+ PyMem_Free(path2);\r
+ if (res != 0)\r
+ /* XXX how to report both path1 and path2??? */\r
+ return posix_error();\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+\r
+PyDoc_STRVAR(stat_result__doc__,\r
+"stat_result: Result from stat or lstat.\n\n\\r
+This object may be accessed either as a tuple of\n\\r
+ (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\\r
+or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\\r
+\n\\r
+Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\\r
+or st_flags, they are available as attributes only.\n\\r
+\n\\r
+See os.stat for more information.");\r
+\r
+static PyStructSequence_Field stat_result_fields[] = {\r
+ {"st_mode", "protection bits"},\r
+ //{"st_ino", "inode"},\r
+ //{"st_dev", "device"},\r
+ //{"st_nlink", "number of hard links"},\r
+ //{"st_uid", "user ID of owner"},\r
+ //{"st_gid", "group ID of owner"},\r
+ {"st_size", "total size, in bytes"},\r
+ /* The NULL is replaced with PyStructSequence_UnnamedField later. */\r
+ {NULL, "integer time of last access"},\r
+ {NULL, "integer time of last modification"},\r
+ {NULL, "integer time of last change"},\r
+ {"st_atime", "time of last access"},\r
+ {"st_mtime", "time of last modification"},\r
+ {"st_ctime", "time of last change"},\r
+#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE\r
+ {"st_blksize", "blocksize for filesystem I/O"},\r
+#endif\r
+#ifdef HAVE_STRUCT_STAT_ST_BLOCKS\r
+ {"st_blocks", "number of blocks allocated"},\r
+#endif\r
+#ifdef HAVE_STRUCT_STAT_ST_RDEV\r
+ {"st_rdev", "device type (if inode device)"},\r
+#endif\r
+#ifdef HAVE_STRUCT_STAT_ST_FLAGS\r
+ {"st_flags", "user defined flags for file"},\r
+#endif\r
+#ifdef HAVE_STRUCT_STAT_ST_GEN\r
+ {"st_gen", "generation number"},\r
+#endif\r
+#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME\r
+ {"st_birthtime", "time of creation"},\r
+#endif\r
+ {0}\r
+};\r
+\r
+#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE\r
+#define ST_BLKSIZE_IDX 8\r
+#else\r
+#define ST_BLKSIZE_IDX 12\r
+#endif\r
+\r
+#ifdef HAVE_STRUCT_STAT_ST_BLOCKS\r
+#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)\r
+#else\r
+#define ST_BLOCKS_IDX ST_BLKSIZE_IDX\r
+#endif\r
+\r
+#ifdef HAVE_STRUCT_STAT_ST_RDEV\r
+#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)\r
+#else\r
+#define ST_RDEV_IDX ST_BLOCKS_IDX\r
+#endif\r
+\r
+#ifdef HAVE_STRUCT_STAT_ST_FLAGS\r
+#define ST_FLAGS_IDX (ST_RDEV_IDX+1)\r
+#else\r
+#define ST_FLAGS_IDX ST_RDEV_IDX\r
+#endif\r
+\r
+#ifdef HAVE_STRUCT_STAT_ST_GEN\r
+#define ST_GEN_IDX (ST_FLAGS_IDX+1)\r
+#else\r
+#define ST_GEN_IDX ST_FLAGS_IDX\r
+#endif\r
+\r
+#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME\r
+#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)\r
+#else\r
+#define ST_BIRTHTIME_IDX ST_GEN_IDX\r
+#endif\r
+\r
+static PyStructSequence_Desc stat_result_desc = {\r
+ "stat_result", /* name */\r
+ stat_result__doc__, /* doc */\r
+ stat_result_fields,\r
+ 10\r
+};\r
+\r
+#ifndef UEFI_C_SOURCE /* Not in UEFI */\r
+PyDoc_STRVAR(statvfs_result__doc__,\r
+"statvfs_result: Result from statvfs or fstatvfs.\n\n\\r
+This object may be accessed either as a tuple of\n\\r
+ (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\\r
+or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\\r
+\n\\r
+See os.statvfs for more information.");\r
+\r
+static PyStructSequence_Field statvfs_result_fields[] = {\r
+ {"f_bsize", },\r
+ {"f_frsize", },\r
+ {"f_blocks", },\r
+ {"f_bfree", },\r
+ {"f_bavail", },\r
+ {"f_files", },\r
+ {"f_ffree", },\r
+ {"f_favail", },\r
+ {"f_flag", },\r
+ {"f_namemax",},\r
+ {0}\r
+};\r
+\r
+static PyStructSequence_Desc statvfs_result_desc = {\r
+ "statvfs_result", /* name */\r
+ statvfs_result__doc__, /* doc */\r
+ statvfs_result_fields,\r
+ 10\r
+};\r
+\r
+static PyTypeObject StatVFSResultType;\r
+#endif\r
+\r
+static int initialized;\r
+static PyTypeObject StatResultType;\r
+static newfunc structseq_new;\r
+\r
+static PyObject *\r
+statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
+{\r
+ PyStructSequence *result;\r
+ int i;\r
+\r
+ result = (PyStructSequence*)structseq_new(type, args, kwds);\r
+ if (!result)\r
+ return NULL;\r
+ /* If we have been initialized from a tuple,\r
+ st_?time might be set to None. Initialize it\r
+ from the int slots. */\r
+ for (i = 7; i <= 9; i++) {\r
+ if (result->ob_item[i+3] == Py_None) {\r
+ Py_DECREF(Py_None);\r
+ Py_INCREF(result->ob_item[i]);\r
+ result->ob_item[i+3] = result->ob_item[i];\r
+ }\r
+ }\r
+ return (PyObject*)result;\r
+}\r
+\r
+\r
+\r
+/* If true, st_?time is float. */\r
+#if defined(UEFI_C_SOURCE)\r
+ static int _stat_float_times = 0;\r
+#else\r
+ static int _stat_float_times = 1;\r
+\r
+PyDoc_STRVAR(stat_float_times__doc__,\r
+"stat_float_times([newval]) -> oldval\n\n\\r
+Determine whether os.[lf]stat represents time stamps as float objects.\n\\r
+If newval is True, future calls to stat() return floats, if it is False,\n\\r
+future calls return ints. \n\\r
+If newval is omitted, return the current setting.\n");\r
+\r
+static PyObject*\r
+stat_float_times(PyObject* self, PyObject *args)\r
+{\r
+ int newval = -1;\r
+\r
+ if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))\r
+ return NULL;\r
+ if (newval == -1)\r
+ /* Return old value */\r
+ return PyBool_FromLong(_stat_float_times);\r
+ _stat_float_times = newval;\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+#endif /* UEFI_C_SOURCE */\r
+\r
+static void\r
+fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)\r
+{\r
+ PyObject *fval,*ival;\r
+#if SIZEOF_TIME_T > SIZEOF_LONG\r
+ ival = PyLong_FromLongLong((PY_LONG_LONG)sec);\r
+#else\r
+ ival = PyInt_FromLong((long)sec);\r
+#endif\r
+ if (!ival)\r
+ return;\r
+ if (_stat_float_times) {\r
+ fval = PyFloat_FromDouble(sec + 1e-9*nsec);\r
+ } else {\r
+ fval = ival;\r
+ Py_INCREF(fval);\r
+ }\r
+ PyStructSequence_SET_ITEM(v, index, ival);\r
+ PyStructSequence_SET_ITEM(v, index+3, fval);\r
+}\r
+\r
+/* pack a system stat C structure into the Python stat tuple\r
+ (used by posix_stat() and posix_fstat()) */\r
+static PyObject*\r
+_pystat_fromstructstat(STRUCT_STAT *st)\r
+{\r
+ unsigned long ansec, mnsec, cnsec;\r
+ PyObject *v = PyStructSequence_New(&StatResultType);\r
+ if (v == NULL)\r
+ return NULL;\r
+\r
+ PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));\r
+ PyStructSequence_SET_ITEM(v, 1,\r
+ PyLong_FromLongLong((PY_LONG_LONG)st->st_size));\r
+\r
+ ansec = mnsec = cnsec = 0;\r
+ /* The index used by fill_time is the index of the integer time.\r
+ fill_time will add 3 to the index to get the floating time index.\r
+ */\r
+ fill_time(v, 2, st->st_atime, ansec);\r
+ fill_time(v, 3, st->st_mtime, mnsec);\r
+ fill_time(v, 4, st->st_mtime, cnsec);\r
+\r
+#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE\r
+ PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,\r
+ PyInt_FromLong((long)st->st_blksize));\r
+#endif\r
+#ifdef HAVE_STRUCT_STAT_ST_BLOCKS\r
+ PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,\r
+ PyInt_FromLong((long)st->st_blocks));\r
+#endif\r
+#ifdef HAVE_STRUCT_STAT_ST_RDEV\r
+ PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,\r
+ PyInt_FromLong((long)st->st_rdev));\r
+#endif\r
+#ifdef HAVE_STRUCT_STAT_ST_GEN\r
+ PyStructSequence_SET_ITEM(v, ST_GEN_IDX,\r
+ PyInt_FromLong((long)st->st_gen));\r
+#endif\r
+#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME\r
+ {\r
+ PyObject *val;\r
+ unsigned long bsec,bnsec;\r
+ bsec = (long)st->st_birthtime;\r
+#ifdef HAVE_STAT_TV_NSEC2\r
+ bnsec = st->st_birthtimespec.tv_nsec;\r
+#else\r
+ bnsec = 0;\r
+#endif\r
+ if (_stat_float_times) {\r
+ val = PyFloat_FromDouble(bsec + 1e-9*bnsec);\r
+ } else {\r
+ val = PyInt_FromLong((long)bsec);\r
+ }\r
+ PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,\r
+ val);\r
+ }\r
+#endif\r
+#ifdef HAVE_STRUCT_STAT_ST_FLAGS\r
+ PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,\r
+ PyInt_FromLong((long)st->st_flags));\r
+#endif\r
+\r
+ if (PyErr_Occurred()) {\r
+ Py_DECREF(v);\r
+ return NULL;\r
+ }\r
+\r
+ return v;\r
+}\r
+\r
+static PyObject *\r
+posix_do_stat(PyObject *self, PyObject *args,\r
+ char *format,\r
+ int (*statfunc)(const char *, STRUCT_STAT *),\r
+ char *wformat,\r
+ int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))\r
+{\r
+ STRUCT_STAT st;\r
+ char *path = NULL; /* pass this to stat; do not free() it */\r
+ char *pathfree = NULL; /* this memory must be free'd */\r
+ int res;\r
+ PyObject *result;\r
+\r
+ if (!PyArg_ParseTuple(args, format,\r
+ Py_FileSystemDefaultEncoding, &path))\r
+ return NULL;\r
+ pathfree = path;\r
+\r
+ Py_BEGIN_ALLOW_THREADS\r
+ res = (*statfunc)(path, &st);\r
+ Py_END_ALLOW_THREADS\r
+\r
+ if (res != 0) {\r
+ result = posix_error_with_filename(pathfree);\r
+ }\r
+ else\r
+ result = _pystat_fromstructstat(&st);\r
+\r
+ PyMem_Free(pathfree);\r
+ return result;\r
+}\r
+\r
+/* POSIX methods */\r
+\r
+PyDoc_STRVAR(posix_access__doc__,\r
+"access(path, mode) -> True if granted, False otherwise\n\n\\r
+Use the real uid/gid to test for access to a path. Note that most\n\\r
+operations will use the effective uid/gid, therefore this routine can\n\\r
+be used in a suid/sgid environment to test if the invoking user has the\n\\r
+specified access to the path. The mode argument can be F_OK to test\n\\r
+existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");\r
+\r
+static PyObject *\r
+posix_access(PyObject *self, PyObject *args)\r
+{\r
+ char *path;\r
+ int mode;\r
+\r
+ int res;\r
+ if (!PyArg_ParseTuple(args, "eti:access",\r
+ Py_FileSystemDefaultEncoding, &path, &mode))\r
+ return NULL;\r
+ Py_BEGIN_ALLOW_THREADS\r
+ res = access(path, mode);\r
+ Py_END_ALLOW_THREADS\r
+ PyMem_Free(path);\r
+ return PyBool_FromLong(res == 0);\r
+}\r
+\r
+#ifndef F_OK\r
+ #define F_OK 0\r
+#endif\r
+#ifndef R_OK\r
+ #define R_OK 4\r
+#endif\r
+#ifndef W_OK\r
+ #define W_OK 2\r
+#endif\r
+#ifndef X_OK\r
+ #define X_OK 1\r
+#endif\r
+\r
+PyDoc_STRVAR(posix_chdir__doc__,\r
+"chdir(path)\n\n\\r
+Change the current working directory to the specified path.");\r
+\r
+static PyObject *\r
+posix_chdir(PyObject *self, PyObject *args)\r
+{\r
+ return posix_1str(args, "et:chdir", chdir);\r
+}\r
+\r
+PyDoc_STRVAR(posix_chmod__doc__,\r
+"chmod(path, mode)\n\n\\r
+Change the access permissions of a file.");\r
+\r
+static PyObject *\r
+posix_chmod(PyObject *self, PyObject *args)\r
+{\r
+ char *path = NULL;\r
+ int i;\r
+ int res;\r
+ if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,\r
+ &path, &i))\r
+ return NULL;\r
+ Py_BEGIN_ALLOW_THREADS\r
+ res = chmod(path, i);\r
+ Py_END_ALLOW_THREADS\r
+ if (res < 0)\r
+ return posix_error_with_allocated_filename(path);\r
+ PyMem_Free(path);\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+\r
+#ifdef HAVE_FCHMOD\r
+PyDoc_STRVAR(posix_fchmod__doc__,\r
+"fchmod(fd, mode)\n\n\\r
+Change the access permissions of the file given by file\n\\r
+descriptor fd.");\r
+\r
+static PyObject *\r
+posix_fchmod(PyObject *self, PyObject *args)\r
+{\r
+ int fd, mode, res;\r
+ if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))\r
+ return NULL;\r
+ Py_BEGIN_ALLOW_THREADS\r
+ res = fchmod(fd, mode);\r
+ Py_END_ALLOW_THREADS\r
+ if (res < 0)\r
+ return posix_error();\r
+ Py_RETURN_NONE;\r
+}\r
+#endif /* HAVE_FCHMOD */\r
+\r
+#ifdef HAVE_LCHMOD\r
+PyDoc_STRVAR(posix_lchmod__doc__,\r
+"lchmod(path, mode)\n\n\\r
+Change the access permissions of a file. If path is a symlink, this\n\\r
+affects the link itself rather than the target.");\r
+\r
+static PyObject *\r
+posix_lchmod(PyObject *self, PyObject *args)\r
+{\r
+ char *path = NULL;\r
+ int i;\r
+ int res;\r
+ if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,\r
+ &path, &i))\r
+ return NULL;\r
+ Py_BEGIN_ALLOW_THREADS\r
+ res = lchmod(path, i);\r
+ Py_END_ALLOW_THREADS\r
+ if (res < 0)\r
+ return posix_error_with_allocated_filename(path);\r
+ PyMem_Free(path);\r
+ Py_RETURN_NONE;\r
+}\r
+#endif /* HAVE_LCHMOD */\r
+\r
+\r
+#ifdef HAVE_CHFLAGS\r
+PyDoc_STRVAR(posix_chflags__doc__,\r
+"chflags(path, flags)\n\n\\r
+Set file flags.");\r
+\r
+static PyObject *\r
+posix_chflags(PyObject *self, PyObject *args)\r
+{\r
+ char *path;\r
+ unsigned long flags;\r
+ int res;\r
+ if (!PyArg_ParseTuple(args, "etk:chflags",\r
+ Py_FileSystemDefaultEncoding, &path, &flags))\r
+ return NULL;\r
+ Py_BEGIN_ALLOW_THREADS\r
+ res = chflags(path, flags);\r
+ Py_END_ALLOW_THREADS\r
+ if (res < 0)\r
+ return posix_error_with_allocated_filename(path);\r
+ PyMem_Free(path);\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+#endif /* HAVE_CHFLAGS */\r
+\r
+#ifdef HAVE_LCHFLAGS\r
+PyDoc_STRVAR(posix_lchflags__doc__,\r
+"lchflags(path, flags)\n\n\\r
+Set file flags.\n\\r
+This function will not follow symbolic links.");\r
+\r
+static PyObject *\r
+posix_lchflags(PyObject *self, PyObject *args)\r
+{\r
+ char *path;\r
+ unsigned long flags;\r
+ int res;\r
+ if (!PyArg_ParseTuple(args, "etk:lchflags",\r
+ Py_FileSystemDefaultEncoding, &path, &flags))\r
+ return NULL;\r
+ Py_BEGIN_ALLOW_THREADS\r
+ res = lchflags(path, flags);\r
+ Py_END_ALLOW_THREADS\r
+ if (res < 0)\r
+ return posix_error_with_allocated_filename(path);\r
+ PyMem_Free(path);\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+#endif /* HAVE_LCHFLAGS */\r
+\r
+#ifdef HAVE_CHROOT\r
+PyDoc_STRVAR(posix_chroot__doc__,\r
+"chroot(path)\n\n\\r
+Change root directory to path.");\r
+\r
+static PyObject *\r
+posix_chroot(PyObject *self, PyObject *args)\r
+{\r
+ return posix_1str(args, "et:chroot", chroot);\r
+}\r
+#endif\r
+\r
+#ifdef HAVE_FSYNC\r
+PyDoc_STRVAR(posix_fsync__doc__,\r
+"fsync(fildes)\n\n\\r
+force write of file with filedescriptor to disk.");\r
+\r
+static PyObject *\r
+posix_fsync(PyObject *self, PyObject *fdobj)\r
+{\r
+ return posix_fildes(fdobj, fsync);\r
+}\r
+#endif /* HAVE_FSYNC */\r
+\r
+#ifdef HAVE_FDATASYNC\r
+\r
+#ifdef __hpux\r
+extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */\r
+#endif\r
+\r
+PyDoc_STRVAR(posix_fdatasync__doc__,\r
+"fdatasync(fildes)\n\n\\r
+force write of file with filedescriptor to disk.\n\\r
+ does not force update of metadata.");\r
+\r
+static PyObject *\r
+posix_fdatasync(PyObject *self, PyObject *fdobj)\r
+{\r
+ return posix_fildes(fdobj, fdatasync);\r
+}\r
+#endif /* HAVE_FDATASYNC */\r
+\r
+\r
+#ifdef HAVE_CHOWN\r
+PyDoc_STRVAR(posix_chown__doc__,\r
+"chown(path, uid, gid)\n\n\\r
+Change the owner and group id of path to the numeric uid and gid.");\r
+\r
+static PyObject *\r
+posix_chown(PyObject *self, PyObject *args)\r
+{\r
+ char *path = NULL;\r
+ long uid, gid;\r
+ int res;\r
+ if (!PyArg_ParseTuple(args, "etll:chown",\r
+ Py_FileSystemDefaultEncoding, &path,\r
+ &uid, &gid))\r
+ return NULL;\r
+ Py_BEGIN_ALLOW_THREADS\r
+ res = chown(path, (uid_t) uid, (gid_t) gid);\r
+ Py_END_ALLOW_THREADS\r
+ if (res < 0)\r
+ return posix_error_with_allocated_filename(path);\r
+ PyMem_Free(path);\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+#endif /* HAVE_CHOWN */\r
+\r
+#ifdef HAVE_FCHOWN\r
+PyDoc_STRVAR(posix_fchown__doc__,\r
+"fchown(fd, uid, gid)\n\n\\r
+Change the owner and group id of the file given by file descriptor\n\\r
+fd to the numeric uid and gid.");\r
+\r
+static PyObject *\r
+posix_fchown(PyObject *self, PyObject *args)\r
+{\r
+ int fd;\r
+ long uid, gid;\r
+ int res;\r
+ if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid))\r
+ return NULL;\r
+ Py_BEGIN_ALLOW_THREADS\r
+ res = fchown(fd, (uid_t) uid, (gid_t) gid);\r
+ Py_END_ALLOW_THREADS\r
+ if (res < 0)\r
+ return posix_error();\r
+ Py_RETURN_NONE;\r
+}\r
+#endif /* HAVE_FCHOWN */\r
+\r
+#ifdef HAVE_LCHOWN\r
+PyDoc_STRVAR(posix_lchown__doc__,\r
+"lchown(path, uid, gid)\n\n\\r
+Change the owner and group id of path to the numeric uid and gid.\n\\r
+This function will not follow symbolic links.");\r
+\r
+static PyObject *\r
+posix_lchown(PyObject *self, PyObject *args)\r
+{\r
+ char *path = NULL;\r
+ long uid, gid;\r
+ int res;\r
+ if (!PyArg_ParseTuple(args, "etll:lchown",\r
+ Py_FileSystemDefaultEncoding, &path,\r
+ &uid, &gid))\r
+ return NULL;\r
+ Py_BEGIN_ALLOW_THREADS\r
+ res = lchown(path, (uid_t) uid, (gid_t) gid);\r
+ Py_END_ALLOW_THREADS\r
+ if (res < 0)\r
+ return posix_error_with_allocated_filename(path);\r
+ PyMem_Free(path);\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+#endif /* HAVE_LCHOWN */\r
+\r
+\r
+#ifdef HAVE_GETCWD\r
+PyDoc_STRVAR(posix_getcwd__doc__,\r
+"getcwd() -> path\n\n\\r
+Return a string representing the current working directory.");\r
+\r
+static PyObject *\r
+posix_getcwd(PyObject *self, PyObject *noargs)\r
+{\r
+ int bufsize_incr = 1024;\r
+ int bufsize = 0;\r
+ char *tmpbuf = NULL;\r
+ char *res = NULL;\r
+ PyObject *dynamic_return;\r
+\r
+ Py_BEGIN_ALLOW_THREADS\r
+ do {\r
+ bufsize = bufsize + bufsize_incr;\r
+ tmpbuf = malloc(bufsize);\r
+ if (tmpbuf == NULL) {\r
+ break;\r
+ }\r
+ res = getcwd(tmpbuf, bufsize);\r
+ if (res == NULL) {\r
+ free(tmpbuf);\r
+ }\r
+ } while ((res == NULL) && (errno == ERANGE));\r
+ Py_END_ALLOW_THREADS\r
+\r
+ if (res == NULL)\r
+ return posix_error();\r
+\r
+ dynamic_return = PyString_FromString(tmpbuf);\r
+ free(tmpbuf);\r
+\r
+ return dynamic_return;\r
+}\r
+\r
+#ifdef Py_USING_UNICODE\r
+PyDoc_STRVAR(posix_getcwdu__doc__,\r
+"getcwdu() -> path\n\n\\r
+Return a unicode string representing the current working directory.");\r
+\r
+static PyObject *\r
+posix_getcwdu(PyObject *self, PyObject *noargs)\r
+{\r
+ char buf[1026];\r
+ char *res;\r
+\r
+ Py_BEGIN_ALLOW_THREADS\r
+ res = getcwd(buf, sizeof buf);\r
+ Py_END_ALLOW_THREADS\r
+ if (res == NULL)\r
+ return posix_error();\r
+ return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");\r
+}\r
+#endif /* Py_USING_UNICODE */\r
+#endif /* HAVE_GETCWD */\r
+\r
+\r
+PyDoc_STRVAR(posix_listdir__doc__,\r
+"listdir(path) -> list_of_strings\n\n\\r
+Return a list containing the names of the entries in the directory.\n\\r
+\n\\r
+ path: path of directory to list\n\\r
+\n\\r
+The list is in arbitrary order. It does not include the special\n\\r
+entries '.' and '..' even if they are present in the directory.");\r
+\r
+static PyObject *\r
+posix_listdir(PyObject *self, PyObject *args)\r
+{\r
+ /* XXX Should redo this putting the (now four) versions of opendir\r
+ in separate files instead of having them all here... */\r
+\r
+ char *name = NULL;\r
+ char *MBname;\r
+ PyObject *d, *v;\r
+ DIR *dirp;\r
+ struct dirent *ep;\r
+ int arg_is_unicode = 1;\r
+\r
+ errno = 0;\r
+ if (!PyArg_ParseTuple(args, "U:listdir", &v)) {\r
+ arg_is_unicode = 0;\r
+ PyErr_Clear();\r
+ }\r
+ if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))\r
+ return NULL;\r
+ Py_BEGIN_ALLOW_THREADS\r
+ dirp = opendir(name);\r
+ Py_END_ALLOW_THREADS\r
+ if (dirp == NULL) {\r
+ return posix_error_with_allocated_filename(name);\r
+ }\r
+ if ((d = PyList_New(0)) == NULL) {\r
+ Py_BEGIN_ALLOW_THREADS\r
+ closedir(dirp);\r
+ Py_END_ALLOW_THREADS\r
+ PyMem_Free(name);\r
+ return NULL;\r
+ }\r
+ if((MBname = malloc(NAME_MAX)) == NULL) {\r
+ Py_BEGIN_ALLOW_THREADS\r
+ closedir(dirp);\r
+ Py_END_ALLOW_THREADS\r
+ Py_DECREF(d);\r
+ PyMem_Free(name);\r
+ return NULL;\r
+ }\r
+ for (;;) {\r
+ errno = 0;\r
+ Py_BEGIN_ALLOW_THREADS\r
+ ep = readdir(dirp);\r
+ Py_END_ALLOW_THREADS\r
+ if (ep == NULL) {\r
+ if ((errno == 0) || (errno == EISDIR)) {\r
+ break;\r
+ } else {\r
+ Py_BEGIN_ALLOW_THREADS\r
+ closedir(dirp);\r
+ Py_END_ALLOW_THREADS\r
+ Py_DECREF(d);\r
+ return posix_error_with_allocated_filename(name);\r
+ }\r
+ }\r
+ if (ep->FileName[0] == L'.' &&\r
+ (NAMLEN(ep) == 1 ||\r
+ (ep->FileName[1] == L'.' && NAMLEN(ep) == 2)))\r
+ continue;\r
+ if(wcstombs(MBname, ep->FileName, NAME_MAX) == -1) {\r
+ free(MBname);\r
+ Py_BEGIN_ALLOW_THREADS\r
+ closedir(dirp);\r
+ Py_END_ALLOW_THREADS\r
+ Py_DECREF(d);\r
+ PyMem_Free(name);\r
+ return NULL;\r
+ }\r
+ v = PyString_FromStringAndSize(MBname, strlen(MBname));\r
+ if (v == NULL) {\r
+ Py_DECREF(d);\r
+ d = NULL;\r
+ break;\r
+ }\r
+#ifdef Py_USING_UNICODE\r
+ if (arg_is_unicode) {\r
+ PyObject *w;\r
+\r
+ w = PyUnicode_FromEncodedObject(v,\r
+ Py_FileSystemDefaultEncoding,\r
+ "strict");\r
+ if (w != NULL) {\r
+ Py_DECREF(v);\r
+ v = w;\r
+ }\r
+ else {\r
+ /* fall back to the original byte string, as\r
+ discussed in patch #683592 */\r
+ PyErr_Clear();\r
+ }\r
+ }\r
+#endif\r
+ if (PyList_Append(d, v) != 0) {\r
+ Py_DECREF(v);\r
+ Py_DECREF(d);\r
+ d = NULL;\r
+ break;\r
+ }\r
+ Py_DECREF(v);\r
+ }\r
+ Py_BEGIN_ALLOW_THREADS\r
+ closedir(dirp);\r
+ Py_END_ALLOW_THREADS\r
+ PyMem_Free(name);\r
+ if(MBname != NULL) {\r
+ free(MBname);\r
+ }\r
+\r
+ return d;\r
+\r
+} /* end of posix_listdir */\r
+\r
+#ifdef MS_WINDOWS\r
+/* A helper function for abspath on win32 */\r
+static PyObject *\r
+posix__getfullpathname(PyObject *self, PyObject *args)\r
+{\r
+ /* assume encoded strings won't more than double no of chars */\r
+ char inbuf[MAX_PATH*2];\r
+ char *inbufp = inbuf;\r
+ Py_ssize_t insize = sizeof(inbuf);\r
+ char outbuf[MAX_PATH*2];\r
+ char *temp;\r
+\r
+ PyUnicodeObject *po;\r
+ if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {\r
+ Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);\r
+ Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;\r
+ Py_UNICODE *wtemp;\r
+ DWORD result;\r
+ PyObject *v;\r
+ result = GetFullPathNameW(wpath,\r
+ sizeof(woutbuf)/sizeof(woutbuf[0]),\r
+ woutbuf, &wtemp);\r
+ if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {\r
+ woutbufp = malloc(result * sizeof(Py_UNICODE));\r
+ if (!woutbufp)\r
+ return PyErr_NoMemory();\r
+ result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);\r
+ }\r
+ if (result)\r
+ v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));\r
+ else\r
+ v = win32_error_unicode("GetFullPathNameW", wpath);\r
+ if (woutbufp != woutbuf)\r
+ free(woutbufp);\r
+ return v;\r
+ }\r
+ /* Drop the argument parsing error as narrow strings\r
+ are also valid. */\r
+ PyErr_Clear();\r
+\r
+ if (!PyArg_ParseTuple (args, "et#:_getfullpathname",\r
+ Py_FileSystemDefaultEncoding, &inbufp,\r
+ &insize))\r
+ return NULL;\r
+ if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),\r
+ outbuf, &temp))\r
+ return win32_error("GetFullPathName", inbuf);\r
+ if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {\r
+ return PyUnicode_Decode(outbuf, strlen(outbuf),\r
+ Py_FileSystemDefaultEncoding, NULL);\r
+ }\r
+ return PyString_FromString(outbuf);\r
+} /* end of posix__getfullpathname */\r
+#endif /* MS_WINDOWS */\r
+\r
+PyDoc_STRVAR(posix_mkdir__doc__,\r
+"mkdir(path [, mode=0777])\n\n\\r
+Create a directory.");\r
+\r
+static PyObject *\r
+posix_mkdir(PyObject *self, PyObject *args)\r
+{\r
+ int res;\r
+ char *path = NULL;\r
+ int mode = 0777;\r
+\r
+ if (!PyArg_ParseTuple(args, "et|i:mkdir",\r
+ Py_FileSystemDefaultEncoding, &path, &mode))\r
+ return NULL;\r
+ Py_BEGIN_ALLOW_THREADS\r
+ res = mkdir(path, mode);\r
+ Py_END_ALLOW_THREADS\r
+ if (res < 0)\r
+ return posix_error_with_allocated_filename(path);\r
+ PyMem_Free(path);\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+\r
+\r
+/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */\r
+#if defined(HAVE_SYS_RESOURCE_H)\r
+#include <sys/resource.h>\r
+#endif\r
+\r
+\r
+#ifdef HAVE_NICE\r
+PyDoc_STRVAR(posix_nice__doc__,\r
+"nice(inc) -> new_priority\n\n\\r
+Decrease the priority of process by inc and return the new priority.");\r
+\r
+static PyObject *\r
+posix_nice(PyObject *self, PyObject *args)\r
+{\r
+ int increment, value;\r
+\r
+ if (!PyArg_ParseTuple(args, "i:nice", &increment))\r
+ return NULL;\r
+\r
+ /* There are two flavours of 'nice': one that returns the new\r
+ priority (as required by almost all standards out there) and the\r
+ Linux/FreeBSD/BSDI one, which returns '0' on success and advices\r
+ the use of getpriority() to get the new priority.\r
+\r
+ If we are of the nice family that returns the new priority, we\r
+ need to clear errno before the call, and check if errno is filled\r
+ before calling posix_error() on a returnvalue of -1, because the\r
+ -1 may be the actual new priority! */\r
+\r
+ errno = 0;\r
+ value = nice(increment);\r
+#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)\r
+ if (value == 0)\r
+ value = getpriority(PRIO_PROCESS, 0);\r
+#endif\r
+ if (value == -1 && errno != 0)\r
+ /* either nice() or getpriority() returned an error */\r
+ return posix_error();\r
+ return PyInt_FromLong((long) value);\r
+}\r
+#endif /* HAVE_NICE */\r
+\r
+PyDoc_STRVAR(posix_rename__doc__,\r
+"rename(old, new)\n\n\\r
+Rename a file or directory.");\r
+\r
+static PyObject *\r
+posix_rename(PyObject *self, PyObject *args)\r
+{\r
+ return posix_2str(args, "etet:rename", rename);\r
+}\r
+\r
+\r
+PyDoc_STRVAR(posix_rmdir__doc__,\r
+"rmdir(path)\n\n\\r
+Remove a directory.");\r
+\r
+static PyObject *\r
+posix_rmdir(PyObject *self, PyObject *args)\r
+{\r
+ return posix_1str(args, "et:rmdir", rmdir);\r
+}\r
+\r
+\r
+PyDoc_STRVAR(posix_stat__doc__,\r
+"stat(path) -> stat result\n\n\\r
+Perform a stat system call on the given path.");\r
+\r
+static PyObject *\r
+posix_stat(PyObject *self, PyObject *args)\r
+{\r
+ return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);\r
+}\r
+\r
+\r
+#ifdef HAVE_SYSTEM\r
+PyDoc_STRVAR(posix_system__doc__,\r
+"system(command) -> exit_status\n\n\\r
+Execute the command (a string) in a subshell.");\r
+\r
+static PyObject *\r
+posix_system(PyObject *self, PyObject *args)\r
+{\r
+ char *command;\r
+ long sts;\r
+ if (!PyArg_ParseTuple(args, "s:system", &command))\r
+ return NULL;\r
+ Py_BEGIN_ALLOW_THREADS\r
+ sts = system(command);\r
+ Py_END_ALLOW_THREADS\r
+ return PyInt_FromLong(sts);\r
+}\r
+#endif\r
+\r
+\r
+PyDoc_STRVAR(posix_umask__doc__,\r
+"umask(new_mask) -> old_mask\n\n\\r
+Set the current numeric umask and return the previous umask.");\r
+\r
+static PyObject *\r
+posix_umask(PyObject *self, PyObject *args)\r
+{\r
+ int i;\r
+ if (!PyArg_ParseTuple(args, "i:umask", &i))\r
+ return NULL;\r
+ i = (int)umask(i);\r
+ if (i < 0)\r
+ return posix_error();\r
+ return PyInt_FromLong((long)i);\r
+}\r
+\r
+\r
+PyDoc_STRVAR(posix_unlink__doc__,\r
+"unlink(path)\n\n\\r
+Remove a file (same as remove(path)).");\r
+\r
+PyDoc_STRVAR(posix_remove__doc__,\r
+"remove(path)\n\n\\r
+Remove a file (same as unlink(path)).");\r
+\r
+static PyObject *\r
+posix_unlink(PyObject *self, PyObject *args)\r
+{\r
+ return posix_1str(args, "et:remove", unlink);\r
+}\r
+\r
+\r
+static int\r
+extract_time(PyObject *t, time_t* sec, long* usec)\r
+{\r
+ time_t intval;\r
+ if (PyFloat_Check(t)) {\r
+ double tval = PyFloat_AsDouble(t);\r
+ PyObject *intobj = PyNumber_Long(t);\r
+ if (!intobj)\r
+ return -1;\r
+#if SIZEOF_TIME_T > SIZEOF_LONG\r
+ intval = PyInt_AsUnsignedLongLongMask(intobj);\r
+#else\r
+ intval = PyInt_AsLong(intobj);\r
+#endif\r
+ Py_DECREF(intobj);\r
+ if (intval == -1 && PyErr_Occurred())\r
+ return -1;\r
+ *sec = intval;\r
+ *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */\r
+ if (*usec < 0)\r
+ /* If rounding gave us a negative number,\r
+ truncate. */\r
+ *usec = 0;\r
+ return 0;\r
+ }\r
+#if SIZEOF_TIME_T > SIZEOF_LONG\r
+ intval = PyInt_AsUnsignedLongLongMask(t);\r
+#else\r
+ intval = PyInt_AsLong(t);\r
+#endif\r
+ if (intval == -1 && PyErr_Occurred())\r
+ return -1;\r
+ *sec = intval;\r
+ *usec = 0;\r
+ return 0;\r
+}\r
+\r
+PyDoc_STRVAR(posix_utime__doc__,\r
+"utime(path, (atime, mtime))\n\\r
+utime(path, None)\n\n\\r
+Set the access and modified time of the file to the given values. If the\n\\r
+second form is used, set the access and modified times to the current time.");\r
+\r
+static PyObject *\r
+posix_utime(PyObject *self, PyObject *args)\r
+{\r
+ char *path = NULL;\r
+ time_t atime, mtime;\r
+ long ausec, musec;\r
+ int res;\r
+ PyObject* arg;\r
+\r
+#if defined(HAVE_UTIMES)\r
+ struct timeval buf[2];\r
+#define ATIME buf[0].tv_sec\r
+#define MTIME buf[1].tv_sec\r
+#elif defined(HAVE_UTIME_H)\r
+/* XXX should define struct utimbuf instead, above */\r
+ struct utimbuf buf;\r
+#define ATIME buf.actime\r
+#define MTIME buf.modtime\r
+#define UTIME_ARG &buf\r
+#else /* HAVE_UTIMES */\r
+ time_t buf[2];\r
+#define ATIME buf[0]\r
+#define MTIME buf[1]\r
+#define UTIME_ARG buf\r
+#endif /* HAVE_UTIMES */\r
+\r
+\r
+ if (!PyArg_ParseTuple(args, "etO:utime",\r
+ Py_FileSystemDefaultEncoding, &path, &arg))\r
+ return NULL;\r
+ if (arg == Py_None) {\r
+ /* optional time values not given */\r
+ Py_BEGIN_ALLOW_THREADS\r
+ res = utime(path, NULL);\r
+ Py_END_ALLOW_THREADS\r
+ }\r
+ else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "utime() arg 2 must be a tuple (atime, mtime)");\r
+ PyMem_Free(path);\r
+ return NULL;\r
+ }\r
+ else {\r
+ if (extract_time(PyTuple_GET_ITEM(arg, 0),\r
+ &atime, &ausec) == -1) {\r
+ PyMem_Free(path);\r
+ return NULL;\r
+ }\r
+ if (extract_time(PyTuple_GET_ITEM(arg, 1),\r
+ &mtime, &musec) == -1) {\r
+ PyMem_Free(path);\r
+ return NULL;\r
+ }\r
+ ATIME = atime;\r
+ MTIME = mtime;\r
+#ifdef HAVE_UTIMES\r
+ buf[0].tv_usec = ausec;\r
+ buf[1].tv_usec = musec;\r
+ Py_BEGIN_ALLOW_THREADS\r
+ res = utimes(path, buf);\r
+ Py_END_ALLOW_THREADS\r
+#else\r
+ Py_BEGIN_ALLOW_THREADS\r
+ res = utime(path, UTIME_ARG);\r
+ Py_END_ALLOW_THREADS\r
+#endif /* HAVE_UTIMES */\r
+ }\r
+ if (res < 0) {\r
+ return posix_error_with_allocated_filename(path);\r
+ }\r
+ PyMem_Free(path);\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+#undef UTIME_ARG\r
+#undef ATIME\r
+#undef MTIME\r
+}\r
+\r
+\r
+/* Process operations */\r
+\r
+PyDoc_STRVAR(posix__exit__doc__,\r
+"_exit(status)\n\n\\r
+Exit to the system with specified status, without normal exit processing.");\r
+\r
+static PyObject *\r
+posix__exit(PyObject *self, PyObject *args)\r
+{\r
+ int sts;\r
+ if (!PyArg_ParseTuple(args, "i:_exit", &sts))\r
+ return NULL;\r
+ _Exit(sts);\r
+ return NULL; /* Make gcc -Wall happy */\r
+}\r
+\r
+#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)\r
+static void\r
+free_string_array(char **array, Py_ssize_t count)\r
+{\r
+ Py_ssize_t i;\r
+ for (i = 0; i < count; i++)\r
+ PyMem_Free(array[i]);\r
+ PyMem_DEL(array);\r
+}\r
+#endif\r
+\r
+\r
+#ifdef HAVE_EXECV\r
+PyDoc_STRVAR(posix_execv__doc__,\r
+"execv(path, args)\n\n\\r
+Execute an executable path with arguments, replacing current process.\n\\r
+\n\\r
+ path: path of executable file\n\\r
+ args: tuple or list of strings");\r
+\r
+static PyObject *\r
+posix_execv(PyObject *self, PyObject *args)\r
+{\r
+ char *path;\r
+ PyObject *argv;\r
+ char **argvlist;\r
+ Py_ssize_t i, argc;\r
+ PyObject *(*getitem)(PyObject *, Py_ssize_t);\r
+\r
+ /* execv has two arguments: (path, argv), where\r
+ argv is a list or tuple of strings. */\r
+\r
+ if (!PyArg_ParseTuple(args, "etO:execv",\r
+ Py_FileSystemDefaultEncoding,\r
+ &path, &argv))\r
+ return NULL;\r
+ if (PyList_Check(argv)) {\r
+ argc = PyList_Size(argv);\r
+ getitem = PyList_GetItem;\r
+ }\r
+ else if (PyTuple_Check(argv)) {\r
+ argc = PyTuple_Size(argv);\r
+ getitem = PyTuple_GetItem;\r
+ }\r
+ else {\r
+ PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");\r
+ PyMem_Free(path);\r
+ return NULL;\r
+ }\r
+ if (argc < 1) {\r
+ PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");\r
+ PyMem_Free(path);\r
+ return NULL;\r
+ }\r
+\r
+ argvlist = PyMem_NEW(char *, argc+1);\r
+ if (argvlist == NULL) {\r
+ PyMem_Free(path);\r
+ return PyErr_NoMemory();\r
+ }\r
+ for (i = 0; i < argc; i++) {\r
+ if (!PyArg_Parse((*getitem)(argv, i), "et",\r
+ Py_FileSystemDefaultEncoding,\r
+ &argvlist[i])) {\r
+ free_string_array(argvlist, i);\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "execv() arg 2 must contain only strings");\r
+ PyMem_Free(path);\r
+ return NULL;\r
+\r
+ }\r
+ }\r
+ argvlist[argc] = NULL;\r
+\r
+ execv(path, argvlist);\r
+\r
+ /* If we get here it's definitely an error */\r
+\r
+ free_string_array(argvlist, argc);\r
+ PyMem_Free(path);\r
+ return posix_error();\r
+}\r
+\r
+\r
+PyDoc_STRVAR(posix_execve__doc__,\r
+"execve(path, args, env)\n\n\\r
+Execute a path with arguments and environment, replacing current process.\n\\r
+\n\\r
+ path: path of executable file\n\\r
+ args: tuple or list of arguments\n\\r
+ env: dictionary of strings mapping to strings");\r
+\r
+static PyObject *\r
+posix_execve(PyObject *self, PyObject *args)\r
+{\r
+ char *path;\r
+ PyObject *argv, *env;\r
+ char **argvlist;\r
+ char **envlist;\r
+ PyObject *key, *val, *keys=NULL, *vals=NULL;\r
+ Py_ssize_t i, pos, argc, envc;\r
+ PyObject *(*getitem)(PyObject *, Py_ssize_t);\r
+ Py_ssize_t lastarg = 0;\r
+\r
+ /* execve has three arguments: (path, argv, env), where\r
+ argv is a list or tuple of strings and env is a dictionary\r
+ like posix.environ. */\r
+\r
+ if (!PyArg_ParseTuple(args, "etOO:execve",\r
+ Py_FileSystemDefaultEncoding,\r
+ &path, &argv, &env))\r
+ return NULL;\r
+ if (PyList_Check(argv)) {\r
+ argc = PyList_Size(argv);\r
+ getitem = PyList_GetItem;\r
+ }\r
+ else if (PyTuple_Check(argv)) {\r
+ argc = PyTuple_Size(argv);\r
+ getitem = PyTuple_GetItem;\r
+ }\r
+ else {\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "execve() arg 2 must be a tuple or list");\r
+ goto fail_0;\r
+ }\r
+ if (!PyMapping_Check(env)) {\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "execve() arg 3 must be a mapping object");\r
+ goto fail_0;\r
+ }\r
+\r
+ argvlist = PyMem_NEW(char *, argc+1);\r
+ if (argvlist == NULL) {\r
+ PyErr_NoMemory();\r
+ goto fail_0;\r
+ }\r
+ for (i = 0; i < argc; i++) {\r
+ if (!PyArg_Parse((*getitem)(argv, i),\r
+ "et;execve() arg 2 must contain only strings",\r
+ Py_FileSystemDefaultEncoding,\r
+ &argvlist[i]))\r
+ {\r
+ lastarg = i;\r
+ goto fail_1;\r
+ }\r
+ }\r
+ lastarg = argc;\r
+ argvlist[argc] = NULL;\r
+\r
+ i = PyMapping_Size(env);\r
+ if (i < 0)\r
+ goto fail_1;\r
+ envlist = PyMem_NEW(char *, i + 1);\r
+ if (envlist == NULL) {\r
+ PyErr_NoMemory();\r
+ goto fail_1;\r
+ }\r
+ envc = 0;\r
+ keys = PyMapping_Keys(env);\r
+ vals = PyMapping_Values(env);\r
+ if (!keys || !vals)\r
+ goto fail_2;\r
+ if (!PyList_Check(keys) || !PyList_Check(vals)) {\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "execve(): env.keys() or env.values() is not a list");\r
+ goto fail_2;\r
+ }\r
+\r
+ for (pos = 0; pos < i; pos++) {\r
+ char *p, *k, *v;\r
+ size_t len;\r
+\r
+ key = PyList_GetItem(keys, pos);\r
+ val = PyList_GetItem(vals, pos);\r
+ if (!key || !val)\r
+ goto fail_2;\r
+\r
+ if (!PyArg_Parse(\r
+ key,\r
+ "s;execve() arg 3 contains a non-string key",\r
+ &k) ||\r
+ !PyArg_Parse(\r
+ val,\r
+ "s;execve() arg 3 contains a non-string value",\r
+ &v))\r
+ {\r
+ goto fail_2;\r
+ }\r
+\r
+#if defined(PYOS_OS2)\r
+ /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */\r
+ if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {\r
+#endif\r
+ len = PyString_Size(key) + PyString_Size(val) + 2;\r
+ p = PyMem_NEW(char, len);\r
+ if (p == NULL) {\r
+ PyErr_NoMemory();\r
+ goto fail_2;\r
+ }\r
+ PyOS_snprintf(p, len, "%s=%s", k, v);\r
+ envlist[envc++] = p;\r
+#if defined(PYOS_OS2)\r
+ }\r
+#endif\r
+ }\r
+ envlist[envc] = 0;\r
+\r
+ execve(path, argvlist, envlist);\r
+\r
+ /* If we get here it's definitely an error */\r
+\r
+ (void) posix_error();\r
+\r
+ fail_2:\r
+ while (--envc >= 0)\r
+ PyMem_DEL(envlist[envc]);\r
+ PyMem_DEL(envlist);\r
+ fail_1:\r
+ free_string_array(argvlist, lastarg);\r
+ Py_XDECREF(vals);\r
+ Py_XDECREF(keys);\r
+ fail_0:\r
+ PyMem_Free(path);\r
+ return NULL;\r
+}\r
+#endif /* HAVE_EXECV */\r
+\r
+\r
+#ifdef HAVE_SPAWNV\r
+PyDoc_STRVAR(posix_spawnv__doc__,\r
+"spawnv(mode, path, args)\n\n\\r
+Execute the program 'path' in a new process.\n\\r
+\n\\r
+ mode: mode of process creation\n\\r
+ path: path of executable file\n\\r
+ args: tuple or list of strings");\r
+\r
+static PyObject *\r
+posix_spawnv(PyObject *self, PyObject *args)\r
+{\r
+ char *path;\r
+ PyObject *argv;\r
+ char **argvlist;\r
+ int mode, i;\r
+ Py_ssize_t argc;\r
+ Py_intptr_t spawnval;\r
+ PyObject *(*getitem)(PyObject *, Py_ssize_t);\r
+\r
+ /* spawnv has three arguments: (mode, path, argv), where\r
+ argv is a list or tuple of strings. */\r
+\r
+ if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,\r
+ Py_FileSystemDefaultEncoding,\r
+ &path, &argv))\r
+ return NULL;\r
+ if (PyList_Check(argv)) {\r
+ argc = PyList_Size(argv);\r
+ getitem = PyList_GetItem;\r
+ }\r
+ else if (PyTuple_Check(argv)) {\r
+ argc = PyTuple_Size(argv);\r
+ getitem = PyTuple_GetItem;\r
+ }\r
+ else {\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "spawnv() arg 2 must be a tuple or list");\r
+ PyMem_Free(path);\r
+ return NULL;\r
+ }\r
+\r
+ argvlist = PyMem_NEW(char *, argc+1);\r
+ if (argvlist == NULL) {\r
+ PyMem_Free(path);\r
+ return PyErr_NoMemory();\r
+ }\r
+ for (i = 0; i < argc; i++) {\r
+ if (!PyArg_Parse((*getitem)(argv, i), "et",\r
+ Py_FileSystemDefaultEncoding,\r
+ &argvlist[i])) {\r
+ free_string_array(argvlist, i);\r
+ PyErr_SetString(\r
+ PyExc_TypeError,\r
+ "spawnv() arg 2 must contain only strings");\r
+ PyMem_Free(path);\r
+ return NULL;\r
+ }\r
+ }\r
+ argvlist[argc] = NULL;\r
+\r
+#if defined(PYOS_OS2) && defined(PYCC_GCC)\r
+ Py_BEGIN_ALLOW_THREADS\r
+ spawnval = spawnv(mode, path, argvlist);\r
+ Py_END_ALLOW_THREADS\r
+#else\r
+ if (mode == _OLD_P_OVERLAY)\r
+ mode = _P_OVERLAY;\r
+\r
+ Py_BEGIN_ALLOW_THREADS\r
+ spawnval = _spawnv(mode, path, argvlist);\r
+ Py_END_ALLOW_THREADS\r
+#endif\r
+\r
+ free_string_array(argvlist, argc);\r
+ PyMem_Free(path);\r
+\r
+ if (spawnval == -1)\r
+ return posix_error();\r
+ else\r
+#if SIZEOF_LONG == SIZEOF_VOID_P\r
+ return Py_BuildValue("l", (long) spawnval);\r
+#else\r
+ return Py_BuildValue("L", (PY_LONG_LONG) spawnval);\r
+#endif\r
+}\r
+\r
+\r
+PyDoc_STRVAR(posix_spawnve__doc__,\r
+"spawnve(mode, path, args, env)\n\n\\r
+Execute the program 'path' in a new process.\n\\r
+\n\\r
+ mode: mode of process creation\n\\r
+ path: path of executable file\n\\r
+ args: tuple or list of arguments\n\\r
+ env: dictionary of strings mapping to strings");\r
+\r
+static PyObject *\r
+posix_spawnve(PyObject *self, PyObject *args)\r
+{\r
+ char *path;\r
+ PyObject *argv, *env;\r
+ char **argvlist;\r
+ char **envlist;\r
+ PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;\r
+ int mode, pos, envc;\r
+ Py_ssize_t argc, i;\r
+ Py_intptr_t spawnval;\r
+ PyObject *(*getitem)(PyObject *, Py_ssize_t);\r
+ Py_ssize_t lastarg = 0;\r
+\r
+ /* spawnve has four arguments: (mode, path, argv, env), where\r
+ argv is a list or tuple of strings and env is a dictionary\r
+ like posix.environ. */\r
+\r
+ if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,\r
+ Py_FileSystemDefaultEncoding,\r
+ &path, &argv, &env))\r
+ return NULL;\r
+ if (PyList_Check(argv)) {\r
+ argc = PyList_Size(argv);\r
+ getitem = PyList_GetItem;\r
+ }\r
+ else if (PyTuple_Check(argv)) {\r
+ argc = PyTuple_Size(argv);\r
+ getitem = PyTuple_GetItem;\r
+ }\r
+ else {\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "spawnve() arg 2 must be a tuple or list");\r
+ goto fail_0;\r
+ }\r
+ if (!PyMapping_Check(env)) {\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "spawnve() arg 3 must be a mapping object");\r
+ goto fail_0;\r
+ }\r
+\r
+ argvlist = PyMem_NEW(char *, argc+1);\r
+ if (argvlist == NULL) {\r
+ PyErr_NoMemory();\r
+ goto fail_0;\r
+ }\r
+ for (i = 0; i < argc; i++) {\r
+ if (!PyArg_Parse((*getitem)(argv, i),\r
+ "et;spawnve() arg 2 must contain only strings",\r
+ Py_FileSystemDefaultEncoding,\r
+ &argvlist[i]))\r
+ {\r
+ lastarg = i;\r
+ goto fail_1;\r
+ }\r
+ }\r
+ lastarg = argc;\r
+ argvlist[argc] = NULL;\r
+\r
+ i = PyMapping_Size(env);\r
+ if (i < 0)\r
+ goto fail_1;\r
+ envlist = PyMem_NEW(char *, i + 1);\r
+ if (envlist == NULL) {\r
+ PyErr_NoMemory();\r
+ goto fail_1;\r
+ }\r
+ envc = 0;\r
+ keys = PyMapping_Keys(env);\r
+ vals = PyMapping_Values(env);\r
+ if (!keys || !vals)\r
+ goto fail_2;\r
+ if (!PyList_Check(keys) || !PyList_Check(vals)) {\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "spawnve(): env.keys() or env.values() is not a list");\r
+ goto fail_2;\r
+ }\r
+\r
+ for (pos = 0; pos < i; pos++) {\r
+ char *p, *k, *v;\r
+ size_t len;\r
+\r
+ key = PyList_GetItem(keys, pos);\r
+ val = PyList_GetItem(vals, pos);\r
+ if (!key || !val)\r
+ goto fail_2;\r
+\r
+ if (!PyArg_Parse(\r
+ key,\r
+ "s;spawnve() arg 3 contains a non-string key",\r
+ &k) ||\r
+ !PyArg_Parse(\r
+ val,\r
+ "s;spawnve() arg 3 contains a non-string value",\r
+ &v))\r
+ {\r
+ goto fail_2;\r
+ }\r
+ len = PyString_Size(key) + PyString_Size(val) + 2;\r
+ p = PyMem_NEW(char, len);\r
+ if (p == NULL) {\r
+ PyErr_NoMemory();\r
+ goto fail_2;\r
+ }\r
+ PyOS_snprintf(p, len, "%s=%s", k, v);\r
+ envlist[envc++] = p;\r
+ }\r
+ envlist[envc] = 0;\r
+\r
+#if defined(PYOS_OS2) && defined(PYCC_GCC)\r
+ Py_BEGIN_ALLOW_THREADS\r
+ spawnval = spawnve(mode, path, argvlist, envlist);\r
+ Py_END_ALLOW_THREADS\r
+#else\r
+ if (mode == _OLD_P_OVERLAY)\r
+ mode = _P_OVERLAY;\r
+\r
+ Py_BEGIN_ALLOW_THREADS\r
+ spawnval = _spawnve(mode, path, argvlist, envlist);\r
+ Py_END_ALLOW_THREADS\r
+#endif\r
+\r
+ if (spawnval == -1)\r
+ (void) posix_error();\r
+ else\r
+#if SIZEOF_LONG == SIZEOF_VOID_P\r
+ res = Py_BuildValue("l", (long) spawnval);\r
+#else\r
+ res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);\r
+#endif\r
+\r
+ fail_2:\r
+ while (--envc >= 0)\r
+ PyMem_DEL(envlist[envc]);\r
+ PyMem_DEL(envlist);\r
+ fail_1:\r
+ free_string_array(argvlist, lastarg);\r
+ Py_XDECREF(vals);\r
+ Py_XDECREF(keys);\r
+ fail_0:\r
+ PyMem_Free(path);\r
+ return res;\r
+}\r
+\r
+/* OS/2 supports spawnvp & spawnvpe natively */\r
+#if defined(PYOS_OS2)\r
+PyDoc_STRVAR(posix_spawnvp__doc__,\r
+"spawnvp(mode, file, args)\n\n\\r
+Execute the program 'file' in a new process, using the environment\n\\r
+search path to find the file.\n\\r
+\n\\r
+ mode: mode of process creation\n\\r
+ file: executable file name\n\\r
+ args: tuple or list of strings");\r
+\r
+static PyObject *\r
+posix_spawnvp(PyObject *self, PyObject *args)\r
+{\r
+ char *path;\r
+ PyObject *argv;\r
+ char **argvlist;\r
+ int mode, i, argc;\r
+ Py_intptr_t spawnval;\r
+ PyObject *(*getitem)(PyObject *, Py_ssize_t);\r
+\r
+ /* spawnvp has three arguments: (mode, path, argv), where\r
+ argv is a list or tuple of strings. */\r
+\r
+ if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,\r
+ Py_FileSystemDefaultEncoding,\r
+ &path, &argv))\r
+ return NULL;\r
+ if (PyList_Check(argv)) {\r
+ argc = PyList_Size(argv);\r
+ getitem = PyList_GetItem;\r
+ }\r
+ else if (PyTuple_Check(argv)) {\r
+ argc = PyTuple_Size(argv);\r
+ getitem = PyTuple_GetItem;\r
+ }\r
+ else {\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "spawnvp() arg 2 must be a tuple or list");\r
+ PyMem_Free(path);\r
+ return NULL;\r
+ }\r
+\r
+ argvlist = PyMem_NEW(char *, argc+1);\r
+ if (argvlist == NULL) {\r
+ PyMem_Free(path);\r
+ return PyErr_NoMemory();\r
+ }\r
+ for (i = 0; i < argc; i++) {\r
+ if (!PyArg_Parse((*getitem)(argv, i), "et",\r
+ Py_FileSystemDefaultEncoding,\r
+ &argvlist[i])) {\r
+ free_string_array(argvlist, i);\r
+ PyErr_SetString(\r
+ PyExc_TypeError,\r
+ "spawnvp() arg 2 must contain only strings");\r
+ PyMem_Free(path);\r
+ return NULL;\r
+ }\r
+ }\r
+ argvlist[argc] = NULL;\r
+\r
+ Py_BEGIN_ALLOW_THREADS\r
+#if defined(PYCC_GCC)\r
+ spawnval = spawnvp(mode, path, argvlist);\r
+#else\r
+ spawnval = _spawnvp(mode, path, argvlist);\r
+#endif\r
+ Py_END_ALLOW_THREADS\r
+\r
+ free_string_array(argvlist, argc);\r
+ PyMem_Free(path);\r
+\r
+ if (spawnval == -1)\r
+ return posix_error();\r
+ else\r
+ return Py_BuildValue("l", (long) spawnval);\r
+}\r
+\r
+\r
+PyDoc_STRVAR(posix_spawnvpe__doc__,\r
+"spawnvpe(mode, file, args, env)\n\n\\r
+Execute the program 'file' in a new process, using the environment\n\\r
+search path to find the file.\n\\r
+\n\\r
+ mode: mode of process creation\n\\r
+ file: executable file name\n\\r
+ args: tuple or list of arguments\n\\r
+ env: dictionary of strings mapping to strings");\r
+\r
+static PyObject *\r
+posix_spawnvpe(PyObject *self, PyObject *args)\r
+{\r
+ char *path;\r
+ PyObject *argv, *env;\r
+ char **argvlist;\r
+ char **envlist;\r
+ PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;\r
+ int mode, i, pos, argc, envc;\r
+ Py_intptr_t spawnval;\r
+ PyObject *(*getitem)(PyObject *, Py_ssize_t);\r
+ int lastarg = 0;\r
+\r
+ /* spawnvpe has four arguments: (mode, path, argv, env), where\r
+ argv is a list or tuple of strings and env is a dictionary\r
+ like posix.environ. */\r
+\r
+ if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,\r
+ Py_FileSystemDefaultEncoding,\r
+ &path, &argv, &env))\r
+ return NULL;\r
+ if (PyList_Check(argv)) {\r
+ argc = PyList_Size(argv);\r
+ getitem = PyList_GetItem;\r
+ }\r
+ else if (PyTuple_Check(argv)) {\r
+ argc = PyTuple_Size(argv);\r
+ getitem = PyTuple_GetItem;\r
+ }\r
+ else {\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "spawnvpe() arg 2 must be a tuple or list");\r
+ goto fail_0;\r
+ }\r
+ if (!PyMapping_Check(env)) {\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "spawnvpe() arg 3 must be a mapping object");\r
+ goto fail_0;\r
+ }\r
+\r
+ argvlist = PyMem_NEW(char *, argc+1);\r
+ if (argvlist == NULL) {\r
+ PyErr_NoMemory();\r
+ goto fail_0;\r
+ }\r
+ for (i = 0; i < argc; i++) {\r
+ if (!PyArg_Parse((*getitem)(argv, i),\r
+ "et;spawnvpe() arg 2 must contain only strings",\r
+ Py_FileSystemDefaultEncoding,\r
+ &argvlist[i]))\r
+ {\r
+ lastarg = i;\r
+ goto fail_1;\r
+ }\r
+ }\r
+ lastarg = argc;\r
+ argvlist[argc] = NULL;\r
+\r
+ i = PyMapping_Size(env);\r
+ if (i < 0)\r
+ goto fail_1;\r
+ envlist = PyMem_NEW(char *, i + 1);\r
+ if (envlist == NULL) {\r
+ PyErr_NoMemory();\r
+ goto fail_1;\r
+ }\r
+ envc = 0;\r
+ keys = PyMapping_Keys(env);\r
+ vals = PyMapping_Values(env);\r
+ if (!keys || !vals)\r
+ goto fail_2;\r
+ if (!PyList_Check(keys) || !PyList_Check(vals)) {\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "spawnvpe(): env.keys() or env.values() is not a list");\r
+ goto fail_2;\r
+ }\r
+\r
+ for (pos = 0; pos < i; pos++) {\r
+ char *p, *k, *v;\r
+ size_t len;\r
+\r
+ key = PyList_GetItem(keys, pos);\r
+ val = PyList_GetItem(vals, pos);\r
+ if (!key || !val)\r
+ goto fail_2;\r
+\r
+ if (!PyArg_Parse(\r
+ key,\r
+ "s;spawnvpe() arg 3 contains a non-string key",\r
+ &k) ||\r
+ !PyArg_Parse(\r
+ val,\r
+ "s;spawnvpe() arg 3 contains a non-string value",\r
+ &v))\r
+ {\r
+ goto fail_2;\r
+ }\r
+ len = PyString_Size(key) + PyString_Size(val) + 2;\r
+ p = PyMem_NEW(char, len);\r
+ if (p == NULL) {\r
+ PyErr_NoMemory();\r
+ goto fail_2;\r
+ }\r
+ PyOS_snprintf(p, len, "%s=%s", k, v);\r
+ envlist[envc++] = p;\r
+ }\r
+ envlist[envc] = 0;\r
+\r
+ Py_BEGIN_ALLOW_THREADS\r
+#if defined(PYCC_GCC)\r
+ spawnval = spawnvpe(mode, path, argvlist, envlist);\r
+#else\r
+ spawnval = _spawnvpe(mode, path, argvlist, envlist);\r
+#endif\r
+ Py_END_ALLOW_THREADS\r
+\r
+ if (spawnval == -1)\r
+ (void) posix_error();\r
+ else\r
+ res = Py_BuildValue("l", (long) spawnval);\r
+\r
+ fail_2:\r
+ while (--envc >= 0)\r
+ PyMem_DEL(envlist[envc]);\r
+ PyMem_DEL(envlist);\r
+ fail_1:\r
+ free_string_array(argvlist, lastarg);\r
+ Py_XDECREF(vals);\r
+ Py_XDECREF(keys);\r
+ fail_0:\r
+ PyMem_Free(path);\r
+ return res;\r
+}\r
+#endif /* PYOS_OS2 */\r
+#endif /* HAVE_SPAWNV */\r
+\r
+\r
+#ifdef HAVE_FORK1\r
+PyDoc_STRVAR(posix_fork1__doc__,\r
+"fork1() -> pid\n\n\\r
+Fork a child process with a single multiplexed (i.e., not bound) thread.\n\\r
+\n\\r
+Return 0 to child process and PID of child to parent process.");\r
+\r
+static PyObject *\r
+posix_fork1(PyObject *self, PyObject *noargs)\r
+{\r
+ pid_t pid;\r
+ int result = 0;\r
+ _PyImport_AcquireLock();\r
+ pid = fork1();\r
+ if (pid == 0) {\r
+ /* child: this clobbers and resets the import lock. */\r
+ PyOS_AfterFork();\r
+ } else {\r
+ /* parent: release the import lock. */\r
+ result = _PyImport_ReleaseLock();\r
+ }\r
+ if (pid == -1)\r
+ return posix_error();\r
+ if (result < 0) {\r
+ /* Don't clobber the OSError if the fork failed. */\r
+ PyErr_SetString(PyExc_RuntimeError,\r
+ "not holding the import lock");\r
+ return NULL;\r
+ }\r
+ return PyLong_FromPid(pid);\r
+}\r
+#endif\r
+\r
+\r
+#ifdef HAVE_FORK\r
+PyDoc_STRVAR(posix_fork__doc__,\r
+"fork() -> pid\n\n\\r
+Fork a child process.\n\\r
+Return 0 to child process and PID of child to parent process.");\r
+\r
+static PyObject *\r
+posix_fork(PyObject *self, PyObject *noargs)\r
+{\r
+ pid_t pid;\r
+ int result = 0;\r
+ _PyImport_AcquireLock();\r
+ pid = fork();\r
+ if (pid == 0) {\r
+ /* child: this clobbers and resets the import lock. */\r
+ PyOS_AfterFork();\r
+ } else {\r
+ /* parent: release the import lock. */\r
+ result = _PyImport_ReleaseLock();\r
+ }\r
+ if (pid == -1)\r
+ return posix_error();\r
+ if (result < 0) {\r
+ /* Don't clobber the OSError if the fork failed. */\r
+ PyErr_SetString(PyExc_RuntimeError,\r
+ "not holding the import lock");\r
+ return NULL;\r
+ }\r
+ return PyLong_FromPid(pid);\r
+}\r
+#endif\r
+\r
+/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */\r
+/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */\r
+#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)\r
+#define DEV_PTY_FILE "/dev/ptc"\r
+#define HAVE_DEV_PTMX\r
+#else\r
+#define DEV_PTY_FILE "/dev/ptmx"\r
+#endif\r
+\r
+#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)\r
+#ifdef HAVE_PTY_H\r
+#include <pty.h>\r
+#else\r
+#ifdef HAVE_LIBUTIL_H\r
+#include <libutil.h>\r
+#else\r
+#ifdef HAVE_UTIL_H\r
+#include <util.h>\r
+#endif /* HAVE_UTIL_H */\r
+#endif /* HAVE_LIBUTIL_H */\r
+#endif /* HAVE_PTY_H */\r
+#ifdef HAVE_STROPTS_H\r
+#include <stropts.h>\r
+#endif\r
+#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */\r
+\r
+#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)\r
+PyDoc_STRVAR(posix_openpty__doc__,\r
+"openpty() -> (master_fd, slave_fd)\n\n\\r
+Open a pseudo-terminal, returning open fd's for both master and slave end.\n");\r
+\r
+static PyObject *\r
+posix_openpty(PyObject *self, PyObject *noargs)\r
+{\r
+ int master_fd, slave_fd;\r
+#ifndef HAVE_OPENPTY\r
+ char * slave_name;\r
+#endif\r
+#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)\r
+ PyOS_sighandler_t sig_saved;\r
+#ifdef sun\r
+ extern char *ptsname(int fildes);\r
+#endif\r
+#endif\r
+\r
+#ifdef HAVE_OPENPTY\r
+ if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)\r
+ return posix_error();\r
+#elif defined(HAVE__GETPTY)\r
+ slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);\r
+ if (slave_name == NULL)\r
+ return posix_error();\r
+\r
+ slave_fd = open(slave_name, O_RDWR);\r
+ if (slave_fd < 0)\r
+ return posix_error();\r
+#else\r
+ master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */\r
+ if (master_fd < 0)\r
+ return posix_error();\r
+ sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);\r
+ /* change permission of slave */\r
+ if (grantpt(master_fd) < 0) {\r
+ PyOS_setsig(SIGCHLD, sig_saved);\r
+ return posix_error();\r
+ }\r
+ /* unlock slave */\r
+ if (unlockpt(master_fd) < 0) {\r
+ PyOS_setsig(SIGCHLD, sig_saved);\r
+ return posix_error();\r
+ }\r
+ PyOS_setsig(SIGCHLD, sig_saved);\r
+ slave_name = ptsname(master_fd); /* get name of slave */\r
+ if (slave_name == NULL)\r
+ return posix_error();\r
+ slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */\r
+ if (slave_fd < 0)\r
+ return posix_error();\r
+#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)\r
+ ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */\r
+ ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */\r
+#ifndef __hpux\r
+ ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */\r
+#endif /* __hpux */\r
+#endif /* HAVE_CYGWIN */\r
+#endif /* HAVE_OPENPTY */\r
+\r
+ return Py_BuildValue("(ii)", master_fd, slave_fd);\r
+\r
+}\r
+#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */\r
+\r
+#ifdef HAVE_FORKPTY\r
+PyDoc_STRVAR(posix_forkpty__doc__,\r
+"forkpty() -> (pid, master_fd)\n\n\\r
+Fork a new process with a new pseudo-terminal as controlling tty.\n\n\\r
+Like fork(), return 0 as pid to child process, and PID of child to parent.\n\\r
+To both, return fd of newly opened pseudo-terminal.\n");\r
+\r
+static PyObject *\r
+posix_forkpty(PyObject *self, PyObject *noargs)\r
+{\r
+ int master_fd = -1, result = 0;\r
+ pid_t pid;\r
+\r
+ _PyImport_AcquireLock();\r
+ pid = forkpty(&master_fd, NULL, NULL, NULL);\r
+ if (pid == 0) {\r
+ /* child: this clobbers and resets the import lock. */\r
+ PyOS_AfterFork();\r
+ } else {\r
+ /* parent: release the import lock. */\r
+ result = _PyImport_ReleaseLock();\r
+ }\r
+ if (pid == -1)\r
+ return posix_error();\r
+ if (result < 0) {\r
+ /* Don't clobber the OSError if the fork failed. */\r
+ PyErr_SetString(PyExc_RuntimeError,\r
+ "not holding the import lock");\r
+ return NULL;\r
+ }\r
+ return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);\r
+}\r
+#endif\r
+\r
+#ifdef HAVE_GETEGID\r
+PyDoc_STRVAR(posix_getegid__doc__,\r
+"getegid() -> egid\n\n\\r
+Return the current process's effective group id.");\r
+\r
+static PyObject *\r
+posix_getegid(PyObject *self, PyObject *noargs)\r
+{\r
+ return PyInt_FromLong((long)getegid());\r
+}\r
+#endif\r
+\r
+\r
+#ifdef HAVE_GETEUID\r
+PyDoc_STRVAR(posix_geteuid__doc__,\r
+"geteuid() -> euid\n\n\\r
+Return the current process's effective user id.");\r
+\r
+static PyObject *\r
+posix_geteuid(PyObject *self, PyObject *noargs)\r
+{\r
+ return PyInt_FromLong((long)geteuid());\r
+}\r
+#endif\r
+\r
+\r
+#ifdef HAVE_GETGID\r
+PyDoc_STRVAR(posix_getgid__doc__,\r
+"getgid() -> gid\n\n\\r
+Return the current process's group id.");\r
+\r
+static PyObject *\r
+posix_getgid(PyObject *self, PyObject *noargs)\r
+{\r
+ return PyInt_FromLong((long)getgid());\r
+}\r
+#endif\r
+\r
+\r
+PyDoc_STRVAR(posix_getpid__doc__,\r
+"getpid() -> pid\n\n\\r
+Return the current process id");\r
+\r
+static PyObject *\r
+posix_getpid(PyObject *self, PyObject *noargs)\r
+{\r
+ return PyLong_FromPid(getpid());\r
+}\r
+\r
+\r
+#ifdef HAVE_GETGROUPS\r
+PyDoc_STRVAR(posix_getgroups__doc__,\r
+"getgroups() -> list of group IDs\n\n\\r
+Return list of supplemental group IDs for the process.");\r
+\r
+static PyObject *\r
+posix_getgroups(PyObject *self, PyObject *noargs)\r
+{\r
+ PyObject *result = NULL;\r
+\r
+#ifdef NGROUPS_MAX\r
+#define MAX_GROUPS NGROUPS_MAX\r
+#else\r
+ /* defined to be 16 on Solaris7, so this should be a small number */\r
+#define MAX_GROUPS 64\r
+#endif\r
+ gid_t grouplist[MAX_GROUPS];\r
+\r
+ /* On MacOSX getgroups(2) can return more than MAX_GROUPS results\r
+ * This is a helper variable to store the intermediate result when\r
+ * that happens.\r
+ *\r
+ * To keep the code readable the OSX behaviour is unconditional,\r
+ * according to the POSIX spec this should be safe on all unix-y\r
+ * systems.\r
+ */\r
+ gid_t* alt_grouplist = grouplist;\r
+ int n;\r
+\r
+ n = getgroups(MAX_GROUPS, grouplist);\r
+ if (n < 0) {\r
+ if (errno == EINVAL) {\r
+ n = getgroups(0, NULL);\r
+ if (n == -1) {\r
+ return posix_error();\r
+ }\r
+ if (n == 0) {\r
+ /* Avoid malloc(0) */\r
+ alt_grouplist = grouplist;\r
+ } else {\r
+ alt_grouplist = PyMem_Malloc(n * sizeof(gid_t));\r
+ if (alt_grouplist == NULL) {\r
+ errno = EINVAL;\r
+ return posix_error();\r
+ }\r
+ n = getgroups(n, alt_grouplist);\r
+ if (n == -1) {\r
+ PyMem_Free(alt_grouplist);\r
+ return posix_error();\r
+ }\r
+ }\r
+ } else {\r
+ return posix_error();\r
+ }\r
+ }\r
+ result = PyList_New(n);\r
+ if (result != NULL) {\r
+ int i;\r
+ for (i = 0; i < n; ++i) {\r
+ PyObject *o = PyInt_FromLong((long)alt_grouplist[i]);\r
+ if (o == NULL) {\r
+ Py_DECREF(result);\r
+ result = NULL;\r
+ break;\r
+ }\r
+ PyList_SET_ITEM(result, i, o);\r
+ }\r
+ }\r
+\r
+ if (alt_grouplist != grouplist) {\r
+ PyMem_Free(alt_grouplist);\r
+ }\r
+\r
+ return result;\r
+}\r
+#endif\r
+\r
+#ifdef HAVE_INITGROUPS\r
+PyDoc_STRVAR(posix_initgroups__doc__,\r
+"initgroups(username, gid) -> None\n\n\\r
+Call the system initgroups() to initialize the group access list with all of\n\\r
+the groups of which the specified username is a member, plus the specified\n\\r
+group id.");\r
+\r
+static PyObject *\r
+posix_initgroups(PyObject *self, PyObject *args)\r
+{\r
+ char *username;\r
+ long gid;\r
+\r
+ if (!PyArg_ParseTuple(args, "sl:initgroups", &username, &gid))\r
+ return NULL;\r
+\r
+ if (initgroups(username, (gid_t) gid) == -1)\r
+ return PyErr_SetFromErrno(PyExc_OSError);\r
+\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+#endif\r
+\r
+#ifdef HAVE_GETPGID\r
+PyDoc_STRVAR(posix_getpgid__doc__,\r
+"getpgid(pid) -> pgid\n\n\\r
+Call the system call getpgid().");\r
+\r
+static PyObject *\r
+posix_getpgid(PyObject *self, PyObject *args)\r
+{\r
+ pid_t pid, pgid;\r
+ if (!PyArg_ParseTuple(args, PARSE_PID ":getpgid", &pid))\r
+ return NULL;\r
+ pgid = getpgid(pid);\r
+ if (pgid < 0)\r
+ return posix_error();\r
+ return PyLong_FromPid(pgid);\r
+}\r
+#endif /* HAVE_GETPGID */\r
+\r
+\r
+#ifdef HAVE_GETPGRP\r
+PyDoc_STRVAR(posix_getpgrp__doc__,\r
+"getpgrp() -> pgrp\n\n\\r
+Return the current process group id.");\r
+\r
+static PyObject *\r
+posix_getpgrp(PyObject *self, PyObject *noargs)\r
+{\r
+#ifdef GETPGRP_HAVE_ARG\r
+ return PyLong_FromPid(getpgrp(0));\r
+#else /* GETPGRP_HAVE_ARG */\r
+ return PyLong_FromPid(getpgrp());\r
+#endif /* GETPGRP_HAVE_ARG */\r
+}\r
+#endif /* HAVE_GETPGRP */\r
+\r
+\r
+#ifdef HAVE_SETPGRP\r
+PyDoc_STRVAR(posix_setpgrp__doc__,\r
+"setpgrp()\n\n\\r
+Make this process the process group leader.");\r
+\r
+static PyObject *\r
+posix_setpgrp(PyObject *self, PyObject *noargs)\r
+{\r
+#ifdef SETPGRP_HAVE_ARG\r
+ if (setpgrp(0, 0) < 0)\r
+#else /* SETPGRP_HAVE_ARG */\r
+ if (setpgrp() < 0)\r
+#endif /* SETPGRP_HAVE_ARG */\r
+ return posix_error();\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+\r
+#endif /* HAVE_SETPGRP */\r
+\r
+#ifdef HAVE_GETPPID\r
+PyDoc_STRVAR(posix_getppid__doc__,\r
+"getppid() -> ppid\n\n\\r
+Return the parent's process id.");\r
+\r
+static PyObject *\r
+posix_getppid(PyObject *self, PyObject *noargs)\r
+{\r
+ return PyLong_FromPid(getppid());\r
+}\r
+#endif\r
+\r
+\r
+#ifdef HAVE_GETLOGIN\r
+PyDoc_STRVAR(posix_getlogin__doc__,\r
+"getlogin() -> string\n\n\\r
+Return the actual login name.");\r
+\r
+static PyObject *\r
+posix_getlogin(PyObject *self, PyObject *noargs)\r
+{\r
+ PyObject *result = NULL;\r
+ char *name;\r
+ int old_errno = errno;\r
+\r
+ errno = 0;\r
+ name = getlogin();\r
+ if (name == NULL) {\r
+ if (errno)\r
+ posix_error();\r
+ else\r
+ PyErr_SetString(PyExc_OSError,\r
+ "unable to determine login name");\r
+ }\r
+ else\r
+ result = PyString_FromString(name);\r
+ errno = old_errno;\r
+\r
+ return result;\r
+}\r
+#endif\r
+\r
+#ifndef UEFI_C_SOURCE\r
+PyDoc_STRVAR(posix_getuid__doc__,\r
+"getuid() -> uid\n\n\\r
+Return the current process's user id.");\r
+\r
+static PyObject *\r
+posix_getuid(PyObject *self, PyObject *noargs)\r
+{\r
+ return PyInt_FromLong((long)getuid());\r
+}\r
+#endif /* UEFI_C_SOURCE */\r
+\r
+#ifdef HAVE_KILL\r
+PyDoc_STRVAR(posix_kill__doc__,\r
+"kill(pid, sig)\n\n\\r
+Kill a process with a signal.");\r
+\r
+static PyObject *\r
+posix_kill(PyObject *self, PyObject *args)\r
+{\r
+ pid_t pid;\r
+ int sig;\r
+ if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))\r
+ return NULL;\r
+#if defined(PYOS_OS2) && !defined(PYCC_GCC)\r
+ if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {\r
+ APIRET rc;\r
+ if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)\r
+ return os2_error(rc);\r
+\r
+ } else if (sig == XCPT_SIGNAL_KILLPROC) {\r
+ APIRET rc;\r
+ if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)\r
+ return os2_error(rc);\r
+\r
+ } else\r
+ return NULL; /* Unrecognized Signal Requested */\r
+#else\r
+ if (kill(pid, sig) == -1)\r
+ return posix_error();\r
+#endif\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+#endif\r
+\r
+#ifdef HAVE_KILLPG\r
+PyDoc_STRVAR(posix_killpg__doc__,\r
+"killpg(pgid, sig)\n\n\\r
+Kill a process group with a signal.");\r
+\r
+static PyObject *\r
+posix_killpg(PyObject *self, PyObject *args)\r
+{\r
+ int sig;\r
+ pid_t pgid;\r
+ /* XXX some man pages make the `pgid` parameter an int, others\r
+ a pid_t. Since getpgrp() returns a pid_t, we assume killpg should\r
+ take the same type. Moreover, pid_t is always at least as wide as\r
+ int (else compilation of this module fails), which is safe. */\r
+ if (!PyArg_ParseTuple(args, PARSE_PID "i:killpg", &pgid, &sig))\r
+ return NULL;\r
+ if (killpg(pgid, sig) == -1)\r
+ return posix_error();\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+#endif\r
+\r
+#ifdef HAVE_PLOCK\r
+\r
+#ifdef HAVE_SYS_LOCK_H\r
+#include <sys/lock.h>\r
+#endif\r
+\r
+PyDoc_STRVAR(posix_plock__doc__,\r
+"plock(op)\n\n\\r
+Lock program segments into memory.");\r
+\r
+static PyObject *\r
+posix_plock(PyObject *self, PyObject *args)\r
+{\r
+ int op;\r
+ if (!PyArg_ParseTuple(args, "i:plock", &op))\r
+ return NULL;\r
+ if (plock(op) == -1)\r
+ return posix_error();\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+#endif\r
+\r
+\r
+#ifdef HAVE_POPEN\r
+PyDoc_STRVAR(posix_popen__doc__,\r
+"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\\r
+Open a pipe to/from a command returning a file object.");\r
+\r
+#if defined(PYOS_OS2)\r
+#if defined(PYCC_VACPP)\r
+static int\r
+async_system(const char *command)\r
+{\r
+ char errormsg[256], args[1024];\r
+ RESULTCODES rcodes;\r
+ APIRET rc;\r
+\r
+ char *shell = getenv("COMSPEC");\r
+ if (!shell)\r
+ shell = "cmd";\r
+\r
+ /* avoid overflowing the argument buffer */\r
+ if (strlen(shell) + 3 + strlen(command) >= 1024)\r
+ return ERROR_NOT_ENOUGH_MEMORY\r
+\r
+ args[0] = '\0';\r
+ strcat(args, shell);\r
+ strcat(args, "/c ");\r
+ strcat(args, command);\r
+\r
+ /* execute asynchronously, inheriting the environment */\r
+ rc = DosExecPgm(errormsg,\r
+ sizeof(errormsg),\r
+ EXEC_ASYNC,\r
+ args,\r
+ NULL,\r
+ &rcodes,\r
+ shell);\r
+ return rc;\r
+}\r
+\r
+static FILE *\r
+popen(const char *command, const char *mode, int pipesize, int *err)\r
+{\r
+ int oldfd, tgtfd;\r
+ HFILE pipeh[2];\r
+ APIRET rc;\r
+\r
+ /* mode determines which of stdin or stdout is reconnected to\r
+ * the pipe to the child\r
+ */\r
+ if (strchr(mode, 'r') != NULL) {\r
+ tgt_fd = 1; /* stdout */\r
+ } else if (strchr(mode, 'w')) {\r
+ tgt_fd = 0; /* stdin */\r
+ } else {\r
+ *err = ERROR_INVALID_ACCESS;\r
+ return NULL;\r
+ }\r
+\r
+ /* setup the pipe */\r
+ if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {\r
+ *err = rc;\r
+ return NULL;\r
+ }\r
+\r
+ /* prevent other threads accessing stdio */\r
+ DosEnterCritSec();\r
+\r
+ /* reconnect stdio and execute child */\r
+ oldfd = dup(tgtfd);\r
+ close(tgtfd);\r
+ if (dup2(pipeh[tgtfd], tgtfd) == 0) {\r
+ DosClose(pipeh[tgtfd]);\r
+ rc = async_system(command);\r
+ }\r
+\r
+ /* restore stdio */\r
+ dup2(oldfd, tgtfd);\r
+ close(oldfd);\r
+\r
+ /* allow other threads access to stdio */\r
+ DosExitCritSec();\r
+\r
+ /* if execution of child was successful return file stream */\r
+ if (rc == NO_ERROR)\r
+ return fdopen(pipeh[1 - tgtfd], mode);\r
+ else {\r
+ DosClose(pipeh[1 - tgtfd]);\r
+ *err = rc;\r
+ return NULL;\r
+ }\r
+}\r
+\r
+static PyObject *\r
+posix_popen(PyObject *self, PyObject *args)\r
+{\r
+ char *name;\r
+ char *mode = "r";\r
+ int err, bufsize = -1;\r
+ FILE *fp;\r
+ PyObject *f;\r
+ if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))\r
+ return NULL;\r
+ Py_BEGIN_ALLOW_THREADS\r
+ fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);\r
+ Py_END_ALLOW_THREADS\r
+ if (fp == NULL)\r
+ return os2_error(err);\r
+\r
+ f = PyFile_FromFile(fp, name, mode, fclose);\r
+ if (f != NULL)\r
+ PyFile_SetBufSize(f, bufsize);\r
+ return f;\r
+}\r
+\r
+#elif defined(PYCC_GCC)\r
+\r
+/* standard posix version of popen() support */\r
+static PyObject *\r
+posix_popen(PyObject *self, PyObject *args)\r
+{\r
+ char *name;\r
+ char *mode = "r";\r
+ int bufsize = -1;\r
+ FILE *fp;\r
+ PyObject *f;\r
+ if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))\r
+ return NULL;\r
+ Py_BEGIN_ALLOW_THREADS\r
+ fp = popen(name, mode);\r
+ Py_END_ALLOW_THREADS\r
+ if (fp == NULL)\r
+ return posix_error();\r
+ f = PyFile_FromFile(fp, name, mode, pclose);\r
+ if (f != NULL)\r
+ PyFile_SetBufSize(f, bufsize);\r
+ return f;\r
+}\r
+\r
+/* fork() under OS/2 has lots'o'warts\r
+ * EMX supports pipe() and spawn*() so we can synthesize popen[234]()\r
+ * most of this code is a ripoff of the win32 code, but using the\r
+ * capabilities of EMX's C library routines\r
+ */\r
+\r
+/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */\r
+#define POPEN_1 1\r
+#define POPEN_2 2\r
+#define POPEN_3 3\r
+#define POPEN_4 4\r
+\r
+static PyObject *_PyPopen(char *, int, int, int);\r
+static int _PyPclose(FILE *file);\r
+\r
+/*\r
+ * Internal dictionary mapping popen* file pointers to process handles,\r
+ * for use when retrieving the process exit code. See _PyPclose() below\r
+ * for more information on this dictionary's use.\r
+ */\r
+static PyObject *_PyPopenProcs = NULL;\r
+\r
+/* os2emx version of popen2()\r
+ *\r
+ * The result of this function is a pipe (file) connected to the\r
+ * process's stdin, and a pipe connected to the process's stdout.\r
+ */\r
+\r
+static PyObject *\r
+os2emx_popen2(PyObject *self, PyObject *args)\r
+{\r
+ PyObject *f;\r
+ int tm=0;\r
+\r
+ char *cmdstring;\r
+ char *mode = "t";\r
+ int bufsize = -1;\r
+ if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))\r
+ return NULL;\r
+\r
+ if (*mode == 't')\r
+ tm = O_TEXT;\r
+ else if (*mode != 'b') {\r
+ PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");\r
+ return NULL;\r
+ } else\r
+ tm = O_BINARY;\r
+\r
+ f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);\r
+\r
+ return f;\r
+}\r
+\r
+/*\r
+ * Variation on os2emx.popen2\r
+ *\r
+ * The result of this function is 3 pipes - the process's stdin,\r
+ * stdout and stderr\r
+ */\r
+\r
+static PyObject *\r
+os2emx_popen3(PyObject *self, PyObject *args)\r
+{\r
+ PyObject *f;\r
+ int tm = 0;\r
+\r
+ char *cmdstring;\r
+ char *mode = "t";\r
+ int bufsize = -1;\r
+ if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))\r
+ return NULL;\r
+\r
+ if (*mode == 't')\r
+ tm = O_TEXT;\r
+ else if (*mode != 'b') {\r
+ PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");\r
+ return NULL;\r
+ } else\r
+ tm = O_BINARY;\r
+\r
+ f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);\r
+\r
+ return f;\r
+}\r
+\r
+/*\r
+ * Variation on os2emx.popen2\r
+ *\r
+ * The result of this function is 2 pipes - the processes stdin,\r
+ * and stdout+stderr combined as a single pipe.\r
+ */\r
+\r
+static PyObject *\r
+os2emx_popen4(PyObject *self, PyObject *args)\r
+{\r
+ PyObject *f;\r
+ int tm = 0;\r
+\r
+ char *cmdstring;\r
+ char *mode = "t";\r
+ int bufsize = -1;\r
+ if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))\r
+ return NULL;\r
+\r
+ if (*mode == 't')\r
+ tm = O_TEXT;\r
+ else if (*mode != 'b') {\r
+ PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");\r
+ return NULL;\r
+ } else\r
+ tm = O_BINARY;\r
+\r
+ f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);\r
+\r
+ return f;\r
+}\r
+\r
+/* a couple of structures for convenient handling of multiple\r
+ * file handles and pipes\r
+ */\r
+struct file_ref\r
+{\r
+ int handle;\r
+ int flags;\r
+};\r
+\r
+struct pipe_ref\r
+{\r
+ int rd;\r
+ int wr;\r
+};\r
+\r
+/* The following code is derived from the win32 code */\r
+\r
+static PyObject *\r
+_PyPopen(char *cmdstring, int mode, int n, int bufsize)\r
+{\r
+ struct file_ref stdio[3];\r
+ struct pipe_ref p_fd[3];\r
+ FILE *p_s[3];\r
+ int file_count, i, pipe_err;\r
+ pid_t pipe_pid;\r
+ char *shell, *sh_name, *opt, *rd_mode, *wr_mode;\r
+ PyObject *f, *p_f[3];\r
+\r
+ /* file modes for subsequent fdopen's on pipe handles */\r
+ if (mode == O_TEXT)\r
+ {\r
+ rd_mode = "rt";\r
+ wr_mode = "wt";\r
+ }\r
+ else\r
+ {\r
+ rd_mode = "rb";\r
+ wr_mode = "wb";\r
+ }\r
+\r
+ /* prepare shell references */\r
+ if ((shell = getenv("EMXSHELL")) == NULL)\r
+ if ((shell = getenv("COMSPEC")) == NULL)\r
+ {\r
+ errno = ENOENT;\r
+ return posix_error();\r
+ }\r
+\r
+ sh_name = _getname(shell);\r
+ if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)\r
+ opt = "/c";\r
+ else\r
+ opt = "-c";\r
+\r
+ /* save current stdio fds + their flags, and set not inheritable */\r
+ i = pipe_err = 0;\r
+ while (pipe_err >= 0 && i < 3)\r
+ {\r
+ pipe_err = stdio[i].handle = dup(i);\r
+ stdio[i].flags = fcntl(i, F_GETFD, 0);\r
+ fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);\r
+ i++;\r
+ }\r
+ if (pipe_err < 0)\r
+ {\r
+ /* didn't get them all saved - clean up and bail out */\r
+ int saved_err = errno;\r
+ while (i-- > 0)\r
+ {\r
+ close(stdio[i].handle);\r
+ }\r
+ errno = saved_err;\r
+ return posix_error();\r
+ }\r
+\r
+ /* create pipe ends */\r
+ file_count = 2;\r
+ if (n == POPEN_3)\r
+ file_count = 3;\r
+ i = pipe_err = 0;\r
+ while ((pipe_err == 0) && (i < file_count))\r
+ pipe_err = pipe((int *)&p_fd[i++]);\r
+ if (pipe_err < 0)\r
+ {\r
+ /* didn't get them all made - clean up and bail out */\r
+ while (i-- > 0)\r
+ {\r
+ close(p_fd[i].wr);\r
+ close(p_fd[i].rd);\r
+ }\r
+ errno = EPIPE;\r
+ return posix_error();\r
+ }\r
+\r
+ /* change the actual standard IO streams over temporarily,\r
+ * making the retained pipe ends non-inheritable\r
+ */\r
+ pipe_err = 0;\r
+\r
+ /* - stdin */\r
+ if (dup2(p_fd[0].rd, 0) == 0)\r
+ {\r
+ close(p_fd[0].rd);\r
+ i = fcntl(p_fd[0].wr, F_GETFD, 0);\r
+ fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);\r
+ if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)\r
+ {\r
+ close(p_fd[0].wr);\r
+ pipe_err = -1;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ pipe_err = -1;\r
+ }\r
+\r
+ /* - stdout */\r
+ if (pipe_err == 0)\r
+ {\r
+ if (dup2(p_fd[1].wr, 1) == 1)\r
+ {\r
+ close(p_fd[1].wr);\r
+ i = fcntl(p_fd[1].rd, F_GETFD, 0);\r
+ fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);\r
+ if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)\r
+ {\r
+ close(p_fd[1].rd);\r
+ pipe_err = -1;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ pipe_err = -1;\r
+ }\r
+ }\r
+\r
+ /* - stderr, as required */\r
+ if (pipe_err == 0)\r
+ switch (n)\r
+ {\r
+ case POPEN_3:\r
+ {\r
+ if (dup2(p_fd[2].wr, 2) == 2)\r
+ {\r
+ close(p_fd[2].wr);\r
+ i = fcntl(p_fd[2].rd, F_GETFD, 0);\r
+ fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);\r
+ if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)\r
+ {\r
+ close(p_fd[2].rd);\r
+ pipe_err = -1;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ pipe_err = -1;\r
+ }\r
+ break;\r
+ }\r
+\r
+ case POPEN_4:\r
+ {\r
+ if (dup2(1, 2) != 2)\r
+ {\r
+ pipe_err = -1;\r
+ }\r
+ break;\r
+ }\r
+ }\r
+\r
+ /* spawn the child process */\r
+ if (pipe_err == 0)\r
+ {\r
+ pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);\r
+ if (pipe_pid == -1)\r
+ {\r
+ pipe_err = -1;\r
+ }\r
+ else\r
+ {\r
+ /* save the PID into the FILE structure\r
+ * NOTE: this implementation doesn't actually\r
+ * take advantage of this, but do it for\r
+ * completeness - AIM Apr01\r
+ */\r
+ for (i = 0; i < file_count; i++)\r
+ p_s[i]->_pid = pipe_pid;\r
+ }\r
+ }\r
+\r
+ /* reset standard IO to normal */\r
+ for (i = 0; i < 3; i++)\r
+ {\r
+ dup2(stdio[i].handle, i);\r
+ fcntl(i, F_SETFD, stdio[i].flags);\r
+ close(stdio[i].handle);\r
+ }\r
+\r
+ /* if any remnant problems, clean up and bail out */\r
+ if (pipe_err < 0)\r
+ {\r
+ for (i = 0; i < 3; i++)\r
+ {\r
+ close(p_fd[i].rd);\r
+ close(p_fd[i].wr);\r
+ }\r
+ errno = EPIPE;\r
+ return posix_error_with_filename(cmdstring);\r
+ }\r
+\r
+ /* build tuple of file objects to return */\r
+ if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)\r
+ PyFile_SetBufSize(p_f[0], bufsize);\r
+ if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)\r
+ PyFile_SetBufSize(p_f[1], bufsize);\r
+ if (n == POPEN_3)\r
+ {\r
+ if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)\r
+ PyFile_SetBufSize(p_f[0], bufsize);\r
+ f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);\r
+ }\r
+ else\r
+ f = PyTuple_Pack(2, p_f[0], p_f[1]);\r
+\r
+ /*\r
+ * Insert the files we've created into the process dictionary\r
+ * all referencing the list with the process handle and the\r
+ * initial number of files (see description below in _PyPclose).\r
+ * Since if _PyPclose later tried to wait on a process when all\r
+ * handles weren't closed, it could create a deadlock with the\r
+ * child, we spend some energy here to try to ensure that we\r
+ * either insert all file handles into the dictionary or none\r
+ * at all. It's a little clumsy with the various popen modes\r
+ * and variable number of files involved.\r
+ */\r
+ if (!_PyPopenProcs)\r
+ {\r
+ _PyPopenProcs = PyDict_New();\r
+ }\r
+\r
+ if (_PyPopenProcs)\r
+ {\r
+ PyObject *procObj, *pidObj, *intObj, *fileObj[3];\r
+ int ins_rc[3];\r
+\r
+ fileObj[0] = fileObj[1] = fileObj[2] = NULL;\r
+ ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;\r
+\r
+ procObj = PyList_New(2);\r
+ pidObj = PyLong_FromPid(pipe_pid);\r
+ intObj = PyInt_FromLong((long) file_count);\r
+\r
+ if (procObj && pidObj && intObj)\r
+ {\r
+ PyList_SetItem(procObj, 0, pidObj);\r
+ PyList_SetItem(procObj, 1, intObj);\r
+\r
+ fileObj[0] = PyLong_FromVoidPtr(p_s[0]);\r
+ if (fileObj[0])\r
+ {\r
+ ins_rc[0] = PyDict_SetItem(_PyPopenProcs,\r
+ fileObj[0],\r
+ procObj);\r
+ }\r
+ fileObj[1] = PyLong_FromVoidPtr(p_s[1]);\r
+ if (fileObj[1])\r
+ {\r
+ ins_rc[1] = PyDict_SetItem(_PyPopenProcs,\r
+ fileObj[1],\r
+ procObj);\r
+ }\r
+ if (file_count >= 3)\r
+ {\r
+ fileObj[2] = PyLong_FromVoidPtr(p_s[2]);\r
+ if (fileObj[2])\r
+ {\r
+ ins_rc[2] = PyDict_SetItem(_PyPopenProcs,\r
+ fileObj[2],\r
+ procObj);\r
+ }\r
+ }\r
+\r
+ if (ins_rc[0] < 0 || !fileObj[0] ||\r
+ ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||\r
+ ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))\r
+ {\r
+ /* Something failed - remove any dictionary\r
+ * entries that did make it.\r
+ */\r
+ if (!ins_rc[0] && fileObj[0])\r
+ {\r
+ PyDict_DelItem(_PyPopenProcs,\r
+ fileObj[0]);\r
+ }\r
+ if (!ins_rc[1] && fileObj[1])\r
+ {\r
+ PyDict_DelItem(_PyPopenProcs,\r
+ fileObj[1]);\r
+ }\r
+ if (!ins_rc[2] && fileObj[2])\r
+ {\r
+ PyDict_DelItem(_PyPopenProcs,\r
+ fileObj[2]);\r
+ }\r
+ }\r
+ }\r
+\r
+ /*\r
+ * Clean up our localized references for the dictionary keys\r
+ * and value since PyDict_SetItem will Py_INCREF any copies\r
+ * that got placed in the dictionary.\r
+ */\r
+ Py_XDECREF(procObj);\r
+ Py_XDECREF(fileObj[0]);\r
+ Py_XDECREF(fileObj[1]);\r
+ Py_XDECREF(fileObj[2]);\r
+ }\r
+\r
+ /* Child is launched. */\r
+ return f;\r
+}\r
+\r
+/*\r
+ * Wrapper for fclose() to use for popen* files, so we can retrieve the\r
+ * exit code for the child process and return as a result of the close.\r
+ *\r
+ * This function uses the _PyPopenProcs dictionary in order to map the\r
+ * input file pointer to information about the process that was\r
+ * originally created by the popen* call that created the file pointer.\r
+ * The dictionary uses the file pointer as a key (with one entry\r
+ * inserted for each file returned by the original popen* call) and a\r
+ * single list object as the value for all files from a single call.\r
+ * The list object contains the Win32 process handle at [0], and a file\r
+ * count at [1], which is initialized to the total number of file\r
+ * handles using that list.\r
+ *\r
+ * This function closes whichever handle it is passed, and decrements\r
+ * the file count in the dictionary for the process handle pointed to\r
+ * by this file. On the last close (when the file count reaches zero),\r
+ * this function will wait for the child process and then return its\r
+ * exit code as the result of the close() operation. This permits the\r
+ * files to be closed in any order - it is always the close() of the\r
+ * final handle that will return the exit code.\r
+ *\r
+ * NOTE: This function is currently called with the GIL released.\r
+ * hence we use the GILState API to manage our state.\r
+ */\r
+\r
+static int _PyPclose(FILE *file)\r
+{\r
+ int result;\r
+ int exit_code;\r
+ pid_t pipe_pid;\r
+ PyObject *procObj, *pidObj, *intObj, *fileObj;\r
+ int file_count;\r
+#ifdef WITH_THREAD\r
+ PyGILState_STATE state;\r
+#endif\r
+\r
+ /* Close the file handle first, to ensure it can't block the\r
+ * child from exiting if it's the last handle.\r
+ */\r
+ result = fclose(file);\r
+\r
+#ifdef WITH_THREAD\r
+ state = PyGILState_Ensure();\r
+#endif\r
+ if (_PyPopenProcs)\r
+ {\r
+ if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&\r
+ (procObj = PyDict_GetItem(_PyPopenProcs,\r
+ fileObj)) != NULL &&\r
+ (pidObj = PyList_GetItem(procObj,0)) != NULL &&\r
+ (intObj = PyList_GetItem(procObj,1)) != NULL)\r
+ {\r
+ pipe_pid = (pid_t) PyLong_AsPid(pidObj);\r
+ file_count = (int) PyInt_AsLong(intObj);\r
+\r
+ if (file_count > 1)\r
+ {\r
+ /* Still other files referencing process */\r
+ file_count--;\r
+ PyList_SetItem(procObj,1,\r
+ PyInt_FromLong((long) file_count));\r
+ }\r
+ else\r
+ {\r
+ /* Last file for this process */\r
+ if (result != EOF &&\r
+ waitpid(pipe_pid, &exit_code, 0) == pipe_pid)\r
+ {\r
+ /* extract exit status */\r
+ if (WIFEXITED(exit_code))\r
+ {\r
+ result = WEXITSTATUS(exit_code);\r
+ }\r
+ else\r
+ {\r
+ errno = EPIPE;\r
+ result = -1;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ /* Indicate failure - this will cause the file object\r
+ * to raise an I/O error and translate the last\r
+ * error code from errno. We do have a problem with\r
+ * last errors that overlap the normal errno table,\r
+ * but that's a consistent problem with the file object.\r
+ */\r
+ result = -1;\r
+ }\r
+ }\r
+\r
+ /* Remove this file pointer from dictionary */\r
+ PyDict_DelItem(_PyPopenProcs, fileObj);\r
+\r
+ if (PyDict_Size(_PyPopenProcs) == 0)\r
+ {\r
+ Py_DECREF(_PyPopenProcs);\r
+ _PyPopenProcs = NULL;\r
+ }\r
+\r
+ } /* if object retrieval ok */\r
+\r
+ Py_XDECREF(fileObj);\r
+ } /* if _PyPopenProcs */\r
+\r
+#ifdef WITH_THREAD\r
+ PyGILState_Release(state);\r
+#endif\r
+ return result;\r
+}\r
+\r
+#endif /* PYCC_??? */\r
+\r
+#elif defined(MS_WINDOWS)\r
+\r
+/*\r
+ * Portable 'popen' replacement for Win32.\r
+ *\r
+ * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks\r
+ * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>\r
+ * Return code handling by David Bolen <db3l@fitlinxx.com>.\r
+ */\r
+\r
+#include <malloc.h>\r
+#include <io.h>\r
+#include <fcntl.h>\r
+\r
+/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */\r
+#define POPEN_1 1\r
+#define POPEN_2 2\r
+#define POPEN_3 3\r
+#define POPEN_4 4\r
+\r
+static PyObject *_PyPopen(char *, int, int);\r
+static int _PyPclose(FILE *file);\r
+\r
+/*\r
+ * Internal dictionary mapping popen* file pointers to process handles,\r
+ * for use when retrieving the process exit code. See _PyPclose() below\r
+ * for more information on this dictionary's use.\r
+ */\r
+static PyObject *_PyPopenProcs = NULL;\r
+\r
+\r
+/* popen that works from a GUI.\r
+ *\r
+ * The result of this function is a pipe (file) connected to the\r
+ * processes stdin or stdout, depending on the requested mode.\r
+ */\r
+\r
+static PyObject *\r
+posix_popen(PyObject *self, PyObject *args)\r
+{\r
+ PyObject *f;\r
+ int tm = 0;\r
+\r
+ char *cmdstring;\r
+ char *mode = "r";\r
+ int bufsize = -1;\r
+ if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))\r
+ return NULL;\r
+\r
+ if (*mode == 'r')\r
+ tm = _O_RDONLY;\r
+ else if (*mode != 'w') {\r
+ PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");\r
+ return NULL;\r
+ } else\r
+ tm = _O_WRONLY;\r
+\r
+ if (bufsize != -1) {\r
+ PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");\r
+ return NULL;\r
+ }\r
+\r
+ if (*(mode+1) == 't')\r
+ f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);\r
+ else if (*(mode+1) == 'b')\r
+ f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);\r
+ else\r
+ f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);\r
+\r
+ return f;\r
+}\r
+\r
+/* Variation on win32pipe.popen\r
+ *\r
+ * The result of this function is a pipe (file) connected to the\r
+ * process's stdin, and a pipe connected to the process's stdout.\r
+ */\r
+\r
+static PyObject *\r
+win32_popen2(PyObject *self, PyObject *args)\r
+{\r
+ PyObject *f;\r
+ int tm=0;\r
+\r
+ char *cmdstring;\r
+ char *mode = "t";\r
+ int bufsize = -1;\r
+ if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))\r
+ return NULL;\r
+\r
+ if (*mode == 't')\r
+ tm = _O_TEXT;\r
+ else if (*mode != 'b') {\r
+ PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");\r
+ return NULL;\r
+ } else\r
+ tm = _O_BINARY;\r
+\r
+ if (bufsize != -1) {\r
+ PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");\r
+ return NULL;\r
+ }\r
+\r
+ f = _PyPopen(cmdstring, tm, POPEN_2);\r
+\r
+ return f;\r
+}\r
+\r
+/*\r
+ * Variation on <om win32pipe.popen>\r
+ *\r
+ * The result of this function is 3 pipes - the process's stdin,\r
+ * stdout and stderr\r
+ */\r
+\r
+static PyObject *\r
+win32_popen3(PyObject *self, PyObject *args)\r
+{\r
+ PyObject *f;\r
+ int tm = 0;\r
+\r
+ char *cmdstring;\r
+ char *mode = "t";\r
+ int bufsize = -1;\r
+ if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))\r
+ return NULL;\r
+\r
+ if (*mode == 't')\r
+ tm = _O_TEXT;\r
+ else if (*mode != 'b') {\r
+ PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");\r
+ return NULL;\r
+ } else\r
+ tm = _O_BINARY;\r
+\r
+ if (bufsize != -1) {\r
+ PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");\r
+ return NULL;\r
+ }\r
+\r
+ f = _PyPopen(cmdstring, tm, POPEN_3);\r
+\r
+ return f;\r
+}\r
+\r
+/*\r
+ * Variation on win32pipe.popen\r
+ *\r
+ * The result of this function is 2 pipes - the processes stdin,\r
+ * and stdout+stderr combined as a single pipe.\r
+ */\r
+\r
+static PyObject *\r
+win32_popen4(PyObject *self, PyObject *args)\r
+{\r
+ PyObject *f;\r
+ int tm = 0;\r
+\r
+ char *cmdstring;\r
+ char *mode = "t";\r
+ int bufsize = -1;\r
+ if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))\r
+ return NULL;\r
+\r
+ if (*mode == 't')\r
+ tm = _O_TEXT;\r
+ else if (*mode != 'b') {\r
+ PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");\r
+ return NULL;\r
+ } else\r
+ tm = _O_BINARY;\r
+\r
+ if (bufsize != -1) {\r
+ PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");\r
+ return NULL;\r
+ }\r
+\r
+ f = _PyPopen(cmdstring, tm, POPEN_4);\r
+\r
+ return f;\r
+}\r
+\r
+static BOOL\r
+_PyPopenCreateProcess(char *cmdstring,\r
+ HANDLE hStdin,\r
+ HANDLE hStdout,\r
+ HANDLE hStderr,\r
+ HANDLE *hProcess)\r
+{\r
+ PROCESS_INFORMATION piProcInfo;\r
+ STARTUPINFO siStartInfo;\r
+ DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */\r
+ char *s1,*s2, *s3 = " /c ";\r
+ const char *szConsoleSpawn = "w9xpopen.exe";\r
+ int i;\r
+ Py_ssize_t x;\r
+\r
+ if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {\r
+ char *comshell;\r
+\r
+ s1 = (char *)alloca(i);\r
+ if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))\r
+ /* x < i, so x fits into an integer */\r
+ return (int)x;\r
+\r
+ /* Explicitly check if we are using COMMAND.COM. If we are\r
+ * then use the w9xpopen hack.\r
+ */\r
+ comshell = s1 + x;\r
+ while (comshell >= s1 && *comshell != '\\')\r
+ --comshell;\r
+ ++comshell;\r
+\r
+ if (GetVersion() < 0x80000000 &&\r
+ _stricmp(comshell, "command.com") != 0) {\r
+ /* NT/2000 and not using command.com. */\r
+ x = i + strlen(s3) + strlen(cmdstring) + 1;\r
+ s2 = (char *)alloca(x);\r
+ ZeroMemory(s2, x);\r
+ PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);\r
+ }\r
+ else {\r
+ /*\r
+ * Oh gag, we're on Win9x or using COMMAND.COM. Use\r
+ * the workaround listed in KB: Q150956\r
+ */\r
+ char modulepath[_MAX_PATH];\r
+ struct stat statinfo;\r
+ GetModuleFileName(NULL, modulepath, sizeof(modulepath));\r
+ for (x = i = 0; modulepath[i]; i++)\r
+ if (modulepath[i] == SEP)\r
+ x = i+1;\r
+ modulepath[x] = '\0';\r
+ /* Create the full-name to w9xpopen, so we can test it exists */\r
+ strncat(modulepath,\r
+ szConsoleSpawn,\r
+ (sizeof(modulepath)/sizeof(modulepath[0]))\r
+ -strlen(modulepath));\r
+ if (stat(modulepath, &statinfo) != 0) {\r
+ size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);\r
+ /* Eeek - file-not-found - possibly an embedding\r
+ situation - see if we can locate it in sys.prefix\r
+ */\r
+ strncpy(modulepath,\r
+ Py_GetExecPrefix(),\r
+ mplen);\r
+ modulepath[mplen-1] = '\0';\r
+ if (modulepath[strlen(modulepath)-1] != '\\')\r
+ strcat(modulepath, "\\");\r
+ strncat(modulepath,\r
+ szConsoleSpawn,\r
+ mplen-strlen(modulepath));\r
+ /* No where else to look - raise an easily identifiable\r
+ error, rather than leaving Windows to report\r
+ "file not found" - as the user is probably blissfully\r
+ unaware this shim EXE is used, and it will confuse them.\r
+ (well, it confused me for a while ;-)\r
+ */\r
+ if (stat(modulepath, &statinfo) != 0) {\r
+ PyErr_Format(PyExc_RuntimeError,\r
+ "Can not locate '%s' which is needed "\r
+ "for popen to work with your shell "\r
+ "or platform.",\r
+ szConsoleSpawn);\r
+ return FALSE;\r
+ }\r
+ }\r
+ x = i + strlen(s3) + strlen(cmdstring) + 1 +\r
+ strlen(modulepath) +\r
+ strlen(szConsoleSpawn) + 1;\r
+\r
+ s2 = (char *)alloca(x);\r
+ ZeroMemory(s2, x);\r
+ /* To maintain correct argument passing semantics,\r
+ we pass the command-line as it stands, and allow\r
+ quoting to be applied. w9xpopen.exe will then\r
+ use its argv vector, and re-quote the necessary\r
+ args for the ultimate child process.\r
+ */\r
+ PyOS_snprintf(\r
+ s2, x,\r
+ "\"%s\" %s%s%s",\r
+ modulepath,\r
+ s1,\r
+ s3,\r
+ cmdstring);\r
+ /* Not passing CREATE_NEW_CONSOLE has been known to\r
+ cause random failures on win9x. Specifically a\r
+ dialog:\r
+ "Your program accessed mem currently in use at xxx"\r
+ and a hopeful warning about the stability of your\r
+ system.\r
+ Cost is Ctrl+C won't kill children, but anyone\r
+ who cares can have a go!\r
+ */\r
+ dwProcessFlags |= CREATE_NEW_CONSOLE;\r
+ }\r
+ }\r
+\r
+ /* Could be an else here to try cmd.exe / command.com in the path\r
+ Now we'll just error out.. */\r
+ else {\r
+ PyErr_SetString(PyExc_RuntimeError,\r
+ "Cannot locate a COMSPEC environment variable to "\r
+ "use as the shell");\r
+ return FALSE;\r
+ }\r
+\r
+ ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));\r
+ siStartInfo.cb = sizeof(STARTUPINFO);\r
+ siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;\r
+ siStartInfo.hStdInput = hStdin;\r
+ siStartInfo.hStdOutput = hStdout;\r
+ siStartInfo.hStdError = hStderr;\r
+ siStartInfo.wShowWindow = SW_HIDE;\r
+\r
+ if (CreateProcess(NULL,\r
+ s2,\r
+ NULL,\r
+ NULL,\r
+ TRUE,\r
+ dwProcessFlags,\r
+ NULL,\r
+ NULL,\r
+ &siStartInfo,\r
+ &piProcInfo) ) {\r
+ /* Close the handles now so anyone waiting is woken. */\r
+ CloseHandle(piProcInfo.hThread);\r
+\r
+ /* Return process handle */\r
+ *hProcess = piProcInfo.hProcess;\r
+ return TRUE;\r
+ }\r
+ win32_error("CreateProcess", s2);\r
+ return FALSE;\r
+}\r
+\r
+/* The following code is based off of KB: Q190351 */\r
+\r
+static PyObject *\r
+_PyPopen(char *cmdstring, int mode, int n)\r
+{\r
+ HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,\r
+ hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,\r
+ hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */\r
+\r
+ SECURITY_ATTRIBUTES saAttr;\r
+ BOOL fSuccess;\r
+ int fd1, fd2, fd3;\r
+ FILE *f1, *f2, *f3;\r
+ long file_count;\r
+ PyObject *f;\r
+\r
+ saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);\r
+ saAttr.bInheritHandle = TRUE;\r
+ saAttr.lpSecurityDescriptor = NULL;\r
+\r
+ if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))\r
+ return win32_error("CreatePipe", NULL);\r
+\r
+ /* Create new output read handle and the input write handle. Set\r
+ * the inheritance properties to FALSE. Otherwise, the child inherits\r
+ * these handles; resulting in non-closeable handles to the pipes\r
+ * being created. */\r
+ fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,\r
+ GetCurrentProcess(), &hChildStdinWrDup, 0,\r
+ FALSE,\r
+ DUPLICATE_SAME_ACCESS);\r
+ if (!fSuccess)\r
+ return win32_error("DuplicateHandle", NULL);\r
+\r
+ /* Close the inheritable version of ChildStdin\r
+ that we're using. */\r
+ CloseHandle(hChildStdinWr);\r
+\r
+ if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))\r
+ return win32_error("CreatePipe", NULL);\r
+\r
+ fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,\r
+ GetCurrentProcess(), &hChildStdoutRdDup, 0,\r
+ FALSE, DUPLICATE_SAME_ACCESS);\r
+ if (!fSuccess)\r
+ return win32_error("DuplicateHandle", NULL);\r
+\r
+ /* Close the inheritable version of ChildStdout\r
+ that we're using. */\r
+ CloseHandle(hChildStdoutRd);\r
+\r
+ if (n != POPEN_4) {\r
+ if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))\r
+ return win32_error("CreatePipe", NULL);\r
+ fSuccess = DuplicateHandle(GetCurrentProcess(),\r
+ hChildStderrRd,\r
+ GetCurrentProcess(),\r
+ &hChildStderrRdDup, 0,\r
+ FALSE, DUPLICATE_SAME_ACCESS);\r
+ if (!fSuccess)\r
+ return win32_error("DuplicateHandle", NULL);\r
+ /* Close the inheritable version of ChildStdErr that we're using. */\r
+ CloseHandle(hChildStderrRd);\r
+ }\r
+\r
+ switch (n) {\r
+ case POPEN_1:\r
+ switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {\r
+ case _O_WRONLY | _O_TEXT:\r
+ /* Case for writing to child Stdin in text mode. */\r
+ fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);\r
+ f1 = _fdopen(fd1, "w");\r
+ f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);\r
+ PyFile_SetBufSize(f, 0);\r
+ /* We don't care about these pipes anymore, so close them. */\r
+ CloseHandle(hChildStdoutRdDup);\r
+ CloseHandle(hChildStderrRdDup);\r
+ break;\r
+\r
+ case _O_RDONLY | _O_TEXT:\r
+ /* Case for reading from child Stdout in text mode. */\r
+ fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);\r
+ f1 = _fdopen(fd1, "r");\r
+ f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);\r
+ PyFile_SetBufSize(f, 0);\r
+ /* We don't care about these pipes anymore, so close them. */\r
+ CloseHandle(hChildStdinWrDup);\r
+ CloseHandle(hChildStderrRdDup);\r
+ break;\r
+\r
+ case _O_RDONLY | _O_BINARY:\r
+ /* Case for readinig from child Stdout in binary mode. */\r
+ fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);\r
+ f1 = _fdopen(fd1, "rb");\r
+ f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);\r
+ PyFile_SetBufSize(f, 0);\r
+ /* We don't care about these pipes anymore, so close them. */\r
+ CloseHandle(hChildStdinWrDup);\r
+ CloseHandle(hChildStderrRdDup);\r
+ break;\r
+\r
+ case _O_WRONLY | _O_BINARY:\r
+ /* Case for writing to child Stdin in binary mode. */\r
+ fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);\r
+ f1 = _fdopen(fd1, "wb");\r
+ f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);\r
+ PyFile_SetBufSize(f, 0);\r
+ /* We don't care about these pipes anymore, so close them. */\r
+ CloseHandle(hChildStdoutRdDup);\r
+ CloseHandle(hChildStderrRdDup);\r
+ break;\r
+ }\r
+ file_count = 1;\r
+ break;\r
+\r
+ case POPEN_2:\r
+ case POPEN_4:\r
+ {\r
+ char *m1, *m2;\r
+ PyObject *p1, *p2;\r
+\r
+ if (mode & _O_TEXT) {\r
+ m1 = "r";\r
+ m2 = "w";\r
+ } else {\r
+ m1 = "rb";\r
+ m2 = "wb";\r
+ }\r
+\r
+ fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);\r
+ f1 = _fdopen(fd1, m2);\r
+ fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);\r
+ f2 = _fdopen(fd2, m1);\r
+ p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);\r
+ PyFile_SetBufSize(p1, 0);\r
+ p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);\r
+ PyFile_SetBufSize(p2, 0);\r
+\r
+ if (n != 4)\r
+ CloseHandle(hChildStderrRdDup);\r
+\r
+ f = PyTuple_Pack(2,p1,p2);\r
+ Py_XDECREF(p1);\r
+ Py_XDECREF(p2);\r
+ file_count = 2;\r
+ break;\r
+ }\r
+\r
+ case POPEN_3:\r
+ {\r
+ char *m1, *m2;\r
+ PyObject *p1, *p2, *p3;\r
+\r
+ if (mode & _O_TEXT) {\r
+ m1 = "r";\r
+ m2 = "w";\r
+ } else {\r
+ m1 = "rb";\r
+ m2 = "wb";\r
+ }\r
+\r
+ fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);\r
+ f1 = _fdopen(fd1, m2);\r
+ fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);\r
+ f2 = _fdopen(fd2, m1);\r
+ fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);\r
+ f3 = _fdopen(fd3, m1);\r
+ p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);\r
+ p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);\r
+ p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);\r
+ PyFile_SetBufSize(p1, 0);\r
+ PyFile_SetBufSize(p2, 0);\r
+ PyFile_SetBufSize(p3, 0);\r
+ f = PyTuple_Pack(3,p1,p2,p3);\r
+ Py_XDECREF(p1);\r
+ Py_XDECREF(p2);\r
+ Py_XDECREF(p3);\r
+ file_count = 3;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (n == POPEN_4) {\r
+ if (!_PyPopenCreateProcess(cmdstring,\r
+ hChildStdinRd,\r
+ hChildStdoutWr,\r
+ hChildStdoutWr,\r
+ &hProcess))\r
+ return NULL;\r
+ }\r
+ else {\r
+ if (!_PyPopenCreateProcess(cmdstring,\r
+ hChildStdinRd,\r
+ hChildStdoutWr,\r
+ hChildStderrWr,\r
+ &hProcess))\r
+ return NULL;\r
+ }\r
+\r
+ /*\r
+ * Insert the files we've created into the process dictionary\r
+ * all referencing the list with the process handle and the\r
+ * initial number of files (see description below in _PyPclose).\r
+ * Since if _PyPclose later tried to wait on a process when all\r
+ * handles weren't closed, it could create a deadlock with the\r
+ * child, we spend some energy here to try to ensure that we\r
+ * either insert all file handles into the dictionary or none\r
+ * at all. It's a little clumsy with the various popen modes\r
+ * and variable number of files involved.\r
+ */\r
+ if (!_PyPopenProcs) {\r
+ _PyPopenProcs = PyDict_New();\r
+ }\r
+\r
+ if (_PyPopenProcs) {\r
+ PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];\r
+ int ins_rc[3];\r
+\r
+ fileObj[0] = fileObj[1] = fileObj[2] = NULL;\r
+ ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;\r
+\r
+ procObj = PyList_New(2);\r
+ hProcessObj = PyLong_FromVoidPtr(hProcess);\r
+ intObj = PyInt_FromLong(file_count);\r
+\r
+ if (procObj && hProcessObj && intObj) {\r
+ PyList_SetItem(procObj,0,hProcessObj);\r
+ PyList_SetItem(procObj,1,intObj);\r
+\r
+ fileObj[0] = PyLong_FromVoidPtr(f1);\r
+ if (fileObj[0]) {\r
+ ins_rc[0] = PyDict_SetItem(_PyPopenProcs,\r
+ fileObj[0],\r
+ procObj);\r
+ }\r
+ if (file_count >= 2) {\r
+ fileObj[1] = PyLong_FromVoidPtr(f2);\r
+ if (fileObj[1]) {\r
+ ins_rc[1] = PyDict_SetItem(_PyPopenProcs,\r
+ fileObj[1],\r
+ procObj);\r
+ }\r
+ }\r
+ if (file_count >= 3) {\r
+ fileObj[2] = PyLong_FromVoidPtr(f3);\r
+ if (fileObj[2]) {\r
+ ins_rc[2] = PyDict_SetItem(_PyPopenProcs,\r
+ fileObj[2],\r
+ procObj);\r
+ }\r
+ }\r
+\r
+ if (ins_rc[0] < 0 || !fileObj[0] ||\r
+ ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||\r
+ ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {\r
+ /* Something failed - remove any dictionary\r
+ * entries that did make it.\r
+ */\r
+ if (!ins_rc[0] && fileObj[0]) {\r
+ PyDict_DelItem(_PyPopenProcs,\r
+ fileObj[0]);\r
+ }\r
+ if (!ins_rc[1] && fileObj[1]) {\r
+ PyDict_DelItem(_PyPopenProcs,\r
+ fileObj[1]);\r
+ }\r
+ if (!ins_rc[2] && fileObj[2]) {\r
+ PyDict_DelItem(_PyPopenProcs,\r
+ fileObj[2]);\r
+ }\r
+ }\r
+ }\r
+\r
+ /*\r
+ * Clean up our localized references for the dictionary keys\r
+ * and value since PyDict_SetItem will Py_INCREF any copies\r
+ * that got placed in the dictionary.\r
+ */\r
+ Py_XDECREF(procObj);\r
+ Py_XDECREF(fileObj[0]);\r
+ Py_XDECREF(fileObj[1]);\r
+ Py_XDECREF(fileObj[2]);\r
+ }\r
+\r
+ /* Child is launched. Close the parents copy of those pipe\r
+ * handles that only the child should have open. You need to\r
+ * make sure that no handles to the write end of the output pipe\r
+ * are maintained in this process or else the pipe will not close\r
+ * when the child process exits and the ReadFile will hang. */\r
+\r
+ if (!CloseHandle(hChildStdinRd))\r
+ return win32_error("CloseHandle", NULL);\r
+\r
+ if (!CloseHandle(hChildStdoutWr))\r
+ return win32_error("CloseHandle", NULL);\r
+\r
+ if ((n != 4) && (!CloseHandle(hChildStderrWr)))\r
+ return win32_error("CloseHandle", NULL);\r
+\r
+ return f;\r
+}\r
+\r
+/*\r
+ * Wrapper for fclose() to use for popen* files, so we can retrieve the\r
+ * exit code for the child process and return as a result of the close.\r
+ *\r
+ * This function uses the _PyPopenProcs dictionary in order to map the\r
+ * input file pointer to information about the process that was\r
+ * originally created by the popen* call that created the file pointer.\r
+ * The dictionary uses the file pointer as a key (with one entry\r
+ * inserted for each file returned by the original popen* call) and a\r
+ * single list object as the value for all files from a single call.\r
+ * The list object contains the Win32 process handle at [0], and a file\r
+ * count at [1], which is initialized to the total number of file\r
+ * handles using that list.\r
+ *\r
+ * This function closes whichever handle it is passed, and decrements\r
+ * the file count in the dictionary for the process handle pointed to\r
+ * by this file. On the last close (when the file count reaches zero),\r
+ * this function will wait for the child process and then return its\r
+ * exit code as the result of the close() operation. This permits the\r
+ * files to be closed in any order - it is always the close() of the\r
+ * final handle that will return the exit code.\r
+ *\r
+ * NOTE: This function is currently called with the GIL released.\r
+ * hence we use the GILState API to manage our state.\r
+ */\r
+\r
+static int _PyPclose(FILE *file)\r
+{\r
+ int result;\r
+ DWORD exit_code;\r
+ HANDLE hProcess;\r
+ PyObject *procObj, *hProcessObj, *intObj, *fileObj;\r
+ long file_count;\r
+#ifdef WITH_THREAD\r
+ PyGILState_STATE state;\r
+#endif\r
+\r
+ /* Close the file handle first, to ensure it can't block the\r
+ * child from exiting if it's the last handle.\r
+ */\r
+ result = fclose(file);\r
+#ifdef WITH_THREAD\r
+ state = PyGILState_Ensure();\r
+#endif\r
+ if (_PyPopenProcs) {\r
+ if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&\r
+ (procObj = PyDict_GetItem(_PyPopenProcs,\r
+ fileObj)) != NULL &&\r
+ (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&\r
+ (intObj = PyList_GetItem(procObj,1)) != NULL) {\r
+\r
+ hProcess = PyLong_AsVoidPtr(hProcessObj);\r
+ file_count = PyInt_AsLong(intObj);\r
+\r
+ if (file_count > 1) {\r
+ /* Still other files referencing process */\r
+ file_count--;\r
+ PyList_SetItem(procObj,1,\r
+ PyInt_FromLong(file_count));\r
+ } else {\r
+ /* Last file for this process */\r
+ if (result != EOF &&\r
+ WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&\r
+ GetExitCodeProcess(hProcess, &exit_code)) {\r
+ /* Possible truncation here in 16-bit environments, but\r
+ * real exit codes are just the lower byte in any event.\r
+ */\r
+ result = exit_code;\r
+ } else {\r
+ /* Indicate failure - this will cause the file object\r
+ * to raise an I/O error and translate the last Win32\r
+ * error code from errno. We do have a problem with\r
+ * last errors that overlap the normal errno table,\r
+ * but that's a consistent problem with the file object.\r
+ */\r
+ if (result != EOF) {\r
+ /* If the error wasn't from the fclose(), then\r
+ * set errno for the file object error handling.\r
+ */\r
+ errno = GetLastError();\r
+ }\r
+ result = -1;\r
+ }\r
+\r
+ /* Free up the native handle at this point */\r
+ CloseHandle(hProcess);\r
+ }\r
+\r
+ /* Remove this file pointer from dictionary */\r
+ PyDict_DelItem(_PyPopenProcs, fileObj);\r
+\r
+ if (PyDict_Size(_PyPopenProcs) == 0) {\r
+ Py_DECREF(_PyPopenProcs);\r
+ _PyPopenProcs = NULL;\r
+ }\r
+\r
+ } /* if object retrieval ok */\r
+\r
+ Py_XDECREF(fileObj);\r
+ } /* if _PyPopenProcs */\r
+\r
+#ifdef WITH_THREAD\r
+ PyGILState_Release(state);\r
+#endif\r
+ return result;\r
+}\r
+\r
+#else /* which OS? */\r
+static PyObject *\r
+posix_popen(PyObject *self, PyObject *args)\r
+{\r
+ char *name;\r
+ char *mode = "r";\r
+ int bufsize = -1;\r
+ FILE *fp;\r
+ PyObject *f;\r
+ if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))\r
+ return NULL;\r
+ /* Strip mode of binary or text modifiers */\r
+ if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)\r
+ mode = "r";\r
+ else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)\r
+ mode = "w";\r
+ Py_BEGIN_ALLOW_THREADS\r
+ fp = popen(name, mode);\r
+ Py_END_ALLOW_THREADS\r
+ if (fp == NULL)\r
+ return posix_error();\r
+ f = PyFile_FromFile(fp, name, mode, pclose);\r
+ if (f != NULL)\r
+ PyFile_SetBufSize(f, bufsize);\r
+ return f;\r
+}\r
+\r
+#endif /* PYOS_??? */\r
+#endif /* HAVE_POPEN */\r
+\r
+\r
+#ifdef HAVE_SETUID\r
+PyDoc_STRVAR(posix_setuid__doc__,\r
+"setuid(uid)\n\n\\r
+Set the current process's user id.");\r
+\r
+static PyObject *\r
+posix_setuid(PyObject *self, PyObject *args)\r
+{\r
+ long uid_arg;\r
+ uid_t uid;\r
+ if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg))\r
+ return NULL;\r
+ uid = uid_arg;\r
+ if (uid != uid_arg) {\r
+ PyErr_SetString(PyExc_OverflowError, "user id too big");\r
+ return NULL;\r
+ }\r
+ if (setuid(uid) < 0)\r
+ return posix_error();\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+#endif /* HAVE_SETUID */\r
+\r
+\r
+#ifdef HAVE_SETEUID\r
+PyDoc_STRVAR(posix_seteuid__doc__,\r
+"seteuid(uid)\n\n\\r
+Set the current process's effective user id.");\r
+\r
+static PyObject *\r
+posix_seteuid (PyObject *self, PyObject *args)\r
+{\r
+ long euid_arg;\r
+ uid_t euid;\r
+ if (!PyArg_ParseTuple(args, "l", &euid_arg))\r
+ return NULL;\r
+ euid = euid_arg;\r
+ if (euid != euid_arg) {\r
+ PyErr_SetString(PyExc_OverflowError, "user id too big");\r
+ return NULL;\r
+ }\r
+ if (seteuid(euid) < 0) {\r
+ return posix_error();\r
+ } else {\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+ }\r
+}\r
+#endif /* HAVE_SETEUID */\r
+\r
+#ifdef HAVE_SETEGID\r
+PyDoc_STRVAR(posix_setegid__doc__,\r
+"setegid(gid)\n\n\\r
+Set the current process's effective group id.");\r
+\r
+static PyObject *\r
+posix_setegid (PyObject *self, PyObject *args)\r
+{\r
+ long egid_arg;\r
+ gid_t egid;\r
+ if (!PyArg_ParseTuple(args, "l", &egid_arg))\r
+ return NULL;\r
+ egid = egid_arg;\r
+ if (egid != egid_arg) {\r
+ PyErr_SetString(PyExc_OverflowError, "group id too big");\r
+ return NULL;\r
+ }\r
+ if (setegid(egid) < 0) {\r
+ return posix_error();\r
+ } else {\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+ }\r
+}\r
+#endif /* HAVE_SETEGID */\r
+\r
+#ifdef HAVE_SETREUID\r
+PyDoc_STRVAR(posix_setreuid__doc__,\r
+"setreuid(ruid, euid)\n\n\\r
+Set the current process's real and effective user ids.");\r
+\r
+static PyObject *\r
+posix_setreuid (PyObject *self, PyObject *args)\r
+{\r
+ long ruid_arg, euid_arg;\r
+ uid_t ruid, euid;\r
+ if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg))\r
+ return NULL;\r
+ if (ruid_arg == -1)\r
+ ruid = (uid_t)-1; /* let the compiler choose how -1 fits */\r
+ else\r
+ ruid = ruid_arg; /* otherwise, assign from our long */\r
+ if (euid_arg == -1)\r
+ euid = (uid_t)-1;\r
+ else\r
+ euid = euid_arg;\r
+ if ((euid_arg != -1 && euid != euid_arg) ||\r
+ (ruid_arg != -1 && ruid != ruid_arg)) {\r
+ PyErr_SetString(PyExc_OverflowError, "user id too big");\r
+ return NULL;\r
+ }\r
+ if (setreuid(ruid, euid) < 0) {\r
+ return posix_error();\r
+ } else {\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+ }\r
+}\r
+#endif /* HAVE_SETREUID */\r
+\r
+#ifdef HAVE_SETREGID\r
+PyDoc_STRVAR(posix_setregid__doc__,\r
+"setregid(rgid, egid)\n\n\\r
+Set the current process's real and effective group ids.");\r
+\r
+static PyObject *\r
+posix_setregid (PyObject *self, PyObject *args)\r
+{\r
+ long rgid_arg, egid_arg;\r
+ gid_t rgid, egid;\r
+ if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg))\r
+ return NULL;\r
+ if (rgid_arg == -1)\r
+ rgid = (gid_t)-1; /* let the compiler choose how -1 fits */\r
+ else\r
+ rgid = rgid_arg; /* otherwise, assign from our long */\r
+ if (egid_arg == -1)\r
+ egid = (gid_t)-1;\r
+ else\r
+ egid = egid_arg;\r
+ if ((egid_arg != -1 && egid != egid_arg) ||\r
+ (rgid_arg != -1 && rgid != rgid_arg)) {\r
+ PyErr_SetString(PyExc_OverflowError, "group id too big");\r
+ return NULL;\r
+ }\r
+ if (setregid(rgid, egid) < 0) {\r
+ return posix_error();\r
+ } else {\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+ }\r
+}\r
+#endif /* HAVE_SETREGID */\r
+\r
+#ifdef HAVE_SETGID\r
+PyDoc_STRVAR(posix_setgid__doc__,\r
+"setgid(gid)\n\n\\r
+Set the current process's group id.");\r
+\r
+static PyObject *\r
+posix_setgid(PyObject *self, PyObject *args)\r
+{\r
+ long gid_arg;\r
+ gid_t gid;\r
+ if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg))\r
+ return NULL;\r
+ gid = gid_arg;\r
+ if (gid != gid_arg) {\r
+ PyErr_SetString(PyExc_OverflowError, "group id too big");\r
+ return NULL;\r
+ }\r
+ if (setgid(gid) < 0)\r
+ return posix_error();\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+#endif /* HAVE_SETGID */\r
+\r
+#ifdef HAVE_SETGROUPS\r
+PyDoc_STRVAR(posix_setgroups__doc__,\r
+"setgroups(list)\n\n\\r
+Set the groups of the current process to list.");\r
+\r
+static PyObject *\r
+posix_setgroups(PyObject *self, PyObject *groups)\r
+{\r
+ int i, len;\r
+ gid_t grouplist[MAX_GROUPS];\r
+\r
+ if (!PySequence_Check(groups)) {\r
+ PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");\r
+ return NULL;\r
+ }\r
+ len = PySequence_Size(groups);\r
+ if (len > MAX_GROUPS) {\r
+ PyErr_SetString(PyExc_ValueError, "too many groups");\r
+ return NULL;\r
+ }\r
+ for(i = 0; i < len; i++) {\r
+ PyObject *elem;\r
+ elem = PySequence_GetItem(groups, i);\r
+ if (!elem)\r
+ return NULL;\r
+ if (!PyInt_Check(elem)) {\r
+ if (!PyLong_Check(elem)) {\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "groups must be integers");\r
+ Py_DECREF(elem);\r
+ return NULL;\r
+ } else {\r
+ unsigned long x = PyLong_AsUnsignedLong(elem);\r
+ if (PyErr_Occurred()) {\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "group id too big");\r
+ Py_DECREF(elem);\r
+ return NULL;\r
+ }\r
+ grouplist[i] = x;\r
+ /* read back to see if it fits in gid_t */\r
+ if (grouplist[i] != x) {\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "group id too big");\r
+ Py_DECREF(elem);\r
+ return NULL;\r
+ }\r
+ }\r
+ } else {\r
+ long x = PyInt_AsLong(elem);\r
+ grouplist[i] = x;\r
+ if (grouplist[i] != x) {\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "group id too big");\r
+ Py_DECREF(elem);\r
+ return NULL;\r
+ }\r
+ }\r
+ Py_DECREF(elem);\r
+ }\r
+\r
+ if (setgroups(len, grouplist) < 0)\r
+ return posix_error();\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+#endif /* HAVE_SETGROUPS */\r
+\r
+#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)\r
+static PyObject *\r
+wait_helper(pid_t pid, int status, struct rusage *ru)\r
+{\r
+ PyObject *result;\r
+ static PyObject *struct_rusage;\r
+\r
+ if (pid == -1)\r
+ return posix_error();\r
+\r
+ if (struct_rusage == NULL) {\r
+ PyObject *m = PyImport_ImportModuleNoBlock("resource");\r
+ if (m == NULL)\r
+ return NULL;\r
+ struct_rusage = PyObject_GetAttrString(m, "struct_rusage");\r
+ Py_DECREF(m);\r
+ if (struct_rusage == NULL)\r
+ return NULL;\r
+ }\r
+\r
+ /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */\r
+ result = PyStructSequence_New((PyTypeObject*) struct_rusage);\r
+ if (!result)\r
+ return NULL;\r
+\r
+#ifndef doubletime\r
+#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)\r
+#endif\r
+\r
+ PyStructSequence_SET_ITEM(result, 0,\r
+ PyFloat_FromDouble(doubletime(ru->ru_utime)));\r
+ PyStructSequence_SET_ITEM(result, 1,\r
+ PyFloat_FromDouble(doubletime(ru->ru_stime)));\r
+#define SET_INT(result, index, value)\\r
+ PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))\r
+ SET_INT(result, 2, ru->ru_maxrss);\r
+ SET_INT(result, 3, ru->ru_ixrss);\r
+ SET_INT(result, 4, ru->ru_idrss);\r
+ SET_INT(result, 5, ru->ru_isrss);\r
+ SET_INT(result, 6, ru->ru_minflt);\r
+ SET_INT(result, 7, ru->ru_majflt);\r
+ SET_INT(result, 8, ru->ru_nswap);\r
+ SET_INT(result, 9, ru->ru_inblock);\r
+ SET_INT(result, 10, ru->ru_oublock);\r
+ SET_INT(result, 11, ru->ru_msgsnd);\r
+ SET_INT(result, 12, ru->ru_msgrcv);\r
+ SET_INT(result, 13, ru->ru_nsignals);\r
+ SET_INT(result, 14, ru->ru_nvcsw);\r
+ SET_INT(result, 15, ru->ru_nivcsw);\r
+#undef SET_INT\r
+\r
+ if (PyErr_Occurred()) {\r
+ Py_DECREF(result);\r
+ return NULL;\r
+ }\r
+\r
+ return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);\r
+}\r
+#endif /* HAVE_WAIT3 || HAVE_WAIT4 */\r
+\r
+#ifdef HAVE_WAIT3\r
+PyDoc_STRVAR(posix_wait3__doc__,\r
+"wait3(options) -> (pid, status, rusage)\n\n\\r
+Wait for completion of a child process.");\r
+\r
+static PyObject *\r
+posix_wait3(PyObject *self, PyObject *args)\r
+{\r
+ pid_t pid;\r
+ int options;\r
+ struct rusage ru;\r
+ WAIT_TYPE status;\r
+ WAIT_STATUS_INT(status) = 0;\r
+\r
+ if (!PyArg_ParseTuple(args, "i:wait3", &options))\r
+ return NULL;\r
+\r
+ Py_BEGIN_ALLOW_THREADS\r
+ pid = wait3(&status, options, &ru);\r
+ Py_END_ALLOW_THREADS\r
+\r
+ return wait_helper(pid, WAIT_STATUS_INT(status), &ru);\r
+}\r
+#endif /* HAVE_WAIT3 */\r
+\r
+#ifdef HAVE_WAIT4\r
+PyDoc_STRVAR(posix_wait4__doc__,\r
+"wait4(pid, options) -> (pid, status, rusage)\n\n\\r
+Wait for completion of a given child process.");\r
+\r
+static PyObject *\r
+posix_wait4(PyObject *self, PyObject *args)\r
+{\r
+ pid_t pid;\r
+ int options;\r
+ struct rusage ru;\r
+ WAIT_TYPE status;\r
+ WAIT_STATUS_INT(status) = 0;\r
+\r
+ if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))\r
+ return NULL;\r
+\r
+ Py_BEGIN_ALLOW_THREADS\r
+ pid = wait4(pid, &status, options, &ru);\r
+ Py_END_ALLOW_THREADS\r
+\r
+ return wait_helper(pid, WAIT_STATUS_INT(status), &ru);\r
+}\r
+#endif /* HAVE_WAIT4 */\r
+\r
+#ifdef HAVE_WAITPID\r
+PyDoc_STRVAR(posix_waitpid__doc__,\r
+"waitpid(pid, options) -> (pid, status)\n\n\\r
+Wait for completion of a given child process.");\r
+\r
+static PyObject *\r
+posix_waitpid(PyObject *self, PyObject *args)\r
+{\r
+ pid_t pid;\r
+ int options;\r
+ WAIT_TYPE status;\r
+ WAIT_STATUS_INT(status) = 0;\r
+\r
+ if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))\r
+ return NULL;\r
+ Py_BEGIN_ALLOW_THREADS\r
+ pid = waitpid(pid, &status, options);\r
+ Py_END_ALLOW_THREADS\r
+ if (pid == -1)\r
+ return posix_error();\r
+\r
+ return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));\r
+}\r
+\r
+#elif defined(HAVE_CWAIT)\r
+\r
+/* MS C has a variant of waitpid() that's usable for most purposes. */\r
+PyDoc_STRVAR(posix_waitpid__doc__,\r
+"waitpid(pid, options) -> (pid, status << 8)\n\n"\r
+"Wait for completion of a given process. options is ignored on Windows.");\r
+\r
+static PyObject *\r
+posix_waitpid(PyObject *self, PyObject *args)\r
+{\r
+ Py_intptr_t pid;\r
+ int status, options;\r
+\r
+ if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))\r
+ return NULL;\r
+ Py_BEGIN_ALLOW_THREADS\r
+ pid = _cwait(&status, pid, options);\r
+ Py_END_ALLOW_THREADS\r
+ if (pid == -1)\r
+ return posix_error();\r
+\r
+ /* shift the status left a byte so this is more like the POSIX waitpid */\r
+ return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);\r
+}\r
+#endif /* HAVE_WAITPID || HAVE_CWAIT */\r
+\r
+#ifdef HAVE_WAIT\r
+PyDoc_STRVAR(posix_wait__doc__,\r
+"wait() -> (pid, status)\n\n\\r
+Wait for completion of a child process.");\r
+\r
+static PyObject *\r
+posix_wait(PyObject *self, PyObject *noargs)\r
+{\r
+ pid_t pid;\r
+ WAIT_TYPE status;\r
+ WAIT_STATUS_INT(status) = 0;\r
+\r
+ Py_BEGIN_ALLOW_THREADS\r
+ pid = wait(&status);\r
+ Py_END_ALLOW_THREADS\r
+ if (pid == -1)\r
+ return posix_error();\r
+\r
+ return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));\r
+}\r
+#endif\r
+\r
+\r
+PyDoc_STRVAR(posix_lstat__doc__,\r
+"lstat(path) -> stat result\n\n\\r
+Like stat(path), but do not follow symbolic links.");\r
+\r
+static PyObject *\r
+posix_lstat(PyObject *self, PyObject *args)\r
+{\r
+#ifdef HAVE_LSTAT\r
+ return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);\r
+#else /* !HAVE_LSTAT */\r
+ return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);\r
+#endif /* !HAVE_LSTAT */\r
+}\r
+\r
+\r
+#ifdef HAVE_READLINK\r
+PyDoc_STRVAR(posix_readlink__doc__,\r
+"readlink(path) -> path\n\n\\r
+Return a string representing the path to which the symbolic link points.");\r
+\r
+static PyObject *\r
+posix_readlink(PyObject *self, PyObject *args)\r
+{\r
+ PyObject* v;\r
+ char buf[MAXPATHLEN];\r
+ char *path;\r
+ int n;\r
+#ifdef Py_USING_UNICODE\r
+ int arg_is_unicode = 0;\r
+#endif\r
+\r
+ if (!PyArg_ParseTuple(args, "et:readlink",\r
+ Py_FileSystemDefaultEncoding, &path))\r
+ return NULL;\r
+#ifdef Py_USING_UNICODE\r
+ v = PySequence_GetItem(args, 0);\r
+ if (v == NULL) {\r
+ PyMem_Free(path);\r
+ return NULL;\r
+ }\r
+\r
+ if (PyUnicode_Check(v)) {\r
+ arg_is_unicode = 1;\r
+ }\r
+ Py_DECREF(v);\r
+#endif\r
+\r
+ Py_BEGIN_ALLOW_THREADS\r
+ n = readlink(path, buf, (int) sizeof buf);\r
+ Py_END_ALLOW_THREADS\r
+ if (n < 0)\r
+ return posix_error_with_allocated_filename(path);\r
+\r
+ PyMem_Free(path);\r
+ v = PyString_FromStringAndSize(buf, n);\r
+#ifdef Py_USING_UNICODE\r
+ if (arg_is_unicode) {\r
+ PyObject *w;\r
+\r
+ w = PyUnicode_FromEncodedObject(v,\r
+ Py_FileSystemDefaultEncoding,\r
+ "strict");\r
+ if (w != NULL) {\r
+ Py_DECREF(v);\r
+ v = w;\r
+ }\r
+ else {\r
+ /* fall back to the original byte string, as\r
+ discussed in patch #683592 */\r
+ PyErr_Clear();\r
+ }\r
+ }\r
+#endif\r
+ return v;\r
+}\r
+#endif /* HAVE_READLINK */\r
+\r
+\r
+#ifdef HAVE_SYMLINK\r
+PyDoc_STRVAR(posix_symlink__doc__,\r
+"symlink(src, dst)\n\n\\r
+Create a symbolic link pointing to src named dst.");\r
+\r
+static PyObject *\r
+posix_symlink(PyObject *self, PyObject *args)\r
+{\r
+ return posix_2str(args, "etet:symlink", symlink);\r
+}\r
+#endif /* HAVE_SYMLINK */\r
+\r
+\r
+#ifdef HAVE_TIMES\r
+#if defined(PYCC_VACPP) && defined(PYOS_OS2)\r
+static long\r
+system_uptime(void)\r
+{\r
+ ULONG value = 0;\r
+\r
+ Py_BEGIN_ALLOW_THREADS\r
+ DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));\r
+ Py_END_ALLOW_THREADS\r
+\r
+ return value;\r
+}\r
+\r
+static PyObject *\r
+posix_times(PyObject *self, PyObject *noargs)\r
+{\r
+ /* Currently Only Uptime is Provided -- Others Later */\r
+ return Py_BuildValue("ddddd",\r
+ (double)0 /* t.tms_utime / HZ */,\r
+ (double)0 /* t.tms_stime / HZ */,\r
+ (double)0 /* t.tms_cutime / HZ */,\r
+ (double)0 /* t.tms_cstime / HZ */,\r
+ (double)system_uptime() / 1000);\r
+}\r
+#else /* not OS2 */\r
+#define NEED_TICKS_PER_SECOND\r
+static long ticks_per_second = -1;\r
+static PyObject *\r
+posix_times(PyObject *self, PyObject *noargs)\r
+{\r
+ struct tms t;\r
+ clock_t c;\r
+ errno = 0;\r
+ c = times(&t);\r
+ if (c == (clock_t) -1)\r
+ return posix_error();\r
+ return Py_BuildValue("ddddd",\r
+ (double)t.tms_utime / ticks_per_second,\r
+ (double)t.tms_stime / ticks_per_second,\r
+ (double)t.tms_cutime / ticks_per_second,\r
+ (double)t.tms_cstime / ticks_per_second,\r
+ (double)c / ticks_per_second);\r
+}\r
+#endif /* not OS2 */\r
+#endif /* HAVE_TIMES */\r
+\r
+\r
+#ifdef HAVE_TIMES\r
+PyDoc_STRVAR(posix_times__doc__,\r
+"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\\r
+Return a tuple of floating point numbers indicating process times.");\r
+#endif\r
+\r
+\r
+#ifdef HAVE_GETSID\r
+PyDoc_STRVAR(posix_getsid__doc__,\r
+"getsid(pid) -> sid\n\n\\r
+Call the system call getsid().");\r
+\r
+static PyObject *\r
+posix_getsid(PyObject *self, PyObject *args)\r
+{\r
+ pid_t pid;\r
+ int sid;\r
+ if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))\r
+ return NULL;\r
+ sid = getsid(pid);\r
+ if (sid < 0)\r
+ return posix_error();\r
+ return PyInt_FromLong((long)sid);\r
+}\r
+#endif /* HAVE_GETSID */\r
+\r
+\r
+#ifdef HAVE_SETSID\r
+PyDoc_STRVAR(posix_setsid__doc__,\r
+"setsid()\n\n\\r
+Call the system call setsid().");\r
+\r
+static PyObject *\r
+posix_setsid(PyObject *self, PyObject *noargs)\r
+{\r
+ if (setsid() < 0)\r
+ return posix_error();\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+#endif /* HAVE_SETSID */\r
+\r
+#ifdef HAVE_SETPGID\r
+PyDoc_STRVAR(posix_setpgid__doc__,\r
+"setpgid(pid, pgrp)\n\n\\r
+Call the system call setpgid().");\r
+\r
+static PyObject *\r
+posix_setpgid(PyObject *self, PyObject *args)\r
+{\r
+ pid_t pid;\r
+ int pgrp;\r
+ if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))\r
+ return NULL;\r
+ if (setpgid(pid, pgrp) < 0)\r
+ return posix_error();\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+#endif /* HAVE_SETPGID */\r
+\r
+\r
+#ifdef HAVE_TCGETPGRP\r
+PyDoc_STRVAR(posix_tcgetpgrp__doc__,\r
+"tcgetpgrp(fd) -> pgid\n\n\\r
+Return the process group associated with the terminal given by a fd.");\r
+\r
+static PyObject *\r
+posix_tcgetpgrp(PyObject *self, PyObject *args)\r
+{\r
+ int fd;\r
+ pid_t pgid;\r
+ if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))\r
+ return NULL;\r
+ pgid = tcgetpgrp(fd);\r
+ if (pgid < 0)\r
+ return posix_error();\r
+ return PyLong_FromPid(pgid);\r
+}\r
+#endif /* HAVE_TCGETPGRP */\r
+\r
+\r
+#ifdef HAVE_TCSETPGRP\r
+PyDoc_STRVAR(posix_tcsetpgrp__doc__,\r
+"tcsetpgrp(fd, pgid)\n\n\\r
+Set the process group associated with the terminal given by a fd.");\r
+\r
+static PyObject *\r
+posix_tcsetpgrp(PyObject *self, PyObject *args)\r
+{\r
+ int fd;\r
+ pid_t pgid;\r
+ if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))\r
+ return NULL;\r
+ if (tcsetpgrp(fd, pgid) < 0)\r
+ return posix_error();\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+#endif /* HAVE_TCSETPGRP */\r
+\r
+/* Functions acting on file descriptors */\r
+\r
+PyDoc_STRVAR(posix_open__doc__,\r
+"open(filename, flag [, mode=0777]) -> fd\n\n\\r
+Open a file (for low level IO).");\r
+\r
+static PyObject *\r
+posix_open(PyObject *self, PyObject *args)\r
+{\r
+ char *file = NULL;\r
+ int flag;\r
+ int mode = 0777;\r
+ int fd;\r
+\r
+ if (!PyArg_ParseTuple(args, "eti|i",\r
+ Py_FileSystemDefaultEncoding, &file,\r
+ &flag, &mode))\r
+ return NULL;\r
+\r
+ Py_BEGIN_ALLOW_THREADS\r
+ fd = open(file, flag, mode);\r
+ Py_END_ALLOW_THREADS\r
+ if (fd < 0)\r
+ return posix_error_with_allocated_filename(file);\r
+ PyMem_Free(file);\r
+ return PyInt_FromLong((long)fd);\r
+}\r
+\r
+\r
+PyDoc_STRVAR(posix_close__doc__,\r
+"close(fd)\n\n\\r
+Close a file descriptor (for low level IO).");\r
+\r
+static PyObject *\r
+posix_close(PyObject *self, PyObject *args)\r
+{\r
+ int fd, res;\r
+ if (!PyArg_ParseTuple(args, "i:close", &fd))\r
+ return NULL;\r
+ if (!_PyVerify_fd(fd))\r
+ return posix_error();\r
+ Py_BEGIN_ALLOW_THREADS\r
+ res = close(fd);\r
+ Py_END_ALLOW_THREADS\r
+ if (res < 0)\r
+ return posix_error();\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+\r
+\r
+PyDoc_STRVAR(posix_closerange__doc__,\r
+"closerange(fd_low, fd_high)\n\n\\r
+Closes all file descriptors in [fd_low, fd_high), ignoring errors.");\r
+\r
+static PyObject *\r
+posix_closerange(PyObject *self, PyObject *args)\r
+{\r
+ int fd_from, fd_to, i;\r
+ if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))\r
+ return NULL;\r
+ Py_BEGIN_ALLOW_THREADS\r
+ for (i = fd_from; i < fd_to; i++)\r
+ if (_PyVerify_fd(i))\r
+ close(i);\r
+ Py_END_ALLOW_THREADS\r
+ Py_RETURN_NONE;\r
+}\r
+\r
+\r
+PyDoc_STRVAR(posix_dup__doc__,\r
+"dup(fd) -> fd2\n\n\\r
+Return a duplicate of a file descriptor.");\r
+\r
+static PyObject *\r
+posix_dup(PyObject *self, PyObject *args)\r
+{\r
+ int fd;\r
+ if (!PyArg_ParseTuple(args, "i:dup", &fd))\r
+ return NULL;\r
+ if (!_PyVerify_fd(fd))\r
+ return posix_error();\r
+ Py_BEGIN_ALLOW_THREADS\r
+ fd = dup(fd);\r
+ Py_END_ALLOW_THREADS\r
+ if (fd < 0)\r
+ return posix_error();\r
+ return PyInt_FromLong((long)fd);\r
+}\r
+\r
+\r
+PyDoc_STRVAR(posix_dup2__doc__,\r
+"dup2(old_fd, new_fd)\n\n\\r
+Duplicate file descriptor.");\r
+\r
+static PyObject *\r
+posix_dup2(PyObject *self, PyObject *args)\r
+{\r
+ int fd, fd2, res;\r
+ if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))\r
+ return NULL;\r
+ if (!_PyVerify_fd_dup2(fd, fd2))\r
+ return posix_error();\r
+ Py_BEGIN_ALLOW_THREADS\r
+ res = dup2(fd, fd2);\r
+ Py_END_ALLOW_THREADS\r
+ if (res < 0)\r
+ return posix_error();\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+\r
+\r
+PyDoc_STRVAR(posix_lseek__doc__,\r
+"lseek(fd, pos, how) -> newpos\n\n\\r
+Set the current position of a file descriptor.");\r
+\r
+static PyObject *\r
+posix_lseek(PyObject *self, PyObject *args)\r
+{\r
+ int fd, how;\r
+ off_t pos, res;\r
+ PyObject *posobj;\r
+ if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))\r
+ return NULL;\r
+#ifdef SEEK_SET\r
+ /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */\r
+ switch (how) {\r
+ case 0: how = SEEK_SET; break;\r
+ case 1: how = SEEK_CUR; break;\r
+ case 2: how = SEEK_END; break;\r
+ }\r
+#endif /* SEEK_END */\r
+\r
+#if !defined(HAVE_LARGEFILE_SUPPORT)\r
+ pos = PyInt_AsLong(posobj);\r
+#else\r
+ pos = PyLong_Check(posobj) ?\r
+ PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);\r
+#endif\r
+ if (PyErr_Occurred())\r
+ return NULL;\r
+\r
+ if (!_PyVerify_fd(fd))\r
+ return posix_error();\r
+ Py_BEGIN_ALLOW_THREADS\r
+ res = lseek(fd, pos, how);\r
+ Py_END_ALLOW_THREADS\r
+ if (res < 0)\r
+ return posix_error();\r
+\r
+#if !defined(HAVE_LARGEFILE_SUPPORT)\r
+ return PyInt_FromLong(res);\r
+#else\r
+ return PyLong_FromLongLong(res);\r
+#endif\r
+}\r
+\r
+\r
+PyDoc_STRVAR(posix_read__doc__,\r
+"read(fd, buffersize) -> string\n\n\\r
+Read a file descriptor.");\r
+\r
+static PyObject *\r
+posix_read(PyObject *self, PyObject *args)\r
+{\r
+ int fd, size, n;\r
+ PyObject *buffer;\r
+ if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))\r
+ return NULL;\r
+ if (size < 0) {\r
+ errno = EINVAL;\r
+ return posix_error();\r
+ }\r
+ buffer = PyString_FromStringAndSize((char *)NULL, size);\r
+ if (buffer == NULL)\r
+ return NULL;\r
+ if (!_PyVerify_fd(fd)) {\r
+ Py_DECREF(buffer);\r
+ return posix_error();\r
+ }\r
+ Py_BEGIN_ALLOW_THREADS\r
+ n = read(fd, PyString_AsString(buffer), size);\r
+ Py_END_ALLOW_THREADS\r
+ if (n < 0) {\r
+ Py_DECREF(buffer);\r
+ return posix_error();\r
+ }\r
+ if (n != size)\r
+ _PyString_Resize(&buffer, n);\r
+ return buffer;\r
+}\r
+\r
+\r
+PyDoc_STRVAR(posix_write__doc__,\r
+"write(fd, string) -> byteswritten\n\n\\r
+Write a string to a file descriptor.");\r
+\r
+static PyObject *\r
+posix_write(PyObject *self, PyObject *args)\r
+{\r
+ Py_buffer pbuf;\r
+ int fd;\r
+ Py_ssize_t size;\r
+\r
+ if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))\r
+ return NULL;\r
+ if (!_PyVerify_fd(fd)) {\r
+ PyBuffer_Release(&pbuf);\r
+ return posix_error();\r
+ }\r
+ Py_BEGIN_ALLOW_THREADS\r
+ size = write(fd, pbuf.buf, (size_t)pbuf.len);\r
+ Py_END_ALLOW_THREADS\r
+ PyBuffer_Release(&pbuf);\r
+ if (size < 0)\r
+ return posix_error();\r
+ return PyInt_FromSsize_t(size);\r
+}\r
+\r
+\r
+PyDoc_STRVAR(posix_fstat__doc__,\r
+"fstat(fd) -> stat result\n\n\\r
+Like stat(), but for an open file descriptor.");\r
+\r
+static PyObject *\r
+posix_fstat(PyObject *self, PyObject *args)\r
+{\r
+ int fd;\r
+ STRUCT_STAT st;\r
+ int res;\r
+ if (!PyArg_ParseTuple(args, "i:fstat", &fd))\r
+ return NULL;\r
+ if (!_PyVerify_fd(fd))\r
+ return posix_error();\r
+ Py_BEGIN_ALLOW_THREADS\r
+ res = FSTAT(fd, &st);\r
+ Py_END_ALLOW_THREADS\r
+ if (res != 0) {\r
+ return posix_error();\r
+ }\r
+\r
+ return _pystat_fromstructstat(&st);\r
+}\r
+\r
+\r
+PyDoc_STRVAR(posix_fdopen__doc__,\r
+"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\\r
+Return an open file object connected to a file descriptor.");\r
+\r
+static PyObject *\r
+posix_fdopen(PyObject *self, PyObject *args)\r
+{\r
+ int fd;\r
+ char *orgmode = "r";\r
+ int bufsize = -1;\r
+ FILE *fp;\r
+ PyObject *f;\r
+ char *mode;\r
+ if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))\r
+ return NULL;\r
+\r
+ /* Sanitize mode. See fileobject.c */\r
+ mode = PyMem_MALLOC(strlen(orgmode)+3);\r
+ if (!mode) {\r
+ PyErr_NoMemory();\r
+ return NULL;\r
+ }\r
+ strcpy(mode, orgmode);\r
+ if (_PyFile_SanitizeMode(mode)) {\r
+ PyMem_FREE(mode);\r
+ return NULL;\r
+ }\r
+ if (!_PyVerify_fd(fd))\r
+ return posix_error();\r
+ Py_BEGIN_ALLOW_THREADS\r
+#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)\r
+ if (mode[0] == 'a') {\r
+ /* try to make sure the O_APPEND flag is set */\r
+ int flags;\r
+ flags = fcntl(fd, F_GETFL);\r
+ if (flags != -1)\r
+ fcntl(fd, F_SETFL, flags | O_APPEND);\r
+ fp = fdopen(fd, mode);\r
+ if (fp == NULL && flags != -1)\r
+ /* restore old mode if fdopen failed */\r
+ fcntl(fd, F_SETFL, flags);\r
+ } else {\r
+ fp = fdopen(fd, mode);\r
+ }\r
+#else\r
+ fp = fdopen(fd, mode);\r
+#endif\r
+ Py_END_ALLOW_THREADS\r
+ PyMem_FREE(mode);\r
+ if (fp == NULL)\r
+ return posix_error();\r
+ f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);\r
+ if (f != NULL)\r
+ PyFile_SetBufSize(f, bufsize);\r
+ return f;\r
+}\r
+\r
+PyDoc_STRVAR(posix_isatty__doc__,\r
+"isatty(fd) -> bool\n\n\\r
+Return True if the file descriptor 'fd' is an open file descriptor\n\\r
+connected to the slave end of a terminal.");\r
+\r
+static PyObject *\r
+posix_isatty(PyObject *self, PyObject *args)\r
+{\r
+ int fd;\r
+ if (!PyArg_ParseTuple(args, "i:isatty", &fd))\r
+ return NULL;\r
+ if (!_PyVerify_fd(fd))\r
+ return PyBool_FromLong(0);\r
+ return PyBool_FromLong(isatty(fd));\r
+}\r
+\r
+#ifdef HAVE_PIPE\r
+PyDoc_STRVAR(posix_pipe__doc__,\r
+"pipe() -> (read_end, write_end)\n\n\\r
+Create a pipe.");\r
+\r
+static PyObject *\r
+posix_pipe(PyObject *self, PyObject *noargs)\r
+{\r
+#if defined(PYOS_OS2)\r
+ HFILE read, write;\r
+ APIRET rc;\r
+\r
+ Py_BEGIN_ALLOW_THREADS\r
+ rc = DosCreatePipe( &read, &write, 4096);\r
+ Py_END_ALLOW_THREADS\r
+ if (rc != NO_ERROR)\r
+ return os2_error(rc);\r
+\r
+ return Py_BuildValue("(ii)", read, write);\r
+#else\r
+#if !defined(MS_WINDOWS)\r
+ int fds[2];\r
+ int res;\r
+ Py_BEGIN_ALLOW_THREADS\r
+ res = pipe(fds);\r
+ Py_END_ALLOW_THREADS\r
+ if (res != 0)\r
+ return posix_error();\r
+ return Py_BuildValue("(ii)", fds[0], fds[1]);\r
+#else /* MS_WINDOWS */\r
+ HANDLE read, write;\r
+ int read_fd, write_fd;\r
+ BOOL ok;\r
+ Py_BEGIN_ALLOW_THREADS\r
+ ok = CreatePipe(&read, &write, NULL, 0);\r
+ Py_END_ALLOW_THREADS\r
+ if (!ok)\r
+ return win32_error("CreatePipe", NULL);\r
+ read_fd = _open_osfhandle((Py_intptr_t)read, 0);\r
+ write_fd = _open_osfhandle((Py_intptr_t)write, 1);\r
+ return Py_BuildValue("(ii)", read_fd, write_fd);\r
+#endif /* MS_WINDOWS */\r
+#endif\r
+}\r
+#endif /* HAVE_PIPE */\r
+\r
+\r
+#ifdef HAVE_MKFIFO\r
+PyDoc_STRVAR(posix_mkfifo__doc__,\r
+"mkfifo(filename [, mode=0666])\n\n\\r
+Create a FIFO (a POSIX named pipe).");\r
+\r
+static PyObject *\r
+posix_mkfifo(PyObject *self, PyObject *args)\r
+{\r
+ char *filename;\r
+ int mode = 0666;\r
+ int res;\r
+ if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))\r
+ return NULL;\r
+ Py_BEGIN_ALLOW_THREADS\r
+ res = mkfifo(filename, mode);\r
+ Py_END_ALLOW_THREADS\r
+ if (res < 0)\r
+ return posix_error();\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+#endif\r
+\r
+\r
+#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)\r
+PyDoc_STRVAR(posix_mknod__doc__,\r
+"mknod(filename [, mode=0600, device])\n\n\\r
+Create a filesystem node (file, device special file or named pipe)\n\\r
+named filename. mode specifies both the permissions to use and the\n\\r
+type of node to be created, being combined (bitwise OR) with one of\n\\r
+S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\\r
+device defines the newly created device special file (probably using\n\\r
+os.makedev()), otherwise it is ignored.");\r
+\r
+\r
+static PyObject *\r
+posix_mknod(PyObject *self, PyObject *args)\r
+{\r
+ char *filename;\r
+ int mode = 0600;\r
+ int device = 0;\r
+ int res;\r
+ if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))\r
+ return NULL;\r
+ Py_BEGIN_ALLOW_THREADS\r
+ res = mknod(filename, mode, device);\r
+ Py_END_ALLOW_THREADS\r
+ if (res < 0)\r
+ return posix_error();\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+#endif\r
+\r
+#ifdef HAVE_DEVICE_MACROS\r
+PyDoc_STRVAR(posix_major__doc__,\r
+"major(device) -> major number\n\\r
+Extracts a device major number from a raw device number.");\r
+\r
+static PyObject *\r
+posix_major(PyObject *self, PyObject *args)\r
+{\r
+ int device;\r
+ if (!PyArg_ParseTuple(args, "i:major", &device))\r
+ return NULL;\r
+ return PyInt_FromLong((long)major(device));\r
+}\r
+\r
+PyDoc_STRVAR(posix_minor__doc__,\r
+"minor(device) -> minor number\n\\r
+Extracts a device minor number from a raw device number.");\r
+\r
+static PyObject *\r
+posix_minor(PyObject *self, PyObject *args)\r
+{\r
+ int device;\r
+ if (!PyArg_ParseTuple(args, "i:minor", &device))\r
+ return NULL;\r
+ return PyInt_FromLong((long)minor(device));\r
+}\r
+\r
+PyDoc_STRVAR(posix_makedev__doc__,\r
+"makedev(major, minor) -> device number\n\\r
+Composes a raw device number from the major and minor device numbers.");\r
+\r
+static PyObject *\r
+posix_makedev(PyObject *self, PyObject *args)\r
+{\r
+ int major, minor;\r
+ if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))\r
+ return NULL;\r
+ return PyInt_FromLong((long)makedev(major, minor));\r
+}\r
+#endif /* device macros */\r
+\r
+\r
+#ifdef HAVE_FTRUNCATE\r
+PyDoc_STRVAR(posix_ftruncate__doc__,\r
+"ftruncate(fd, length)\n\n\\r
+Truncate a file to a specified length.");\r
+\r
+static PyObject *\r
+posix_ftruncate(PyObject *self, PyObject *args)\r
+{\r
+ int fd;\r
+ off_t length;\r
+ int res;\r
+ PyObject *lenobj;\r
+\r
+ if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))\r
+ return NULL;\r
+\r
+#if !defined(HAVE_LARGEFILE_SUPPORT)\r
+ length = PyInt_AsLong(lenobj);\r
+#else\r
+ length = PyLong_Check(lenobj) ?\r
+ PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);\r
+#endif\r
+ if (PyErr_Occurred())\r
+ return NULL;\r
+\r
+ Py_BEGIN_ALLOW_THREADS\r
+ res = ftruncate(fd, length);\r
+ Py_END_ALLOW_THREADS\r
+ if (res < 0)\r
+ return posix_error();\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+#endif\r
+\r
+#ifdef HAVE_PUTENV\r
+PyDoc_STRVAR(posix_putenv__doc__,\r
+"putenv(key, value)\n\n\\r
+Change or add an environment variable.");\r
+\r
+/* Save putenv() parameters as values here, so we can collect them when they\r
+ * get re-set with another call for the same key. */\r
+static PyObject *posix_putenv_garbage;\r
+\r
+static PyObject *\r
+posix_putenv(PyObject *self, PyObject *args)\r
+{\r
+ char *s1, *s2;\r
+ char *newenv;\r
+ PyObject *newstr;\r
+ size_t len;\r
+\r
+ if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))\r
+ return NULL;\r
+\r
+#if defined(PYOS_OS2)\r
+ if (stricmp(s1, "BEGINLIBPATH") == 0) {\r
+ APIRET rc;\r
+\r
+ rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);\r
+ if (rc != NO_ERROR)\r
+ return os2_error(rc);\r
+\r
+ } else if (stricmp(s1, "ENDLIBPATH") == 0) {\r
+ APIRET rc;\r
+\r
+ rc = DosSetExtLIBPATH(s2, END_LIBPATH);\r
+ if (rc != NO_ERROR)\r
+ return os2_error(rc);\r
+ } else {\r
+#endif\r
+\r
+ /* XXX This can leak memory -- not easy to fix :-( */\r
+ len = strlen(s1) + strlen(s2) + 2;\r
+ /* len includes space for a trailing \0; the size arg to\r
+ PyString_FromStringAndSize does not count that */\r
+ newstr = PyString_FromStringAndSize(NULL, (int)len - 1);\r
+ if (newstr == NULL)\r
+ return PyErr_NoMemory();\r
+ newenv = PyString_AS_STRING(newstr);\r
+ PyOS_snprintf(newenv, len, "%s=%s", s1, s2);\r
+ if (putenv(newenv)) {\r
+ Py_DECREF(newstr);\r
+ posix_error();\r
+ return NULL;\r
+ }\r
+ /* Install the first arg and newstr in posix_putenv_garbage;\r
+ * this will cause previous value to be collected. This has to\r
+ * happen after the real putenv() call because the old value\r
+ * was still accessible until then. */\r
+ if (PyDict_SetItem(posix_putenv_garbage,\r
+ PyTuple_GET_ITEM(args, 0), newstr)) {\r
+ /* really not much we can do; just leak */\r
+ PyErr_Clear();\r
+ }\r
+ else {\r
+ Py_DECREF(newstr);\r
+ }\r
+\r
+#if defined(PYOS_OS2)\r
+ }\r
+#endif\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+#endif /* putenv */\r
+\r
+#ifdef HAVE_UNSETENV\r
+PyDoc_STRVAR(posix_unsetenv__doc__,\r
+"unsetenv(key)\n\n\\r
+Delete an environment variable.");\r
+\r
+static PyObject *\r
+posix_unsetenv(PyObject *self, PyObject *args)\r
+{\r
+ char *s1;\r
+\r
+ if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))\r
+ return NULL;\r
+\r
+ unsetenv(s1);\r
+\r
+ /* Remove the key from posix_putenv_garbage;\r
+ * this will cause it to be collected. This has to\r
+ * happen after the real unsetenv() call because the\r
+ * old value was still accessible until then.\r
+ */\r
+ if (PyDict_DelItem(posix_putenv_garbage,\r
+ PyTuple_GET_ITEM(args, 0))) {\r
+ /* really not much we can do; just leak */\r
+ PyErr_Clear();\r
+ }\r
+\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+#endif /* unsetenv */\r
+\r
+PyDoc_STRVAR(posix_strerror__doc__,\r
+"strerror(code) -> string\n\n\\r
+Translate an error code to a message string.");\r
+\r
+static PyObject *\r
+posix_strerror(PyObject *self, PyObject *args)\r
+{\r
+ int code;\r
+ char *message;\r
+ if (!PyArg_ParseTuple(args, "i:strerror", &code))\r
+ return NULL;\r
+ message = strerror(code);\r
+ if (message == NULL) {\r
+ PyErr_SetString(PyExc_ValueError,\r
+ "strerror() argument out of range");\r
+ return NULL;\r
+ }\r
+ return PyString_FromString(message);\r
+}\r
+\r
+\r
+#ifdef HAVE_SYS_WAIT_H\r
+\r
+#ifdef WCOREDUMP\r
+PyDoc_STRVAR(posix_WCOREDUMP__doc__,\r
+"WCOREDUMP(status) -> bool\n\n\\r
+Return True if the process returning 'status' was dumped to a core file.");\r
+\r
+static PyObject *\r
+posix_WCOREDUMP(PyObject *self, PyObject *args)\r
+{\r
+ WAIT_TYPE status;\r
+ WAIT_STATUS_INT(status) = 0;\r
+\r
+ if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))\r
+ return NULL;\r
+\r
+ return PyBool_FromLong(WCOREDUMP(status));\r
+}\r
+#endif /* WCOREDUMP */\r
+\r
+#ifdef WIFCONTINUED\r
+PyDoc_STRVAR(posix_WIFCONTINUED__doc__,\r
+"WIFCONTINUED(status) -> bool\n\n\\r
+Return True if the process returning 'status' was continued from a\n\\r
+job control stop.");\r
+\r
+static PyObject *\r
+posix_WIFCONTINUED(PyObject *self, PyObject *args)\r
+{\r
+ WAIT_TYPE status;\r
+ WAIT_STATUS_INT(status) = 0;\r
+\r
+ if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))\r
+ return NULL;\r
+\r
+ return PyBool_FromLong(WIFCONTINUED(status));\r
+}\r
+#endif /* WIFCONTINUED */\r
+\r
+#ifdef WIFSTOPPED\r
+PyDoc_STRVAR(posix_WIFSTOPPED__doc__,\r
+"WIFSTOPPED(status) -> bool\n\n\\r
+Return True if the process returning 'status' was stopped.");\r
+\r
+static PyObject *\r
+posix_WIFSTOPPED(PyObject *self, PyObject *args)\r
+{\r
+ WAIT_TYPE status;\r
+ WAIT_STATUS_INT(status) = 0;\r
+\r
+ if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))\r
+ return NULL;\r
+\r
+ return PyBool_FromLong(WIFSTOPPED(status));\r
+}\r
+#endif /* WIFSTOPPED */\r
+\r
+#ifdef WIFSIGNALED\r
+PyDoc_STRVAR(posix_WIFSIGNALED__doc__,\r
+"WIFSIGNALED(status) -> bool\n\n\\r
+Return True if the process returning 'status' was terminated by a signal.");\r
+\r
+static PyObject *\r
+posix_WIFSIGNALED(PyObject *self, PyObject *args)\r
+{\r
+ WAIT_TYPE status;\r
+ WAIT_STATUS_INT(status) = 0;\r
+\r
+ if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))\r
+ return NULL;\r
+\r
+ return PyBool_FromLong(WIFSIGNALED(status));\r
+}\r
+#endif /* WIFSIGNALED */\r
+\r
+#ifdef WIFEXITED\r
+PyDoc_STRVAR(posix_WIFEXITED__doc__,\r
+"WIFEXITED(status) -> bool\n\n\\r
+Return true if the process returning 'status' exited using the exit()\n\\r
+system call.");\r
+\r
+static PyObject *\r
+posix_WIFEXITED(PyObject *self, PyObject *args)\r
+{\r
+ WAIT_TYPE status;\r
+ WAIT_STATUS_INT(status) = 0;\r
+\r
+ if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))\r
+ return NULL;\r
+\r
+ return PyBool_FromLong(WIFEXITED(status));\r
+}\r
+#endif /* WIFEXITED */\r
+\r
+#ifdef WEXITSTATUS\r
+PyDoc_STRVAR(posix_WEXITSTATUS__doc__,\r
+"WEXITSTATUS(status) -> integer\n\n\\r
+Return the process return code from 'status'.");\r
+\r
+static PyObject *\r
+posix_WEXITSTATUS(PyObject *self, PyObject *args)\r
+{\r
+ WAIT_TYPE status;\r
+ WAIT_STATUS_INT(status) = 0;\r
+\r
+ if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))\r
+ return NULL;\r
+\r
+ return Py_BuildValue("i", WEXITSTATUS(status));\r
+}\r
+#endif /* WEXITSTATUS */\r
+\r
+#ifdef WTERMSIG\r
+PyDoc_STRVAR(posix_WTERMSIG__doc__,\r
+"WTERMSIG(status) -> integer\n\n\\r
+Return the signal that terminated the process that provided the 'status'\n\\r
+value.");\r
+\r
+static PyObject *\r
+posix_WTERMSIG(PyObject *self, PyObject *args)\r
+{\r
+ WAIT_TYPE status;\r
+ WAIT_STATUS_INT(status) = 0;\r
+\r
+ if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))\r
+ return NULL;\r
+\r
+ return Py_BuildValue("i", WTERMSIG(status));\r
+}\r
+#endif /* WTERMSIG */\r
+\r
+#ifdef WSTOPSIG\r
+PyDoc_STRVAR(posix_WSTOPSIG__doc__,\r
+"WSTOPSIG(status) -> integer\n\n\\r
+Return the signal that stopped the process that provided\n\\r
+the 'status' value.");\r
+\r
+static PyObject *\r
+posix_WSTOPSIG(PyObject *self, PyObject *args)\r
+{\r
+ WAIT_TYPE status;\r
+ WAIT_STATUS_INT(status) = 0;\r
+\r
+ if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))\r
+ return NULL;\r
+\r
+ return Py_BuildValue("i", WSTOPSIG(status));\r
+}\r
+#endif /* WSTOPSIG */\r
+\r
+#endif /* HAVE_SYS_WAIT_H */\r
+\r
+\r
+#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)\r
+#ifdef _SCO_DS\r
+/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the\r
+ needed definitions in sys/statvfs.h */\r
+#define _SVID3\r
+#endif\r
+#include <sys/statvfs.h>\r
+\r
+static PyObject*\r
+_pystatvfs_fromstructstatvfs(struct statvfs st) {\r
+ PyObject *v = PyStructSequence_New(&StatVFSResultType);\r
+ if (v == NULL)\r
+ return NULL;\r
+\r
+#if !defined(HAVE_LARGEFILE_SUPPORT)\r
+ PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));\r
+ PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));\r
+ PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));\r
+ PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));\r
+ PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));\r
+ PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));\r
+ PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));\r
+ PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));\r
+ PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));\r
+ PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));\r
+#else\r
+ PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));\r
+ PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));\r
+ PyStructSequence_SET_ITEM(v, 2,\r
+ PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));\r
+ PyStructSequence_SET_ITEM(v, 3,\r
+ PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));\r
+ PyStructSequence_SET_ITEM(v, 4,\r
+ PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));\r
+ PyStructSequence_SET_ITEM(v, 5,\r
+ PyLong_FromLongLong((PY_LONG_LONG) st.f_files));\r
+ PyStructSequence_SET_ITEM(v, 6,\r
+ PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));\r
+ PyStructSequence_SET_ITEM(v, 7,\r
+ PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));\r
+ PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));\r
+ PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));\r
+#endif\r
+\r
+ return v;\r
+}\r
+\r
+PyDoc_STRVAR(posix_fstatvfs__doc__,\r
+"fstatvfs(fd) -> statvfs result\n\n\\r
+Perform an fstatvfs system call on the given fd.");\r
+\r
+static PyObject *\r
+posix_fstatvfs(PyObject *self, PyObject *args)\r
+{\r
+ int fd, res;\r
+ struct statvfs st;\r
+\r
+ if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))\r
+ return NULL;\r
+ Py_BEGIN_ALLOW_THREADS\r
+ res = fstatvfs(fd, &st);\r
+ Py_END_ALLOW_THREADS\r
+ if (res != 0)\r
+ return posix_error();\r
+\r
+ return _pystatvfs_fromstructstatvfs(st);\r
+}\r
+#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */\r
+\r
+\r
+#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)\r
+#include <sys/statvfs.h>\r
+\r
+PyDoc_STRVAR(posix_statvfs__doc__,\r
+"statvfs(path) -> statvfs result\n\n\\r
+Perform a statvfs system call on the given path.");\r
+\r
+static PyObject *\r
+posix_statvfs(PyObject *self, PyObject *args)\r
+{\r
+ char *path;\r
+ int res;\r
+ struct statvfs st;\r
+ if (!PyArg_ParseTuple(args, "s:statvfs", &path))\r
+ return NULL;\r
+ Py_BEGIN_ALLOW_THREADS\r
+ res = statvfs(path, &st);\r
+ Py_END_ALLOW_THREADS\r
+ if (res != 0)\r
+ return posix_error_with_filename(path);\r
+\r
+ return _pystatvfs_fromstructstatvfs(st);\r
+}\r
+#endif /* HAVE_STATVFS */\r
+\r
+\r
+#ifdef HAVE_TEMPNAM\r
+PyDoc_STRVAR(posix_tempnam__doc__,\r
+"tempnam([dir[, prefix]]) -> string\n\n\\r
+Return a unique name for a temporary file.\n\\r
+The directory and a prefix may be specified as strings; they may be omitted\n\\r
+or None if not needed.");\r
+\r
+static PyObject *\r
+posix_tempnam(PyObject *self, PyObject *args)\r
+{\r
+ PyObject *result = NULL;\r
+ char *dir = NULL;\r
+ char *pfx = NULL;\r
+ char *name;\r
+\r
+ if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))\r
+ return NULL;\r
+\r
+ if (PyErr_Warn(PyExc_RuntimeWarning,\r
+ "tempnam is a potential security risk to your program") < 0)\r
+ return NULL;\r
+\r
+ if (PyErr_WarnPy3k("tempnam has been removed in 3.x; "\r
+ "use the tempfile module", 1) < 0)\r
+ return NULL;\r
+\r
+ name = tempnam(dir, pfx);\r
+ if (name == NULL)\r
+ return PyErr_NoMemory();\r
+ result = PyString_FromString(name);\r
+ free(name);\r
+ return result;\r
+}\r
+#endif\r
+\r
+\r
+#ifdef HAVE_TMPFILE\r
+PyDoc_STRVAR(posix_tmpfile__doc__,\r
+"tmpfile() -> file object\n\n\\r
+Create a temporary file with no directory entries.");\r
+\r
+static PyObject *\r
+posix_tmpfile(PyObject *self, PyObject *noargs)\r
+{\r
+ FILE *fp;\r
+\r
+ if (PyErr_WarnPy3k("tmpfile has been removed in 3.x; "\r
+ "use the tempfile module", 1) < 0)\r
+ return NULL;\r
+\r
+ fp = tmpfile();\r
+ if (fp == NULL)\r
+ return posix_error();\r
+ return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);\r
+}\r
+#endif\r
+\r
+\r
+#ifdef HAVE_TMPNAM\r
+PyDoc_STRVAR(posix_tmpnam__doc__,\r
+"tmpnam() -> string\n\n\\r
+Return a unique name for a temporary file.");\r
+\r
+static PyObject *\r
+posix_tmpnam(PyObject *self, PyObject *noargs)\r
+{\r
+ char buffer[L_tmpnam];\r
+ char *name;\r
+\r
+ if (PyErr_Warn(PyExc_RuntimeWarning,\r
+ "tmpnam is a potential security risk to your program") < 0)\r
+ return NULL;\r
+\r
+ if (PyErr_WarnPy3k("tmpnam has been removed in 3.x; "\r
+ "use the tempfile module", 1) < 0)\r
+ return NULL;\r
+\r
+#ifdef USE_TMPNAM_R\r
+ name = tmpnam_r(buffer);\r
+#else\r
+ name = tmpnam(buffer);\r
+#endif\r
+ if (name == NULL) {\r
+ PyObject *err = Py_BuildValue("is", 0,\r
+#ifdef USE_TMPNAM_R\r
+ "unexpected NULL from tmpnam_r"\r
+#else\r
+ "unexpected NULL from tmpnam"\r
+#endif\r
+ );\r
+ PyErr_SetObject(PyExc_OSError, err);\r
+ Py_XDECREF(err);\r
+ return NULL;\r
+ }\r
+ return PyString_FromString(buffer);\r
+}\r
+#endif\r
+\r
+\r
+/* This is used for fpathconf(), pathconf(), confstr() and sysconf().\r
+ * It maps strings representing configuration variable names to\r
+ * integer values, allowing those functions to be called with the\r
+ * magic names instead of polluting the module's namespace with tons of\r
+ * rarely-used constants. There are three separate tables that use\r
+ * these definitions.\r
+ *\r
+ * This code is always included, even if none of the interfaces that\r
+ * need it are included. The #if hackery needed to avoid it would be\r
+ * sufficiently pervasive that it's not worth the loss of readability.\r
+ */\r
+struct constdef {\r
+ char *name;\r
+ long value;\r
+};\r
+\r
+#ifndef UEFI_C_SOURCE\r
+static int\r
+conv_confname(PyObject *arg, int *valuep, struct constdef *table,\r
+ size_t tablesize)\r
+{\r
+ if (PyInt_Check(arg)) {\r
+ *valuep = PyInt_AS_LONG(arg);\r
+ return 1;\r
+ }\r
+ if (PyString_Check(arg)) {\r
+ /* look up the value in the table using a binary search */\r
+ size_t lo = 0;\r
+ size_t mid;\r
+ size_t hi = tablesize;\r
+ int cmp;\r
+ char *confname = PyString_AS_STRING(arg);\r
+ while (lo < hi) {\r
+ mid = (lo + hi) / 2;\r
+ cmp = strcmp(confname, table[mid].name);\r
+ if (cmp < 0)\r
+ hi = mid;\r
+ else if (cmp > 0)\r
+ lo = mid + 1;\r
+ else {\r
+ *valuep = table[mid].value;\r
+ return 1;\r
+ }\r
+ }\r
+ PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");\r
+ }\r
+ else\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "configuration names must be strings or integers");\r
+ return 0;\r
+}\r
+#endif /* UEFI_C_SOURCE */\r
+\r
+#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)\r
+static struct constdef posix_constants_pathconf[] = {\r
+#ifdef _PC_ABI_AIO_XFER_MAX\r
+ {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},\r
+#endif\r
+#ifdef _PC_ABI_ASYNC_IO\r
+ {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},\r
+#endif\r
+#ifdef _PC_ASYNC_IO\r
+ {"PC_ASYNC_IO", _PC_ASYNC_IO},\r
+#endif\r
+#ifdef _PC_CHOWN_RESTRICTED\r
+ {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},\r
+#endif\r
+#ifdef _PC_FILESIZEBITS\r
+ {"PC_FILESIZEBITS", _PC_FILESIZEBITS},\r
+#endif\r
+#ifdef _PC_LAST\r
+ {"PC_LAST", _PC_LAST},\r
+#endif\r
+#ifdef _PC_LINK_MAX\r
+ {"PC_LINK_MAX", _PC_LINK_MAX},\r
+#endif\r
+#ifdef _PC_MAX_CANON\r
+ {"PC_MAX_CANON", _PC_MAX_CANON},\r
+#endif\r
+#ifdef _PC_MAX_INPUT\r
+ {"PC_MAX_INPUT", _PC_MAX_INPUT},\r
+#endif\r
+#ifdef _PC_NAME_MAX\r
+ {"PC_NAME_MAX", _PC_NAME_MAX},\r
+#endif\r
+#ifdef _PC_NO_TRUNC\r
+ {"PC_NO_TRUNC", _PC_NO_TRUNC},\r
+#endif\r
+#ifdef _PC_PATH_MAX\r
+ {"PC_PATH_MAX", _PC_PATH_MAX},\r
+#endif\r
+#ifdef _PC_PIPE_BUF\r
+ {"PC_PIPE_BUF", _PC_PIPE_BUF},\r
+#endif\r
+#ifdef _PC_PRIO_IO\r
+ {"PC_PRIO_IO", _PC_PRIO_IO},\r
+#endif\r
+#ifdef _PC_SOCK_MAXBUF\r
+ {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},\r
+#endif\r
+#ifdef _PC_SYNC_IO\r
+ {"PC_SYNC_IO", _PC_SYNC_IO},\r
+#endif\r
+#ifdef _PC_VDISABLE\r
+ {"PC_VDISABLE", _PC_VDISABLE},\r
+#endif\r
+};\r
+\r
+static int\r
+conv_path_confname(PyObject *arg, int *valuep)\r
+{\r
+ return conv_confname(arg, valuep, posix_constants_pathconf,\r
+ sizeof(posix_constants_pathconf)\r
+ / sizeof(struct constdef));\r
+}\r
+#endif\r
+\r
+#ifdef HAVE_FPATHCONF\r
+PyDoc_STRVAR(posix_fpathconf__doc__,\r
+"fpathconf(fd, name) -> integer\n\n\\r
+Return the configuration limit name for the file descriptor fd.\n\\r
+If there is no limit, return -1.");\r
+\r
+static PyObject *\r
+posix_fpathconf(PyObject *self, PyObject *args)\r
+{\r
+ PyObject *result = NULL;\r
+ int name, fd;\r
+\r
+ if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,\r
+ conv_path_confname, &name)) {\r
+ long limit;\r
+\r
+ errno = 0;\r
+ limit = fpathconf(fd, name);\r
+ if (limit == -1 && errno != 0)\r
+ posix_error();\r
+ else\r
+ result = PyInt_FromLong(limit);\r
+ }\r
+ return result;\r
+}\r
+#endif\r
+\r
+\r
+#ifdef HAVE_PATHCONF\r
+PyDoc_STRVAR(posix_pathconf__doc__,\r
+"pathconf(path, name) -> integer\n\n\\r
+Return the configuration limit name for the file or directory path.\n\\r
+If there is no limit, return -1.");\r
+\r
+static PyObject *\r
+posix_pathconf(PyObject *self, PyObject *args)\r
+{\r
+ PyObject *result = NULL;\r
+ int name;\r
+ char *path;\r
+\r
+ if (PyArg_ParseTuple(args, "sO&:pathconf", &path,\r
+ conv_path_confname, &name)) {\r
+ long limit;\r
+\r
+ errno = 0;\r
+ limit = pathconf(path, name);\r
+ if (limit == -1 && errno != 0) {\r
+ if (errno == EINVAL)\r
+ /* could be a path or name problem */\r
+ posix_error();\r
+ else\r
+ posix_error_with_filename(path);\r
+ }\r
+ else\r
+ result = PyInt_FromLong(limit);\r
+ }\r
+ return result;\r
+}\r
+#endif\r
+\r
+#ifdef HAVE_CONFSTR\r
+static struct constdef posix_constants_confstr[] = {\r
+#ifdef _CS_ARCHITECTURE\r
+ {"CS_ARCHITECTURE", _CS_ARCHITECTURE},\r
+#endif\r
+#ifdef _CS_HOSTNAME\r
+ {"CS_HOSTNAME", _CS_HOSTNAME},\r
+#endif\r
+#ifdef _CS_HW_PROVIDER\r
+ {"CS_HW_PROVIDER", _CS_HW_PROVIDER},\r
+#endif\r
+#ifdef _CS_HW_SERIAL\r
+ {"CS_HW_SERIAL", _CS_HW_SERIAL},\r
+#endif\r
+#ifdef _CS_INITTAB_NAME\r
+ {"CS_INITTAB_NAME", _CS_INITTAB_NAME},\r
+#endif\r
+#ifdef _CS_LFS64_CFLAGS\r
+ {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},\r
+#endif\r
+#ifdef _CS_LFS64_LDFLAGS\r
+ {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},\r
+#endif\r
+#ifdef _CS_LFS64_LIBS\r
+ {"CS_LFS64_LIBS", _CS_LFS64_LIBS},\r
+#endif\r
+#ifdef _CS_LFS64_LINTFLAGS\r
+ {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},\r
+#endif\r
+#ifdef _CS_LFS_CFLAGS\r
+ {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},\r
+#endif\r
+#ifdef _CS_LFS_LDFLAGS\r
+ {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},\r
+#endif\r
+#ifdef _CS_LFS_LIBS\r
+ {"CS_LFS_LIBS", _CS_LFS_LIBS},\r
+#endif\r
+#ifdef _CS_LFS_LINTFLAGS\r
+ {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},\r
+#endif\r
+#ifdef _CS_MACHINE\r
+ {"CS_MACHINE", _CS_MACHINE},\r
+#endif\r
+#ifdef _CS_PATH\r
+ {"CS_PATH", _CS_PATH},\r
+#endif\r
+#ifdef _CS_RELEASE\r
+ {"CS_RELEASE", _CS_RELEASE},\r
+#endif\r
+#ifdef _CS_SRPC_DOMAIN\r
+ {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},\r
+#endif\r
+#ifdef _CS_SYSNAME\r
+ {"CS_SYSNAME", _CS_SYSNAME},\r
+#endif\r
+#ifdef _CS_VERSION\r
+ {"CS_VERSION", _CS_VERSION},\r
+#endif\r
+#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS\r
+ {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},\r
+#endif\r
+#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS\r
+ {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},\r
+#endif\r
+#ifdef _CS_XBS5_ILP32_OFF32_LIBS\r
+ {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},\r
+#endif\r
+#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS\r
+ {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},\r
+#endif\r
+#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS\r
+ {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},\r
+#endif\r
+#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS\r
+ {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},\r
+#endif\r
+#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS\r
+ {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},\r
+#endif\r
+#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS\r
+ {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},\r
+#endif\r
+#ifdef _CS_XBS5_LP64_OFF64_CFLAGS\r
+ {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},\r
+#endif\r
+#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS\r
+ {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},\r
+#endif\r
+#ifdef _CS_XBS5_LP64_OFF64_LIBS\r
+ {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},\r
+#endif\r
+#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS\r
+ {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},\r
+#endif\r
+#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS\r
+ {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},\r
+#endif\r
+#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS\r
+ {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},\r
+#endif\r
+#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS\r
+ {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},\r
+#endif\r
+#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS\r
+ {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},\r
+#endif\r
+#ifdef _MIPS_CS_AVAIL_PROCESSORS\r
+ {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},\r
+#endif\r
+#ifdef _MIPS_CS_BASE\r
+ {"MIPS_CS_BASE", _MIPS_CS_BASE},\r
+#endif\r
+#ifdef _MIPS_CS_HOSTID\r
+ {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},\r
+#endif\r
+#ifdef _MIPS_CS_HW_NAME\r
+ {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},\r
+#endif\r
+#ifdef _MIPS_CS_NUM_PROCESSORS\r
+ {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},\r
+#endif\r
+#ifdef _MIPS_CS_OSREL_MAJ\r
+ {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},\r
+#endif\r
+#ifdef _MIPS_CS_OSREL_MIN\r
+ {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},\r
+#endif\r
+#ifdef _MIPS_CS_OSREL_PATCH\r
+ {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},\r
+#endif\r
+#ifdef _MIPS_CS_OS_NAME\r
+ {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},\r
+#endif\r
+#ifdef _MIPS_CS_OS_PROVIDER\r
+ {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},\r
+#endif\r
+#ifdef _MIPS_CS_PROCESSORS\r
+ {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},\r
+#endif\r
+#ifdef _MIPS_CS_SERIAL\r
+ {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},\r
+#endif\r
+#ifdef _MIPS_CS_VENDOR\r
+ {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},\r
+#endif\r
+};\r
+\r
+static int\r
+conv_confstr_confname(PyObject *arg, int *valuep)\r
+{\r
+ return conv_confname(arg, valuep, posix_constants_confstr,\r
+ sizeof(posix_constants_confstr)\r
+ / sizeof(struct constdef));\r
+}\r
+\r
+PyDoc_STRVAR(posix_confstr__doc__,\r
+"confstr(name) -> string\n\n\\r
+Return a string-valued system configuration variable.");\r
+\r
+static PyObject *\r
+posix_confstr(PyObject *self, PyObject *args)\r
+{\r
+ PyObject *result = NULL;\r
+ int name;\r
+ char buffer[256];\r
+\r
+ if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {\r
+ int len;\r
+\r
+ errno = 0;\r
+ len = confstr(name, buffer, sizeof(buffer));\r
+ if (len == 0) {\r
+ if (errno) {\r
+ posix_error();\r
+ }\r
+ else {\r
+ result = Py_None;\r
+ Py_INCREF(Py_None);\r
+ }\r
+ }\r
+ else {\r
+ if ((unsigned int)len >= sizeof(buffer)) {\r
+ result = PyString_FromStringAndSize(NULL, len-1);\r
+ if (result != NULL)\r
+ confstr(name, PyString_AS_STRING(result), len);\r
+ }\r
+ else\r
+ result = PyString_FromStringAndSize(buffer, len-1);\r
+ }\r
+ }\r
+ return result;\r
+}\r
+#endif\r
+\r
+\r
+#ifdef HAVE_SYSCONF\r
+static struct constdef posix_constants_sysconf[] = {\r
+#ifdef _SC_2_CHAR_TERM\r
+ {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},\r
+#endif\r
+#ifdef _SC_2_C_BIND\r
+ {"SC_2_C_BIND", _SC_2_C_BIND},\r
+#endif\r
+#ifdef _SC_2_C_DEV\r
+ {"SC_2_C_DEV", _SC_2_C_DEV},\r
+#endif\r
+#ifdef _SC_2_C_VERSION\r
+ {"SC_2_C_VERSION", _SC_2_C_VERSION},\r
+#endif\r
+#ifdef _SC_2_FORT_DEV\r
+ {"SC_2_FORT_DEV", _SC_2_FORT_DEV},\r
+#endif\r
+#ifdef _SC_2_FORT_RUN\r
+ {"SC_2_FORT_RUN", _SC_2_FORT_RUN},\r
+#endif\r
+#ifdef _SC_2_LOCALEDEF\r
+ {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},\r
+#endif\r
+#ifdef _SC_2_SW_DEV\r
+ {"SC_2_SW_DEV", _SC_2_SW_DEV},\r
+#endif\r
+#ifdef _SC_2_UPE\r
+ {"SC_2_UPE", _SC_2_UPE},\r
+#endif\r
+#ifdef _SC_2_VERSION\r
+ {"SC_2_VERSION", _SC_2_VERSION},\r
+#endif\r
+#ifdef _SC_ABI_ASYNCHRONOUS_IO\r
+ {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},\r
+#endif\r
+#ifdef _SC_ACL\r
+ {"SC_ACL", _SC_ACL},\r
+#endif\r
+#ifdef _SC_AIO_LISTIO_MAX\r
+ {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},\r
+#endif\r
+#ifdef _SC_AIO_MAX\r
+ {"SC_AIO_MAX", _SC_AIO_MAX},\r
+#endif\r
+#ifdef _SC_AIO_PRIO_DELTA_MAX\r
+ {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},\r
+#endif\r
+#ifdef _SC_ARG_MAX\r
+ {"SC_ARG_MAX", _SC_ARG_MAX},\r
+#endif\r
+#ifdef _SC_ASYNCHRONOUS_IO\r
+ {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},\r
+#endif\r
+#ifdef _SC_ATEXIT_MAX\r
+ {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},\r
+#endif\r
+#ifdef _SC_AUDIT\r
+ {"SC_AUDIT", _SC_AUDIT},\r
+#endif\r
+#ifdef _SC_AVPHYS_PAGES\r
+ {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},\r
+#endif\r
+#ifdef _SC_BC_BASE_MAX\r
+ {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},\r
+#endif\r
+#ifdef _SC_BC_DIM_MAX\r
+ {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},\r
+#endif\r
+#ifdef _SC_BC_SCALE_MAX\r
+ {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},\r
+#endif\r
+#ifdef _SC_BC_STRING_MAX\r
+ {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},\r
+#endif\r
+#ifdef _SC_CAP\r
+ {"SC_CAP", _SC_CAP},\r
+#endif\r
+#ifdef _SC_CHARCLASS_NAME_MAX\r
+ {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},\r
+#endif\r
+#ifdef _SC_CHAR_BIT\r
+ {"SC_CHAR_BIT", _SC_CHAR_BIT},\r
+#endif\r
+#ifdef _SC_CHAR_MAX\r
+ {"SC_CHAR_MAX", _SC_CHAR_MAX},\r
+#endif\r
+#ifdef _SC_CHAR_MIN\r
+ {"SC_CHAR_MIN", _SC_CHAR_MIN},\r
+#endif\r
+#ifdef _SC_CHILD_MAX\r
+ {"SC_CHILD_MAX", _SC_CHILD_MAX},\r
+#endif\r
+#ifdef _SC_CLK_TCK\r
+ {"SC_CLK_TCK", _SC_CLK_TCK},\r
+#endif\r
+#ifdef _SC_COHER_BLKSZ\r
+ {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},\r
+#endif\r
+#ifdef _SC_COLL_WEIGHTS_MAX\r
+ {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},\r
+#endif\r
+#ifdef _SC_DCACHE_ASSOC\r
+ {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},\r
+#endif\r
+#ifdef _SC_DCACHE_BLKSZ\r
+ {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},\r
+#endif\r
+#ifdef _SC_DCACHE_LINESZ\r
+ {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},\r
+#endif\r
+#ifdef _SC_DCACHE_SZ\r
+ {"SC_DCACHE_SZ", _SC_DCACHE_SZ},\r
+#endif\r
+#ifdef _SC_DCACHE_TBLKSZ\r
+ {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},\r
+#endif\r
+#ifdef _SC_DELAYTIMER_MAX\r
+ {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},\r
+#endif\r
+#ifdef _SC_EQUIV_CLASS_MAX\r
+ {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},\r
+#endif\r
+#ifdef _SC_EXPR_NEST_MAX\r
+ {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},\r
+#endif\r
+#ifdef _SC_FSYNC\r
+ {"SC_FSYNC", _SC_FSYNC},\r
+#endif\r
+#ifdef _SC_GETGR_R_SIZE_MAX\r
+ {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},\r
+#endif\r
+#ifdef _SC_GETPW_R_SIZE_MAX\r
+ {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},\r
+#endif\r
+#ifdef _SC_ICACHE_ASSOC\r
+ {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},\r
+#endif\r
+#ifdef _SC_ICACHE_BLKSZ\r
+ {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},\r
+#endif\r
+#ifdef _SC_ICACHE_LINESZ\r
+ {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},\r
+#endif\r
+#ifdef _SC_ICACHE_SZ\r
+ {"SC_ICACHE_SZ", _SC_ICACHE_SZ},\r
+#endif\r
+#ifdef _SC_INF\r
+ {"SC_INF", _SC_INF},\r
+#endif\r
+#ifdef _SC_INT_MAX\r
+ {"SC_INT_MAX", _SC_INT_MAX},\r
+#endif\r
+#ifdef _SC_INT_MIN\r
+ {"SC_INT_MIN", _SC_INT_MIN},\r
+#endif\r
+#ifdef _SC_IOV_MAX\r
+ {"SC_IOV_MAX", _SC_IOV_MAX},\r
+#endif\r
+#ifdef _SC_IP_SECOPTS\r
+ {"SC_IP_SECOPTS", _SC_IP_SECOPTS},\r
+#endif\r
+#ifdef _SC_JOB_CONTROL\r
+ {"SC_JOB_CONTROL", _SC_JOB_CONTROL},\r
+#endif\r
+#ifdef _SC_KERN_POINTERS\r
+ {"SC_KERN_POINTERS", _SC_KERN_POINTERS},\r
+#endif\r
+#ifdef _SC_KERN_SIM\r
+ {"SC_KERN_SIM", _SC_KERN_SIM},\r
+#endif\r
+#ifdef _SC_LINE_MAX\r
+ {"SC_LINE_MAX", _SC_LINE_MAX},\r
+#endif\r
+#ifdef _SC_LOGIN_NAME_MAX\r
+ {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},\r
+#endif\r
+#ifdef _SC_LOGNAME_MAX\r
+ {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},\r
+#endif\r
+#ifdef _SC_LONG_BIT\r
+ {"SC_LONG_BIT", _SC_LONG_BIT},\r
+#endif\r
+#ifdef _SC_MAC\r
+ {"SC_MAC", _SC_MAC},\r
+#endif\r
+#ifdef _SC_MAPPED_FILES\r
+ {"SC_MAPPED_FILES", _SC_MAPPED_FILES},\r
+#endif\r
+#ifdef _SC_MAXPID\r
+ {"SC_MAXPID", _SC_MAXPID},\r
+#endif\r
+#ifdef _SC_MB_LEN_MAX\r
+ {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},\r
+#endif\r
+#ifdef _SC_MEMLOCK\r
+ {"SC_MEMLOCK", _SC_MEMLOCK},\r
+#endif\r
+#ifdef _SC_MEMLOCK_RANGE\r
+ {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},\r
+#endif\r
+#ifdef _SC_MEMORY_PROTECTION\r
+ {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},\r
+#endif\r
+#ifdef _SC_MESSAGE_PASSING\r
+ {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},\r
+#endif\r
+#ifdef _SC_MMAP_FIXED_ALIGNMENT\r
+ {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},\r
+#endif\r
+#ifdef _SC_MQ_OPEN_MAX\r
+ {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},\r
+#endif\r
+#ifdef _SC_MQ_PRIO_MAX\r
+ {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},\r
+#endif\r
+#ifdef _SC_NACLS_MAX\r
+ {"SC_NACLS_MAX", _SC_NACLS_MAX},\r
+#endif\r
+#ifdef _SC_NGROUPS_MAX\r
+ {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},\r
+#endif\r
+#ifdef _SC_NL_ARGMAX\r
+ {"SC_NL_ARGMAX", _SC_NL_ARGMAX},\r
+#endif\r
+#ifdef _SC_NL_LANGMAX\r
+ {"SC_NL_LANGMAX", _SC_NL_LANGMAX},\r
+#endif\r
+#ifdef _SC_NL_MSGMAX\r
+ {"SC_NL_MSGMAX", _SC_NL_MSGMAX},\r
+#endif\r
+#ifdef _SC_NL_NMAX\r
+ {"SC_NL_NMAX", _SC_NL_NMAX},\r
+#endif\r
+#ifdef _SC_NL_SETMAX\r
+ {"SC_NL_SETMAX", _SC_NL_SETMAX},\r
+#endif\r
+#ifdef _SC_NL_TEXTMAX\r
+ {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},\r
+#endif\r
+#ifdef _SC_NPROCESSORS_CONF\r
+ {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},\r
+#endif\r
+#ifdef _SC_NPROCESSORS_ONLN\r
+ {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},\r
+#endif\r
+#ifdef _SC_NPROC_CONF\r
+ {"SC_NPROC_CONF", _SC_NPROC_CONF},\r
+#endif\r
+#ifdef _SC_NPROC_ONLN\r
+ {"SC_NPROC_ONLN", _SC_NPROC_ONLN},\r
+#endif\r
+#ifdef _SC_NZERO\r
+ {"SC_NZERO", _SC_NZERO},\r
+#endif\r
+#ifdef _SC_OPEN_MAX\r
+ {"SC_OPEN_MAX", _SC_OPEN_MAX},\r
+#endif\r
+#ifdef _SC_PAGESIZE\r
+ {"SC_PAGESIZE", _SC_PAGESIZE},\r
+#endif\r
+#ifdef _SC_PAGE_SIZE\r
+ {"SC_PAGE_SIZE", _SC_PAGE_SIZE},\r
+#endif\r
+#ifdef _SC_PASS_MAX\r
+ {"SC_PASS_MAX", _SC_PASS_MAX},\r
+#endif\r
+#ifdef _SC_PHYS_PAGES\r
+ {"SC_PHYS_PAGES", _SC_PHYS_PAGES},\r
+#endif\r
+#ifdef _SC_PII\r
+ {"SC_PII", _SC_PII},\r
+#endif\r
+#ifdef _SC_PII_INTERNET\r
+ {"SC_PII_INTERNET", _SC_PII_INTERNET},\r
+#endif\r
+#ifdef _SC_PII_INTERNET_DGRAM\r
+ {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},\r
+#endif\r
+#ifdef _SC_PII_INTERNET_STREAM\r
+ {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},\r
+#endif\r
+#ifdef _SC_PII_OSI\r
+ {"SC_PII_OSI", _SC_PII_OSI},\r
+#endif\r
+#ifdef _SC_PII_OSI_CLTS\r
+ {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},\r
+#endif\r
+#ifdef _SC_PII_OSI_COTS\r
+ {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},\r
+#endif\r
+#ifdef _SC_PII_OSI_M\r
+ {"SC_PII_OSI_M", _SC_PII_OSI_M},\r
+#endif\r
+#ifdef _SC_PII_SOCKET\r
+ {"SC_PII_SOCKET", _SC_PII_SOCKET},\r
+#endif\r
+#ifdef _SC_PII_XTI\r
+ {"SC_PII_XTI", _SC_PII_XTI},\r
+#endif\r
+#ifdef _SC_POLL\r
+ {"SC_POLL", _SC_POLL},\r
+#endif\r
+#ifdef _SC_PRIORITIZED_IO\r
+ {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},\r
+#endif\r
+#ifdef _SC_PRIORITY_SCHEDULING\r
+ {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},\r
+#endif\r
+#ifdef _SC_REALTIME_SIGNALS\r
+ {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},\r
+#endif\r
+#ifdef _SC_RE_DUP_MAX\r
+ {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},\r
+#endif\r
+#ifdef _SC_RTSIG_MAX\r
+ {"SC_RTSIG_MAX", _SC_RTSIG_MAX},\r
+#endif\r
+#ifdef _SC_SAVED_IDS\r
+ {"SC_SAVED_IDS", _SC_SAVED_IDS},\r
+#endif\r
+#ifdef _SC_SCHAR_MAX\r
+ {"SC_SCHAR_MAX", _SC_SCHAR_MAX},\r
+#endif\r
+#ifdef _SC_SCHAR_MIN\r
+ {"SC_SCHAR_MIN", _SC_SCHAR_MIN},\r
+#endif\r
+#ifdef _SC_SELECT\r
+ {"SC_SELECT", _SC_SELECT},\r
+#endif\r
+#ifdef _SC_SEMAPHORES\r
+ {"SC_SEMAPHORES", _SC_SEMAPHORES},\r
+#endif\r
+#ifdef _SC_SEM_NSEMS_MAX\r
+ {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},\r
+#endif\r
+#ifdef _SC_SEM_VALUE_MAX\r
+ {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},\r
+#endif\r
+#ifdef _SC_SHARED_MEMORY_OBJECTS\r
+ {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},\r
+#endif\r
+#ifdef _SC_SHRT_MAX\r
+ {"SC_SHRT_MAX", _SC_SHRT_MAX},\r
+#endif\r
+#ifdef _SC_SHRT_MIN\r
+ {"SC_SHRT_MIN", _SC_SHRT_MIN},\r
+#endif\r
+#ifdef _SC_SIGQUEUE_MAX\r
+ {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},\r
+#endif\r
+#ifdef _SC_SIGRT_MAX\r
+ {"SC_SIGRT_MAX", _SC_SIGRT_MAX},\r
+#endif\r
+#ifdef _SC_SIGRT_MIN\r
+ {"SC_SIGRT_MIN", _SC_SIGRT_MIN},\r
+#endif\r
+#ifdef _SC_SOFTPOWER\r
+ {"SC_SOFTPOWER", _SC_SOFTPOWER},\r
+#endif\r
+#ifdef _SC_SPLIT_CACHE\r
+ {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},\r
+#endif\r
+#ifdef _SC_SSIZE_MAX\r
+ {"SC_SSIZE_MAX", _SC_SSIZE_MAX},\r
+#endif\r
+#ifdef _SC_STACK_PROT\r
+ {"SC_STACK_PROT", _SC_STACK_PROT},\r
+#endif\r
+#ifdef _SC_STREAM_MAX\r
+ {"SC_STREAM_MAX", _SC_STREAM_MAX},\r
+#endif\r
+#ifdef _SC_SYNCHRONIZED_IO\r
+ {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},\r
+#endif\r
+#ifdef _SC_THREADS\r
+ {"SC_THREADS", _SC_THREADS},\r
+#endif\r
+#ifdef _SC_THREAD_ATTR_STACKADDR\r
+ {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},\r
+#endif\r
+#ifdef _SC_THREAD_ATTR_STACKSIZE\r
+ {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},\r
+#endif\r
+#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS\r
+ {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},\r
+#endif\r
+#ifdef _SC_THREAD_KEYS_MAX\r
+ {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},\r
+#endif\r
+#ifdef _SC_THREAD_PRIORITY_SCHEDULING\r
+ {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},\r
+#endif\r
+#ifdef _SC_THREAD_PRIO_INHERIT\r
+ {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},\r
+#endif\r
+#ifdef _SC_THREAD_PRIO_PROTECT\r
+ {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},\r
+#endif\r
+#ifdef _SC_THREAD_PROCESS_SHARED\r
+ {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},\r
+#endif\r
+#ifdef _SC_THREAD_SAFE_FUNCTIONS\r
+ {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},\r
+#endif\r
+#ifdef _SC_THREAD_STACK_MIN\r
+ {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},\r
+#endif\r
+#ifdef _SC_THREAD_THREADS_MAX\r
+ {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},\r
+#endif\r
+#ifdef _SC_TIMERS\r
+ {"SC_TIMERS", _SC_TIMERS},\r
+#endif\r
+#ifdef _SC_TIMER_MAX\r
+ {"SC_TIMER_MAX", _SC_TIMER_MAX},\r
+#endif\r
+#ifdef _SC_TTY_NAME_MAX\r
+ {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},\r
+#endif\r
+#ifdef _SC_TZNAME_MAX\r
+ {"SC_TZNAME_MAX", _SC_TZNAME_MAX},\r
+#endif\r
+#ifdef _SC_T_IOV_MAX\r
+ {"SC_T_IOV_MAX", _SC_T_IOV_MAX},\r
+#endif\r
+#ifdef _SC_UCHAR_MAX\r
+ {"SC_UCHAR_MAX", _SC_UCHAR_MAX},\r
+#endif\r
+#ifdef _SC_UINT_MAX\r
+ {"SC_UINT_MAX", _SC_UINT_MAX},\r
+#endif\r
+#ifdef _SC_UIO_MAXIOV\r
+ {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},\r
+#endif\r
+#ifdef _SC_ULONG_MAX\r
+ {"SC_ULONG_MAX", _SC_ULONG_MAX},\r
+#endif\r
+#ifdef _SC_USHRT_MAX\r
+ {"SC_USHRT_MAX", _SC_USHRT_MAX},\r
+#endif\r
+#ifdef _SC_VERSION\r
+ {"SC_VERSION", _SC_VERSION},\r
+#endif\r
+#ifdef _SC_WORD_BIT\r
+ {"SC_WORD_BIT", _SC_WORD_BIT},\r
+#endif\r
+#ifdef _SC_XBS5_ILP32_OFF32\r
+ {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},\r
+#endif\r
+#ifdef _SC_XBS5_ILP32_OFFBIG\r
+ {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},\r
+#endif\r
+#ifdef _SC_XBS5_LP64_OFF64\r
+ {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},\r
+#endif\r
+#ifdef _SC_XBS5_LPBIG_OFFBIG\r
+ {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},\r
+#endif\r
+#ifdef _SC_XOPEN_CRYPT\r
+ {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},\r
+#endif\r
+#ifdef _SC_XOPEN_ENH_I18N\r
+ {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},\r
+#endif\r
+#ifdef _SC_XOPEN_LEGACY\r
+ {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},\r
+#endif\r
+#ifdef _SC_XOPEN_REALTIME\r
+ {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},\r
+#endif\r
+#ifdef _SC_XOPEN_REALTIME_THREADS\r
+ {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},\r
+#endif\r
+#ifdef _SC_XOPEN_SHM\r
+ {"SC_XOPEN_SHM", _SC_XOPEN_SHM},\r
+#endif\r
+#ifdef _SC_XOPEN_UNIX\r
+ {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},\r
+#endif\r
+#ifdef _SC_XOPEN_VERSION\r
+ {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},\r
+#endif\r
+#ifdef _SC_XOPEN_XCU_VERSION\r
+ {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},\r
+#endif\r
+#ifdef _SC_XOPEN_XPG2\r
+ {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},\r
+#endif\r
+#ifdef _SC_XOPEN_XPG3\r
+ {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},\r
+#endif\r
+#ifdef _SC_XOPEN_XPG4\r
+ {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},\r
+#endif\r
+};\r
+\r
+static int\r
+conv_sysconf_confname(PyObject *arg, int *valuep)\r
+{\r
+ return conv_confname(arg, valuep, posix_constants_sysconf,\r
+ sizeof(posix_constants_sysconf)\r
+ / sizeof(struct constdef));\r
+}\r
+\r
+PyDoc_STRVAR(posix_sysconf__doc__,\r
+"sysconf(name) -> integer\n\n\\r
+Return an integer-valued system configuration variable.");\r
+\r
+static PyObject *\r
+posix_sysconf(PyObject *self, PyObject *args)\r
+{\r
+ PyObject *result = NULL;\r
+ int name;\r
+\r
+ if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {\r
+ int value;\r
+\r
+ errno = 0;\r
+ value = sysconf(name);\r
+ if (value == -1 && errno != 0)\r
+ posix_error();\r
+ else\r
+ result = PyInt_FromLong(value);\r
+ }\r
+ return result;\r
+}\r
+#endif\r
+\r
+\r
+#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF) || defined(HAVE_CONFSTR) || defined(HAVE_SYSCONF)\r
+/* This code is used to ensure that the tables of configuration value names\r
+ * are in sorted order as required by conv_confname(), and also to build the\r
+ * the exported dictionaries that are used to publish information about the\r
+ * names available on the host platform.\r
+ *\r
+ * Sorting the table at runtime ensures that the table is properly ordered\r
+ * when used, even for platforms we're not able to test on. It also makes\r
+ * it easier to add additional entries to the tables.\r
+ */\r
+\r
+static int\r
+cmp_constdefs(const void *v1, const void *v2)\r
+{\r
+ const struct constdef *c1 =\r
+ (const struct constdef *) v1;\r
+ const struct constdef *c2 =\r
+ (const struct constdef *) v2;\r
+\r
+ return strcmp(c1->name, c2->name);\r
+}\r
+\r
+static int\r
+setup_confname_table(struct constdef *table, size_t tablesize,\r
+ char *tablename, PyObject *module)\r
+{\r
+ PyObject *d = NULL;\r
+ size_t i;\r
+\r
+ qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);\r
+ d = PyDict_New();\r
+ if (d == NULL)\r
+ return -1;\r
+\r
+ for (i=0; i < tablesize; ++i) {\r
+ PyObject *o = PyInt_FromLong(table[i].value);\r
+ if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {\r
+ Py_XDECREF(o);\r
+ Py_DECREF(d);\r
+ return -1;\r
+ }\r
+ Py_DECREF(o);\r
+ }\r
+ return PyModule_AddObject(module, tablename, d);\r
+}\r
+#endif /* HAVE_FPATHCONF || HAVE_PATHCONF || HAVE_CONFSTR || HAVE_SYSCONF */\r
+\r
+/* Return -1 on failure, 0 on success. */\r
+static int\r
+setup_confname_tables(PyObject *module)\r
+{\r
+#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)\r
+ if (setup_confname_table(posix_constants_pathconf,\r
+ sizeof(posix_constants_pathconf)\r
+ / sizeof(struct constdef),\r
+ "pathconf_names", module))\r
+ return -1;\r
+#endif\r
+#ifdef HAVE_CONFSTR\r
+ if (setup_confname_table(posix_constants_confstr,\r
+ sizeof(posix_constants_confstr)\r
+ / sizeof(struct constdef),\r
+ "confstr_names", module))\r
+ return -1;\r
+#endif\r
+#ifdef HAVE_SYSCONF\r
+ if (setup_confname_table(posix_constants_sysconf,\r
+ sizeof(posix_constants_sysconf)\r
+ / sizeof(struct constdef),\r
+ "sysconf_names", module))\r
+ return -1;\r
+#endif\r
+ return 0;\r
+}\r
+\r
+\r
+PyDoc_STRVAR(posix_abort__doc__,\r
+"abort() -> does not return!\n\n\\r
+Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\\r
+in the hardest way possible on the hosting operating system.");\r
+\r
+static PyObject *\r
+posix_abort(PyObject *self, PyObject *noargs)\r
+{\r
+ abort();\r
+ /*NOTREACHED*/\r
+ Py_FatalError("abort() called from Python code didn't abort!");\r
+ return NULL;\r
+}\r
+\r
+#ifdef HAVE_SETRESUID\r
+PyDoc_STRVAR(posix_setresuid__doc__,\r
+"setresuid(ruid, euid, suid)\n\n\\r
+Set the current process's real, effective, and saved user ids.");\r
+\r
+static PyObject*\r
+posix_setresuid (PyObject *self, PyObject *args)\r
+{\r
+ /* We assume uid_t is no larger than a long. */\r
+ long ruid, euid, suid;\r
+ if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid))\r
+ return NULL;\r
+ if (setresuid(ruid, euid, suid) < 0)\r
+ return posix_error();\r
+ Py_RETURN_NONE;\r
+}\r
+#endif\r
+\r
+#ifdef HAVE_SETRESGID\r
+PyDoc_STRVAR(posix_setresgid__doc__,\r
+"setresgid(rgid, egid, sgid)\n\n\\r
+Set the current process's real, effective, and saved group ids.");\r
+\r
+static PyObject*\r
+posix_setresgid (PyObject *self, PyObject *args)\r
+{\r
+ /* We assume uid_t is no larger than a long. */\r
+ long rgid, egid, sgid;\r
+ if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid))\r
+ return NULL;\r
+ if (setresgid(rgid, egid, sgid) < 0)\r
+ return posix_error();\r
+ Py_RETURN_NONE;\r
+}\r
+#endif\r
+\r
+#ifdef HAVE_GETRESUID\r
+PyDoc_STRVAR(posix_getresuid__doc__,\r
+"getresuid() -> (ruid, euid, suid)\n\n\\r
+Get tuple of the current process's real, effective, and saved user ids.");\r
+\r
+static PyObject*\r
+posix_getresuid (PyObject *self, PyObject *noargs)\r
+{\r
+ uid_t ruid, euid, suid;\r
+ long l_ruid, l_euid, l_suid;\r
+ if (getresuid(&ruid, &euid, &suid) < 0)\r
+ return posix_error();\r
+ /* Force the values into long's as we don't know the size of uid_t. */\r
+ l_ruid = ruid;\r
+ l_euid = euid;\r
+ l_suid = suid;\r
+ return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid);\r
+}\r
+#endif\r
+\r
+#ifdef HAVE_GETRESGID\r
+PyDoc_STRVAR(posix_getresgid__doc__,\r
+"getresgid() -> (rgid, egid, sgid)\n\n\\r
+Get tuple of the current process's real, effective, and saved group ids.");\r
+\r
+static PyObject*\r
+posix_getresgid (PyObject *self, PyObject *noargs)\r
+{\r
+ uid_t rgid, egid, sgid;\r
+ long l_rgid, l_egid, l_sgid;\r
+ if (getresgid(&rgid, &egid, &sgid) < 0)\r
+ return posix_error();\r
+ /* Force the values into long's as we don't know the size of uid_t. */\r
+ l_rgid = rgid;\r
+ l_egid = egid;\r
+ l_sgid = sgid;\r
+ return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid);\r
+}\r
+#endif\r
+\r
+static PyMethodDef posix_methods[] = {\r
+ {"access", posix_access, METH_VARARGS, posix_access__doc__},\r
+#ifdef HAVE_TTYNAME\r
+ {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},\r
+#endif\r
+ {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},\r
+#ifdef HAVE_CHFLAGS\r
+ {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},\r
+#endif /* HAVE_CHFLAGS */\r
+ {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},\r
+#ifdef HAVE_FCHMOD\r
+ {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},\r
+#endif /* HAVE_FCHMOD */\r
+#ifdef HAVE_CHOWN\r
+ {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},\r
+#endif /* HAVE_CHOWN */\r
+#ifdef HAVE_LCHMOD\r
+ {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},\r
+#endif /* HAVE_LCHMOD */\r
+#ifdef HAVE_FCHOWN\r
+ {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},\r
+#endif /* HAVE_FCHOWN */\r
+#ifdef HAVE_LCHFLAGS\r
+ {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},\r
+#endif /* HAVE_LCHFLAGS */\r
+#ifdef HAVE_LCHOWN\r
+ {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},\r
+#endif /* HAVE_LCHOWN */\r
+#ifdef HAVE_CHROOT\r
+ {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},\r
+#endif\r
+#ifdef HAVE_CTERMID\r
+ {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},\r
+#endif\r
+#ifdef HAVE_GETCWD\r
+ {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},\r
+#ifdef Py_USING_UNICODE\r
+ {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},\r
+#endif\r
+#endif\r
+#ifdef HAVE_LINK\r
+ {"link", posix_link, METH_VARARGS, posix_link__doc__},\r
+#endif /* HAVE_LINK */\r
+ {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},\r
+ {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},\r
+ {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},\r
+#ifdef HAVE_NICE\r
+ {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},\r
+#endif /* HAVE_NICE */\r
+#ifdef HAVE_READLINK\r
+ {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},\r
+#endif /* HAVE_READLINK */\r
+ {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},\r
+ {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},\r
+ {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},\r
+ //{"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},\r
+#ifdef HAVE_SYMLINK\r
+ {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},\r
+#endif /* HAVE_SYMLINK */\r
+#ifdef HAVE_SYSTEM\r
+ {"system", posix_system, METH_VARARGS, posix_system__doc__},\r
+#endif\r
+ {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},\r
+#ifdef HAVE_UNAME\r
+ {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},\r
+#endif /* HAVE_UNAME */\r
+ {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},\r
+ {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},\r
+ {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},\r
+#ifdef HAVE_TIMES\r
+ {"times", posix_times, METH_NOARGS, posix_times__doc__},\r
+#endif /* HAVE_TIMES */\r
+ {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},\r
+#ifdef HAVE_EXECV\r
+ {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},\r
+ {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},\r
+#endif /* HAVE_EXECV */\r
+#ifdef HAVE_SPAWNV\r
+ {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},\r
+ {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},\r
+#if defined(PYOS_OS2)\r
+ {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},\r
+ {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},\r
+#endif /* PYOS_OS2 */\r
+#endif /* HAVE_SPAWNV */\r
+#ifdef HAVE_FORK1\r
+ {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},\r
+#endif /* HAVE_FORK1 */\r
+#ifdef HAVE_FORK\r
+ {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},\r
+#endif /* HAVE_FORK */\r
+#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)\r
+ {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},\r
+#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */\r
+#ifdef HAVE_FORKPTY\r
+ {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},\r
+#endif /* HAVE_FORKPTY */\r
+#ifdef HAVE_GETEGID\r
+ {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},\r
+#endif /* HAVE_GETEGID */\r
+#ifdef HAVE_GETEUID\r
+ {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},\r
+#endif /* HAVE_GETEUID */\r
+#ifdef HAVE_GETGID\r
+ {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},\r
+#endif /* HAVE_GETGID */\r
+#ifdef HAVE_GETGROUPS\r
+ {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},\r
+#endif\r
+ {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},\r
+#ifdef HAVE_GETPGRP\r
+ {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},\r
+#endif /* HAVE_GETPGRP */\r
+#ifdef HAVE_GETPPID\r
+ {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},\r
+#endif /* HAVE_GETPPID */\r
+#ifdef HAVE_GETUID\r
+ {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},\r
+#endif /* HAVE_GETUID */\r
+#ifdef HAVE_GETLOGIN\r
+ {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},\r
+#endif\r
+#ifdef HAVE_KILL\r
+ {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},\r
+#endif /* HAVE_KILL */\r
+#ifdef HAVE_KILLPG\r
+ {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},\r
+#endif /* HAVE_KILLPG */\r
+#ifdef HAVE_PLOCK\r
+ {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},\r
+#endif /* HAVE_PLOCK */\r
+#ifdef HAVE_POPEN\r
+ {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},\r
+#ifdef MS_WINDOWS\r
+ {"popen2", win32_popen2, METH_VARARGS},\r
+ {"popen3", win32_popen3, METH_VARARGS},\r
+ {"popen4", win32_popen4, METH_VARARGS},\r
+ {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},\r
+ {"kill", win32_kill, METH_VARARGS, win32_kill__doc__},\r
+#else\r
+#if defined(PYOS_OS2) && defined(PYCC_GCC)\r
+ {"popen2", os2emx_popen2, METH_VARARGS},\r
+ {"popen3", os2emx_popen3, METH_VARARGS},\r
+ {"popen4", os2emx_popen4, METH_VARARGS},\r
+#endif\r
+#endif\r
+#endif /* HAVE_POPEN */\r
+#ifdef HAVE_SETUID\r
+ {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},\r
+#endif /* HAVE_SETUID */\r
+#ifdef HAVE_SETEUID\r
+ {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},\r
+#endif /* HAVE_SETEUID */\r
+#ifdef HAVE_SETEGID\r
+ {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},\r
+#endif /* HAVE_SETEGID */\r
+#ifdef HAVE_SETREUID\r
+ {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},\r
+#endif /* HAVE_SETREUID */\r
+#ifdef HAVE_SETREGID\r
+ {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},\r
+#endif /* HAVE_SETREGID */\r
+#ifdef HAVE_SETGID\r
+ {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},\r
+#endif /* HAVE_SETGID */\r
+#ifdef HAVE_SETGROUPS\r
+ {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},\r
+#endif /* HAVE_SETGROUPS */\r
+#ifdef HAVE_INITGROUPS\r
+ {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},\r
+#endif /* HAVE_INITGROUPS */\r
+#ifdef HAVE_GETPGID\r
+ {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},\r
+#endif /* HAVE_GETPGID */\r
+#ifdef HAVE_SETPGRP\r
+ {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},\r
+#endif /* HAVE_SETPGRP */\r
+#ifdef HAVE_WAIT\r
+ {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},\r
+#endif /* HAVE_WAIT */\r
+#ifdef HAVE_WAIT3\r
+ {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},\r
+#endif /* HAVE_WAIT3 */\r
+#ifdef HAVE_WAIT4\r
+ {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},\r
+#endif /* HAVE_WAIT4 */\r
+#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)\r
+ {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},\r
+#endif /* HAVE_WAITPID */\r
+#ifdef HAVE_GETSID\r
+ {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},\r
+#endif /* HAVE_GETSID */\r
+#ifdef HAVE_SETSID\r
+ {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},\r
+#endif /* HAVE_SETSID */\r
+#ifdef HAVE_SETPGID\r
+ {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},\r
+#endif /* HAVE_SETPGID */\r
+#ifdef HAVE_TCGETPGRP\r
+ {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},\r
+#endif /* HAVE_TCGETPGRP */\r
+#ifdef HAVE_TCSETPGRP\r
+ {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},\r
+#endif /* HAVE_TCSETPGRP */\r
+ {"open", posix_open, METH_VARARGS, posix_open__doc__},\r
+ {"close", posix_close, METH_VARARGS, posix_close__doc__},\r
+ {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},\r
+ {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},\r
+ {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},\r
+ {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},\r
+ {"read", posix_read, METH_VARARGS, posix_read__doc__},\r
+ {"write", posix_write, METH_VARARGS, posix_write__doc__},\r
+ {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},\r
+ {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},\r
+ {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},\r
+#ifdef HAVE_PIPE\r
+ {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},\r
+#endif\r
+#ifdef HAVE_MKFIFO\r
+ {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},\r
+#endif\r
+#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)\r
+ {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},\r
+#endif\r
+#ifdef HAVE_DEVICE_MACROS\r
+ {"major", posix_major, METH_VARARGS, posix_major__doc__},\r
+ {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},\r
+ {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},\r
+#endif\r
+#ifdef HAVE_FTRUNCATE\r
+ {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},\r
+#endif\r
+#ifdef HAVE_PUTENV\r
+ {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},\r
+#endif\r
+#ifdef HAVE_UNSETENV\r
+ {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},\r
+#endif\r
+ {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},\r
+#ifdef HAVE_FCHDIR\r
+ {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},\r
+#endif\r
+#ifdef HAVE_FSYNC\r
+ {"fsync", posix_fsync, METH_O, posix_fsync__doc__},\r
+#endif\r
+#ifdef HAVE_FDATASYNC\r
+ {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},\r
+#endif\r
+#ifdef HAVE_SYS_WAIT_H\r
+#ifdef WCOREDUMP\r
+ {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},\r
+#endif /* WCOREDUMP */\r
+#ifdef WIFCONTINUED\r
+ {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},\r
+#endif /* WIFCONTINUED */\r
+#ifdef WIFSTOPPED\r
+ {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},\r
+#endif /* WIFSTOPPED */\r
+#ifdef WIFSIGNALED\r
+ {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},\r
+#endif /* WIFSIGNALED */\r
+#ifdef WIFEXITED\r
+ {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},\r
+#endif /* WIFEXITED */\r
+#ifdef WEXITSTATUS\r
+ {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},\r
+#endif /* WEXITSTATUS */\r
+#ifdef WTERMSIG\r
+ {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},\r
+#endif /* WTERMSIG */\r
+#ifdef WSTOPSIG\r
+ {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},\r
+#endif /* WSTOPSIG */\r
+#endif /* HAVE_SYS_WAIT_H */\r
+#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)\r
+ {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},\r
+#endif\r
+#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)\r
+ {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},\r
+#endif\r
+#ifdef HAVE_TMPFILE\r
+ {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},\r
+#endif\r
+#ifdef HAVE_TEMPNAM\r
+ {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},\r
+#endif\r
+#ifdef HAVE_TMPNAM\r
+ {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},\r
+#endif\r
+#ifdef HAVE_CONFSTR\r
+ {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},\r
+#endif\r
+#ifdef HAVE_SYSCONF\r
+ {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},\r
+#endif\r
+#ifdef HAVE_FPATHCONF\r
+ {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},\r
+#endif\r
+#ifdef HAVE_PATHCONF\r
+ {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},\r
+#endif\r
+ {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},\r
+#ifdef HAVE_SETRESUID\r
+ {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__},\r
+#endif\r
+#ifdef HAVE_SETRESGID\r
+ {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__},\r
+#endif\r
+#ifdef HAVE_GETRESUID\r
+ {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__},\r
+#endif\r
+#ifdef HAVE_GETRESGID\r
+ {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__},\r
+#endif\r
+\r
+ {NULL, NULL} /* Sentinel */\r
+};\r
+\r
+\r
+static int\r
+ins(PyObject *module, char *symbol, long value)\r
+{\r
+ return PyModule_AddIntConstant(module, symbol, value);\r
+}\r
+\r
+static int\r
+all_ins(PyObject *d)\r
+{\r
+#ifdef F_OK\r
+ if (ins(d, "F_OK", (long)F_OK)) return -1;\r
+#endif\r
+#ifdef R_OK\r
+ if (ins(d, "R_OK", (long)R_OK)) return -1;\r
+#endif\r
+#ifdef W_OK\r
+ if (ins(d, "W_OK", (long)W_OK)) return -1;\r
+#endif\r
+#ifdef X_OK\r
+ if (ins(d, "X_OK", (long)X_OK)) return -1;\r
+#endif\r
+#ifdef NGROUPS_MAX\r
+ if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;\r
+#endif\r
+#ifdef TMP_MAX\r
+ if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;\r
+#endif\r
+#ifdef WCONTINUED\r
+ if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;\r
+#endif\r
+#ifdef WNOHANG\r
+ if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;\r
+#endif\r
+#ifdef WUNTRACED\r
+ if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;\r
+#endif\r
+#ifdef O_RDONLY\r
+ if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;\r
+#endif\r
+#ifdef O_WRONLY\r
+ if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;\r
+#endif\r
+#ifdef O_RDWR\r
+ if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;\r
+#endif\r
+#ifdef O_NDELAY\r
+ if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;\r
+#endif\r
+#ifdef O_NONBLOCK\r
+ if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;\r
+#endif\r
+#ifdef O_APPEND\r
+ if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;\r
+#endif\r
+#ifdef O_DSYNC\r
+ if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;\r
+#endif\r
+#ifdef O_RSYNC\r
+ if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;\r
+#endif\r
+#ifdef O_SYNC\r
+ if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;\r
+#endif\r
+#ifdef O_NOCTTY\r
+ if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;\r
+#endif\r
+#ifdef O_CREAT\r
+ if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;\r
+#endif\r
+#ifdef O_EXCL\r
+ if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;\r
+#endif\r
+#ifdef O_TRUNC\r
+ if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;\r
+#endif\r
+#ifdef O_BINARY\r
+ if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;\r
+#endif\r
+#ifdef O_TEXT\r
+ if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;\r
+#endif\r
+#ifdef O_LARGEFILE\r
+ if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;\r
+#endif\r
+#ifdef O_SHLOCK\r
+ if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;\r
+#endif\r
+#ifdef O_EXLOCK\r
+ if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;\r
+#endif\r
+\r
+/* MS Windows */\r
+#ifdef O_NOINHERIT\r
+ /* Don't inherit in child processes. */\r
+ if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;\r
+#endif\r
+#ifdef _O_SHORT_LIVED\r
+ /* Optimize for short life (keep in memory). */\r
+ /* MS forgot to define this one with a non-underscore form too. */\r
+ if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;\r
+#endif\r
+#ifdef O_TEMPORARY\r
+ /* Automatically delete when last handle is closed. */\r
+ if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;\r
+#endif\r
+#ifdef O_RANDOM\r
+ /* Optimize for random access. */\r
+ if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;\r
+#endif\r
+#ifdef O_SEQUENTIAL\r
+ /* Optimize for sequential access. */\r
+ if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;\r
+#endif\r
+\r
+/* GNU extensions. */\r
+#ifdef O_ASYNC\r
+ /* Send a SIGIO signal whenever input or output\r
+ becomes available on file descriptor */\r
+ if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;\r
+#endif\r
+#ifdef O_DIRECT\r
+ /* Direct disk access. */\r
+ if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;\r
+#endif\r
+#ifdef O_DIRECTORY\r
+ /* Must be a directory. */\r
+ if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;\r
+#endif\r
+#ifdef O_NOFOLLOW\r
+ /* Do not follow links. */\r
+ if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;\r
+#endif\r
+#ifdef O_NOATIME\r
+ /* Do not update the access time. */\r
+ if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;\r
+#endif\r
+\r
+ /* These come from sysexits.h */\r
+#ifdef EX_OK\r
+ if (ins(d, "EX_OK", (long)EX_OK)) return -1;\r
+#endif /* EX_OK */\r
+#ifdef EX_USAGE\r
+ if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;\r
+#endif /* EX_USAGE */\r
+#ifdef EX_DATAERR\r
+ if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;\r
+#endif /* EX_DATAERR */\r
+#ifdef EX_NOINPUT\r
+ if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;\r
+#endif /* EX_NOINPUT */\r
+#ifdef EX_NOUSER\r
+ if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;\r
+#endif /* EX_NOUSER */\r
+#ifdef EX_NOHOST\r
+ if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;\r
+#endif /* EX_NOHOST */\r
+#ifdef EX_UNAVAILABLE\r
+ if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;\r
+#endif /* EX_UNAVAILABLE */\r
+#ifdef EX_SOFTWARE\r
+ if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;\r
+#endif /* EX_SOFTWARE */\r
+#ifdef EX_OSERR\r
+ if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;\r
+#endif /* EX_OSERR */\r
+#ifdef EX_OSFILE\r
+ if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;\r
+#endif /* EX_OSFILE */\r
+#ifdef EX_CANTCREAT\r
+ if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;\r
+#endif /* EX_CANTCREAT */\r
+#ifdef EX_IOERR\r
+ if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;\r
+#endif /* EX_IOERR */\r
+#ifdef EX_TEMPFAIL\r
+ if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;\r
+#endif /* EX_TEMPFAIL */\r
+#ifdef EX_PROTOCOL\r
+ if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;\r
+#endif /* EX_PROTOCOL */\r
+#ifdef EX_NOPERM\r
+ if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;\r
+#endif /* EX_NOPERM */\r
+#ifdef EX_CONFIG\r
+ if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;\r
+#endif /* EX_CONFIG */\r
+#ifdef EX_NOTFOUND\r
+ if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;\r
+#endif /* EX_NOTFOUND */\r
+\r
+#ifdef HAVE_SPAWNV\r
+#if defined(PYOS_OS2) && defined(PYCC_GCC)\r
+ if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;\r
+ if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;\r
+ if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;\r
+ if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;\r
+ if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;\r
+ if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;\r
+ if (ins(d, "P_PM", (long)P_PM)) return -1;\r
+ if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;\r
+ if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;\r
+ if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;\r
+ if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;\r
+ if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;\r
+ if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;\r
+ if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;\r
+ if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;\r
+ if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;\r
+ if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;\r
+ if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;\r
+ if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;\r
+ if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;\r
+#else\r
+ if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;\r
+ if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;\r
+ if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;\r
+ if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;\r
+ if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;\r
+#endif\r
+#endif\r
+ return 0;\r
+}\r
+\r
+#define INITFUNC initedk2\r
+#define MODNAME "edk2"\r
+\r
+PyMODINIT_FUNC\r
+INITFUNC(void)\r
+{\r
+ PyObject *m;\r
+\r
+#ifndef UEFI_C_SOURCE\r
+ PyObject *v;\r
+#endif\r
+\r
+ m = Py_InitModule3(MODNAME,\r
+ posix_methods,\r
+ edk2__doc__);\r
+ if (m == NULL)\r
+ return;\r
+\r
+#ifndef UEFI_C_SOURCE\r
+ /* Initialize environ dictionary */\r
+ v = convertenviron();\r
+ Py_XINCREF(v);\r
+ if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)\r
+ return;\r
+ Py_DECREF(v);\r
+#endif /* UEFI_C_SOURCE */\r
+\r
+ if (all_ins(m))\r
+ return;\r
+\r
+ if (setup_confname_tables(m))\r
+ return;\r
+\r
+ Py_INCREF(PyExc_OSError);\r
+ PyModule_AddObject(m, "error", PyExc_OSError);\r
+\r
+#ifdef HAVE_PUTENV\r
+ if (posix_putenv_garbage == NULL)\r
+ posix_putenv_garbage = PyDict_New();\r
+#endif\r
+\r
+ if (!initialized) {\r
+ stat_result_desc.name = MODNAME ".stat_result";\r
+ stat_result_desc.fields[2].name = PyStructSequence_UnnamedField;\r
+ stat_result_desc.fields[3].name = PyStructSequence_UnnamedField;\r
+ stat_result_desc.fields[4].name = PyStructSequence_UnnamedField;\r
+ PyStructSequence_InitType(&StatResultType, &stat_result_desc);\r
+ structseq_new = StatResultType.tp_new;\r
+ StatResultType.tp_new = statresult_new;\r
+\r
+ //statvfs_result_desc.name = MODNAME ".statvfs_result";\r
+ //PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);\r
+#ifdef NEED_TICKS_PER_SECOND\r
+# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)\r
+ ticks_per_second = sysconf(_SC_CLK_TCK);\r
+# elif defined(HZ)\r
+ ticks_per_second = HZ;\r
+# else\r
+ ticks_per_second = 60; /* magic fallback value; may be bogus */\r
+# endif\r
+#endif\r
+ }\r
+ Py_INCREF((PyObject*) &StatResultType);\r
+ PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);\r
+ //Py_INCREF((PyObject*) &StatVFSResultType);\r
+ //PyModule_AddObject(m, "statvfs_result",\r
+ // (PyObject*) &StatVFSResultType);\r
+ initialized = 1;\r
+\r
+}\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+\r
--- /dev/null
+\r
+/* Errno module */\r
+\r
+#include "Python.h"\r
+\r
+/* Windows socket errors (WSA*) */\r
+#ifdef MS_WINDOWS\r
+#include <windows.h>\r
+#endif\r
+\r
+/*\r
+ * Pull in the system error definitions\r
+ */\r
+\r
+static PyMethodDef errno_methods[] = {\r
+ {NULL, NULL}\r
+};\r
+\r
+/* Helper function doing the dictionary inserting */\r
+\r
+static void\r
+_inscode(PyObject *d, PyObject *de, char *name, int code)\r
+{\r
+ PyObject *u = PyString_FromString(name);\r
+ PyObject *v = PyInt_FromLong((long) code);\r
+\r
+ /* Don't bother checking for errors; they'll be caught at the end\r
+ * of the module initialization function by the caller of\r
+ * initerrno().\r
+ */\r
+ if (u && v) {\r
+ /* insert in modules dict */\r
+ PyDict_SetItem(d, u, v);\r
+ /* insert in errorcode dict */\r
+ PyDict_SetItem(de, v, u);\r
+ }\r
+ Py_XDECREF(u);\r
+ Py_XDECREF(v);\r
+}\r
+\r
+PyDoc_STRVAR(errno__doc__,\r
+"This module makes available standard errno system symbols.\n\\r
+\n\\r
+The value of each symbol is the corresponding integer value,\n\\r
+e.g., on most systems, errno.ENOENT equals the integer 2.\n\\r
+\n\\r
+The dictionary errno.errorcode maps numeric codes to symbol names,\n\\r
+e.g., errno.errorcode[2] could be the string 'ENOENT'.\n\\r
+\n\\r
+Symbols that are not relevant to the underlying system are not defined.\n\\r
+\n\\r
+To map error codes to error messages, use the function os.strerror(),\n\\r
+e.g. os.strerror(2) could return 'No such file or directory'.");\r
+\r
+PyMODINIT_FUNC\r
+initerrno(void)\r
+{\r
+ PyObject *m, *d, *de;\r
+ m = Py_InitModule3("errno", errno_methods, errno__doc__);\r
+ if (m == NULL)\r
+ return;\r
+ d = PyModule_GetDict(m);\r
+ de = PyDict_New();\r
+ if (!d || !de || PyDict_SetItemString(d, "errorcode", de) < 0)\r
+ return;\r
+\r
+/* Macro so I don't have to edit each and every line below... */\r
+#define inscode(d, ds, de, name, code, comment) _inscode(d, de, name, code)\r
+\r
+ /*\r
+ * The names and comments are borrowed from linux/include/errno.h,\r
+ * which should be pretty all-inclusive\r
+ */\r
+\r
+#ifdef ENODEV\r
+ inscode(d, ds, de, "ENODEV", ENODEV, "No such device");\r
+#endif\r
+#ifdef ENOCSI\r
+ inscode(d, ds, de, "ENOCSI", ENOCSI, "No CSI structure available");\r
+#endif\r
+#ifdef EHOSTUNREACH\r
+ inscode(d, ds, de, "EHOSTUNREACH", EHOSTUNREACH, "No route to host");\r
+#else\r
+#ifdef WSAEHOSTUNREACH\r
+ inscode(d, ds, de, "EHOSTUNREACH", WSAEHOSTUNREACH, "No route to host");\r
+#endif\r
+#endif\r
+#ifdef ENOMSG\r
+ inscode(d, ds, de, "ENOMSG", ENOMSG, "No message of desired type");\r
+#endif\r
+#ifdef EUCLEAN\r
+ inscode(d, ds, de, "EUCLEAN", EUCLEAN, "Structure needs cleaning");\r
+#endif\r
+#ifdef EL2NSYNC\r
+ inscode(d, ds, de, "EL2NSYNC", EL2NSYNC, "Level 2 not synchronized");\r
+#endif\r
+#ifdef EL2HLT\r
+ inscode(d, ds, de, "EL2HLT", EL2HLT, "Level 2 halted");\r
+#endif\r
+#ifdef ENODATA\r
+ inscode(d, ds, de, "ENODATA", ENODATA, "No data available");\r
+#endif\r
+#ifdef ENOTBLK\r
+ inscode(d, ds, de, "ENOTBLK", ENOTBLK, "Block device required");\r
+#endif\r
+#ifdef ENOSYS\r
+ inscode(d, ds, de, "ENOSYS", ENOSYS, "Function not implemented");\r
+#endif\r
+#ifdef EPIPE\r
+ inscode(d, ds, de, "EPIPE", EPIPE, "Broken pipe");\r
+#endif\r
+#ifdef EINVAL\r
+ inscode(d, ds, de, "EINVAL", EINVAL, "Invalid argument");\r
+#else\r
+#ifdef WSAEINVAL\r
+ inscode(d, ds, de, "EINVAL", WSAEINVAL, "Invalid argument");\r
+#endif\r
+#endif\r
+#ifdef EOVERFLOW\r
+ inscode(d, ds, de, "EOVERFLOW", EOVERFLOW, "Value too large for defined data type");\r
+#endif\r
+#ifdef EADV\r
+ inscode(d, ds, de, "EADV", EADV, "Advertise error");\r
+#endif\r
+#ifdef EINTR\r
+ inscode(d, ds, de, "EINTR", EINTR, "Interrupted system call");\r
+#else\r
+#ifdef WSAEINTR\r
+ inscode(d, ds, de, "EINTR", WSAEINTR, "Interrupted system call");\r
+#endif\r
+#endif\r
+#ifdef EUSERS\r
+ inscode(d, ds, de, "EUSERS", EUSERS, "Too many users");\r
+#else\r
+#ifdef WSAEUSERS\r
+ inscode(d, ds, de, "EUSERS", WSAEUSERS, "Too many users");\r
+#endif\r
+#endif\r
+#ifdef ENOTEMPTY\r
+ inscode(d, ds, de, "ENOTEMPTY", ENOTEMPTY, "Directory not empty");\r
+#else\r
+#ifdef WSAENOTEMPTY\r
+ inscode(d, ds, de, "ENOTEMPTY", WSAENOTEMPTY, "Directory not empty");\r
+#endif\r
+#endif\r
+#ifdef ENOBUFS\r
+ inscode(d, ds, de, "ENOBUFS", ENOBUFS, "No buffer space available");\r
+#else\r
+#ifdef WSAENOBUFS\r
+ inscode(d, ds, de, "ENOBUFS", WSAENOBUFS, "No buffer space available");\r
+#endif\r
+#endif\r
+#ifdef EPROTO\r
+ inscode(d, ds, de, "EPROTO", EPROTO, "Protocol error");\r
+#endif\r
+#ifdef EREMOTE\r
+ inscode(d, ds, de, "EREMOTE", EREMOTE, "Object is remote");\r
+#else\r
+#ifdef WSAEREMOTE\r
+ inscode(d, ds, de, "EREMOTE", WSAEREMOTE, "Object is remote");\r
+#endif\r
+#endif\r
+#ifdef ENAVAIL\r
+ inscode(d, ds, de, "ENAVAIL", ENAVAIL, "No XENIX semaphores available");\r
+#endif\r
+#ifdef ECHILD\r
+ inscode(d, ds, de, "ECHILD", ECHILD, "No child processes");\r
+#endif\r
+#ifdef ELOOP\r
+ inscode(d, ds, de, "ELOOP", ELOOP, "Too many symbolic links encountered");\r
+#else\r
+#ifdef WSAELOOP\r
+ inscode(d, ds, de, "ELOOP", WSAELOOP, "Too many symbolic links encountered");\r
+#endif\r
+#endif\r
+#ifdef EXDEV\r
+ inscode(d, ds, de, "EXDEV", EXDEV, "Cross-device link");\r
+#endif\r
+#ifdef E2BIG\r
+ inscode(d, ds, de, "E2BIG", E2BIG, "Arg list too long");\r
+#endif\r
+#ifdef ESRCH\r
+ inscode(d, ds, de, "ESRCH", ESRCH, "No such process");\r
+#endif\r
+#ifdef EMSGSIZE\r
+ inscode(d, ds, de, "EMSGSIZE", EMSGSIZE, "Message too long");\r
+#else\r
+#ifdef WSAEMSGSIZE\r
+ inscode(d, ds, de, "EMSGSIZE", WSAEMSGSIZE, "Message too long");\r
+#endif\r
+#endif\r
+#ifdef EAFNOSUPPORT\r
+ inscode(d, ds, de, "EAFNOSUPPORT", EAFNOSUPPORT, "Address family not supported by protocol");\r
+#else\r
+#ifdef WSAEAFNOSUPPORT\r
+ inscode(d, ds, de, "EAFNOSUPPORT", WSAEAFNOSUPPORT, "Address family not supported by protocol");\r
+#endif\r
+#endif\r
+#ifdef EBADR\r
+ inscode(d, ds, de, "EBADR", EBADR, "Invalid request descriptor");\r
+#endif\r
+#ifdef EHOSTDOWN\r
+ inscode(d, ds, de, "EHOSTDOWN", EHOSTDOWN, "Host is down");\r
+#else\r
+#ifdef WSAEHOSTDOWN\r
+ inscode(d, ds, de, "EHOSTDOWN", WSAEHOSTDOWN, "Host is down");\r
+#endif\r
+#endif\r
+#ifdef EPFNOSUPPORT\r
+ inscode(d, ds, de, "EPFNOSUPPORT", EPFNOSUPPORT, "Protocol family not supported");\r
+#else\r
+#ifdef WSAEPFNOSUPPORT\r
+ inscode(d, ds, de, "EPFNOSUPPORT", WSAEPFNOSUPPORT, "Protocol family not supported");\r
+#endif\r
+#endif\r
+#ifdef ENOPROTOOPT\r
+ inscode(d, ds, de, "ENOPROTOOPT", ENOPROTOOPT, "Protocol not available");\r
+#else\r
+#ifdef WSAENOPROTOOPT\r
+ inscode(d, ds, de, "ENOPROTOOPT", WSAENOPROTOOPT, "Protocol not available");\r
+#endif\r
+#endif\r
+#ifdef EBUSY\r
+ inscode(d, ds, de, "EBUSY", EBUSY, "Device or resource busy");\r
+#endif\r
+#ifdef EWOULDBLOCK\r
+ inscode(d, ds, de, "EWOULDBLOCK", EWOULDBLOCK, "Operation would block");\r
+#else\r
+#ifdef WSAEWOULDBLOCK\r
+ inscode(d, ds, de, "EWOULDBLOCK", WSAEWOULDBLOCK, "Operation would block");\r
+#endif\r
+#endif\r
+#ifdef EBADFD\r
+ inscode(d, ds, de, "EBADFD", EBADFD, "File descriptor in bad state");\r
+#endif\r
+#ifdef EDOTDOT\r
+ inscode(d, ds, de, "EDOTDOT", EDOTDOT, "RFS specific error");\r
+#endif\r
+#ifdef EISCONN\r
+ inscode(d, ds, de, "EISCONN", EISCONN, "Transport endpoint is already connected");\r
+#else\r
+#ifdef WSAEISCONN\r
+ inscode(d, ds, de, "EISCONN", WSAEISCONN, "Transport endpoint is already connected");\r
+#endif\r
+#endif\r
+#ifdef ENOANO\r
+ inscode(d, ds, de, "ENOANO", ENOANO, "No anode");\r
+#endif\r
+#ifdef ESHUTDOWN\r
+ inscode(d, ds, de, "ESHUTDOWN", ESHUTDOWN, "Cannot send after transport endpoint shutdown");\r
+#else\r
+#ifdef WSAESHUTDOWN\r
+ inscode(d, ds, de, "ESHUTDOWN", WSAESHUTDOWN, "Cannot send after transport endpoint shutdown");\r
+#endif\r
+#endif\r
+#ifdef ECHRNG\r
+ inscode(d, ds, de, "ECHRNG", ECHRNG, "Channel number out of range");\r
+#endif\r
+#ifdef ELIBBAD\r
+ inscode(d, ds, de, "ELIBBAD", ELIBBAD, "Accessing a corrupted shared library");\r
+#endif\r
+#ifdef ENONET\r
+ inscode(d, ds, de, "ENONET", ENONET, "Machine is not on the network");\r
+#endif\r
+#ifdef EBADE\r
+ inscode(d, ds, de, "EBADE", EBADE, "Invalid exchange");\r
+#endif\r
+#ifdef EBADF\r
+ inscode(d, ds, de, "EBADF", EBADF, "Bad file number");\r
+#else\r
+#ifdef WSAEBADF\r
+ inscode(d, ds, de, "EBADF", WSAEBADF, "Bad file number");\r
+#endif\r
+#endif\r
+#ifdef EMULTIHOP\r
+ inscode(d, ds, de, "EMULTIHOP", EMULTIHOP, "Multihop attempted");\r
+#endif\r
+#ifdef EIO\r
+ inscode(d, ds, de, "EIO", EIO, "I/O error");\r
+#endif\r
+#ifdef EUNATCH\r
+ inscode(d, ds, de, "EUNATCH", EUNATCH, "Protocol driver not attached");\r
+#endif\r
+#ifdef EPROTOTYPE\r
+ inscode(d, ds, de, "EPROTOTYPE", EPROTOTYPE, "Protocol wrong type for socket");\r
+#else\r
+#ifdef WSAEPROTOTYPE\r
+ inscode(d, ds, de, "EPROTOTYPE", WSAEPROTOTYPE, "Protocol wrong type for socket");\r
+#endif\r
+#endif\r
+#ifdef ENOSPC\r
+ inscode(d, ds, de, "ENOSPC", ENOSPC, "No space left on device");\r
+#endif\r
+#ifdef ENOEXEC\r
+ inscode(d, ds, de, "ENOEXEC", ENOEXEC, "Exec format error");\r
+#endif\r
+#ifdef EALREADY\r
+ inscode(d, ds, de, "EALREADY", EALREADY, "Operation already in progress");\r
+#else\r
+#ifdef WSAEALREADY\r
+ inscode(d, ds, de, "EALREADY", WSAEALREADY, "Operation already in progress");\r
+#endif\r
+#endif\r
+#ifdef ENETDOWN\r
+ inscode(d, ds, de, "ENETDOWN", ENETDOWN, "Network is down");\r
+#else\r
+#ifdef WSAENETDOWN\r
+ inscode(d, ds, de, "ENETDOWN", WSAENETDOWN, "Network is down");\r
+#endif\r
+#endif\r
+#ifdef ENOTNAM\r
+ inscode(d, ds, de, "ENOTNAM", ENOTNAM, "Not a XENIX named type file");\r
+#endif\r
+#ifdef EACCES\r
+ inscode(d, ds, de, "EACCES", EACCES, "Permission denied");\r
+#else\r
+#ifdef WSAEACCES\r
+ inscode(d, ds, de, "EACCES", WSAEACCES, "Permission denied");\r
+#endif\r
+#endif\r
+#ifdef ELNRNG\r
+ inscode(d, ds, de, "ELNRNG", ELNRNG, "Link number out of range");\r
+#endif\r
+#ifdef EILSEQ\r
+ inscode(d, ds, de, "EILSEQ", EILSEQ, "Illegal byte sequence");\r
+#endif\r
+#ifdef ENOTDIR\r
+ inscode(d, ds, de, "ENOTDIR", ENOTDIR, "Not a directory");\r
+#endif\r
+#ifdef ENOTUNIQ\r
+ inscode(d, ds, de, "ENOTUNIQ", ENOTUNIQ, "Name not unique on network");\r
+#endif\r
+#ifdef EPERM\r
+ inscode(d, ds, de, "EPERM", EPERM, "Operation not permitted");\r
+#endif\r
+#ifdef EDOM\r
+ inscode(d, ds, de, "EDOM", EDOM, "Math argument out of domain of func");\r
+#endif\r
+#ifdef EXFULL\r
+ inscode(d, ds, de, "EXFULL", EXFULL, "Exchange full");\r
+#endif\r
+#ifdef ECONNREFUSED\r
+ inscode(d, ds, de, "ECONNREFUSED", ECONNREFUSED, "Connection refused");\r
+#else\r
+#ifdef WSAECONNREFUSED\r
+ inscode(d, ds, de, "ECONNREFUSED", WSAECONNREFUSED, "Connection refused");\r
+#endif\r
+#endif\r
+#ifdef EISDIR\r
+ inscode(d, ds, de, "EISDIR", EISDIR, "Is a directory");\r
+#endif\r
+#ifdef EPROTONOSUPPORT\r
+ inscode(d, ds, de, "EPROTONOSUPPORT", EPROTONOSUPPORT, "Protocol not supported");\r
+#else\r
+#ifdef WSAEPROTONOSUPPORT\r
+ inscode(d, ds, de, "EPROTONOSUPPORT", WSAEPROTONOSUPPORT, "Protocol not supported");\r
+#endif\r
+#endif\r
+#ifdef EROFS\r
+ inscode(d, ds, de, "EROFS", EROFS, "Read-only file system");\r
+#endif\r
+#ifdef EADDRNOTAVAIL\r
+ inscode(d, ds, de, "EADDRNOTAVAIL", EADDRNOTAVAIL, "Cannot assign requested address");\r
+#else\r
+#ifdef WSAEADDRNOTAVAIL\r
+ inscode(d, ds, de, "EADDRNOTAVAIL", WSAEADDRNOTAVAIL, "Cannot assign requested address");\r
+#endif\r
+#endif\r
+#ifdef EIDRM\r
+ inscode(d, ds, de, "EIDRM", EIDRM, "Identifier removed");\r
+#endif\r
+#ifdef ECOMM\r
+ inscode(d, ds, de, "ECOMM", ECOMM, "Communication error on send");\r
+#endif\r
+#ifdef ESRMNT\r
+ inscode(d, ds, de, "ESRMNT", ESRMNT, "Srmount error");\r
+#endif\r
+#ifdef EREMOTEIO\r
+ inscode(d, ds, de, "EREMOTEIO", EREMOTEIO, "Remote I/O error");\r
+#endif\r
+#ifdef EL3RST\r
+ inscode(d, ds, de, "EL3RST", EL3RST, "Level 3 reset");\r
+#endif\r
+#ifdef EBADMSG\r
+ inscode(d, ds, de, "EBADMSG", EBADMSG, "Not a data message");\r
+#endif\r
+#ifdef ENFILE\r
+ inscode(d, ds, de, "ENFILE", ENFILE, "File table overflow");\r
+#endif\r
+#ifdef ELIBMAX\r
+ inscode(d, ds, de, "ELIBMAX", ELIBMAX, "Attempting to link in too many shared libraries");\r
+#endif\r
+#ifdef ESPIPE\r
+ inscode(d, ds, de, "ESPIPE", ESPIPE, "Illegal seek");\r
+#endif\r
+#ifdef ENOLINK\r
+ inscode(d, ds, de, "ENOLINK", ENOLINK, "Link has been severed");\r
+#endif\r
+#ifdef ENETRESET\r
+ inscode(d, ds, de, "ENETRESET", ENETRESET, "Network dropped connection because of reset");\r
+#else\r
+#ifdef WSAENETRESET\r
+ inscode(d, ds, de, "ENETRESET", WSAENETRESET, "Network dropped connection because of reset");\r
+#endif\r
+#endif\r
+#ifdef ETIMEDOUT\r
+ inscode(d, ds, de, "ETIMEDOUT", ETIMEDOUT, "Connection timed out");\r
+#else\r
+#ifdef WSAETIMEDOUT\r
+ inscode(d, ds, de, "ETIMEDOUT", WSAETIMEDOUT, "Connection timed out");\r
+#endif\r
+#endif\r
+#ifdef ENOENT\r
+ inscode(d, ds, de, "ENOENT", ENOENT, "No such file or directory");\r
+#endif\r
+#ifdef EEXIST\r
+ inscode(d, ds, de, "EEXIST", EEXIST, "File exists");\r
+#endif\r
+#ifdef EDQUOT\r
+ inscode(d, ds, de, "EDQUOT", EDQUOT, "Quota exceeded");\r
+#else\r
+#ifdef WSAEDQUOT\r
+ inscode(d, ds, de, "EDQUOT", WSAEDQUOT, "Quota exceeded");\r
+#endif\r
+#endif\r
+#ifdef ENOSTR\r
+ inscode(d, ds, de, "ENOSTR", ENOSTR, "Device not a stream");\r
+#endif\r
+#ifdef EBADSLT\r
+ inscode(d, ds, de, "EBADSLT", EBADSLT, "Invalid slot");\r
+#endif\r
+#ifdef EBADRQC\r
+ inscode(d, ds, de, "EBADRQC", EBADRQC, "Invalid request code");\r
+#endif\r
+#ifdef ELIBACC\r
+ inscode(d, ds, de, "ELIBACC", ELIBACC, "Can not access a needed shared library");\r
+#endif\r
+#ifdef EFAULT\r
+ inscode(d, ds, de, "EFAULT", EFAULT, "Bad address");\r
+#else\r
+#ifdef WSAEFAULT\r
+ inscode(d, ds, de, "EFAULT", WSAEFAULT, "Bad address");\r
+#endif\r
+#endif\r
+#ifdef EFBIG\r
+ inscode(d, ds, de, "EFBIG", EFBIG, "File too large");\r
+#endif\r
+#ifdef EDEADLK\r
+ inscode(d, ds, de, "EDEADLK", EDEADLK, "Resource deadlock would occur");\r
+#endif\r
+#ifdef ENOTCONN\r
+ inscode(d, ds, de, "ENOTCONN", ENOTCONN, "Transport endpoint is not connected");\r
+#else\r
+#ifdef WSAENOTCONN\r
+ inscode(d, ds, de, "ENOTCONN", WSAENOTCONN, "Transport endpoint is not connected");\r
+#endif\r
+#endif\r
+#ifdef EDESTADDRREQ\r
+ inscode(d, ds, de, "EDESTADDRREQ", EDESTADDRREQ, "Destination address required");\r
+#else\r
+#ifdef WSAEDESTADDRREQ\r
+ inscode(d, ds, de, "EDESTADDRREQ", WSAEDESTADDRREQ, "Destination address required");\r
+#endif\r
+#endif\r
+#ifdef ELIBSCN\r
+ inscode(d, ds, de, "ELIBSCN", ELIBSCN, ".lib section in a.out corrupted");\r
+#endif\r
+#ifdef ENOLCK\r
+ inscode(d, ds, de, "ENOLCK", ENOLCK, "No record locks available");\r
+#endif\r
+#ifdef EISNAM\r
+ inscode(d, ds, de, "EISNAM", EISNAM, "Is a named type file");\r
+#endif\r
+#ifdef ECONNABORTED\r
+ inscode(d, ds, de, "ECONNABORTED", ECONNABORTED, "Software caused connection abort");\r
+#else\r
+#ifdef WSAECONNABORTED\r
+ inscode(d, ds, de, "ECONNABORTED", WSAECONNABORTED, "Software caused connection abort");\r
+#endif\r
+#endif\r
+#ifdef ENETUNREACH\r
+ inscode(d, ds, de, "ENETUNREACH", ENETUNREACH, "Network is unreachable");\r
+#else\r
+#ifdef WSAENETUNREACH\r
+ inscode(d, ds, de, "ENETUNREACH", WSAENETUNREACH, "Network is unreachable");\r
+#endif\r
+#endif\r
+#ifdef ESTALE\r
+ inscode(d, ds, de, "ESTALE", ESTALE, "Stale NFS file handle");\r
+#else\r
+#ifdef WSAESTALE\r
+ inscode(d, ds, de, "ESTALE", WSAESTALE, "Stale NFS file handle");\r
+#endif\r
+#endif\r
+#ifdef ENOSR\r
+ inscode(d, ds, de, "ENOSR", ENOSR, "Out of streams resources");\r
+#endif\r
+#ifdef ENOMEM\r
+ inscode(d, ds, de, "ENOMEM", ENOMEM, "Out of memory");\r
+#endif\r
+#ifdef ENOTSOCK\r
+ inscode(d, ds, de, "ENOTSOCK", ENOTSOCK, "Socket operation on non-socket");\r
+#else\r
+#ifdef WSAENOTSOCK\r
+ inscode(d, ds, de, "ENOTSOCK", WSAENOTSOCK, "Socket operation on non-socket");\r
+#endif\r
+#endif\r
+#ifdef ESTRPIPE\r
+ inscode(d, ds, de, "ESTRPIPE", ESTRPIPE, "Streams pipe error");\r
+#endif\r
+#ifdef EMLINK\r
+ inscode(d, ds, de, "EMLINK", EMLINK, "Too many links");\r
+#endif\r
+#ifdef ERANGE\r
+ inscode(d, ds, de, "ERANGE", ERANGE, "Math result not representable");\r
+#endif\r
+#ifdef ELIBEXEC\r
+ inscode(d, ds, de, "ELIBEXEC", ELIBEXEC, "Cannot exec a shared library directly");\r
+#endif\r
+#ifdef EL3HLT\r
+ inscode(d, ds, de, "EL3HLT", EL3HLT, "Level 3 halted");\r
+#endif\r
+#ifdef ECONNRESET\r
+ inscode(d, ds, de, "ECONNRESET", ECONNRESET, "Connection reset by peer");\r
+#else\r
+#ifdef WSAECONNRESET\r
+ inscode(d, ds, de, "ECONNRESET", WSAECONNRESET, "Connection reset by peer");\r
+#endif\r
+#endif\r
+#ifdef EADDRINUSE\r
+ inscode(d, ds, de, "EADDRINUSE", EADDRINUSE, "Address already in use");\r
+#else\r
+#ifdef WSAEADDRINUSE\r
+ inscode(d, ds, de, "EADDRINUSE", WSAEADDRINUSE, "Address already in use");\r
+#endif\r
+#endif\r
+#ifdef EOPNOTSUPP\r
+ inscode(d, ds, de, "EOPNOTSUPP", EOPNOTSUPP, "Operation not supported on transport endpoint");\r
+#else\r
+#ifdef WSAEOPNOTSUPP\r
+ inscode(d, ds, de, "EOPNOTSUPP", WSAEOPNOTSUPP, "Operation not supported on transport endpoint");\r
+#endif\r
+#endif\r
+#ifdef EREMCHG\r
+ inscode(d, ds, de, "EREMCHG", EREMCHG, "Remote address changed");\r
+#endif\r
+#ifdef EAGAIN\r
+ inscode(d, ds, de, "EAGAIN", EAGAIN, "Try again");\r
+#endif\r
+#ifdef ENAMETOOLONG\r
+ inscode(d, ds, de, "ENAMETOOLONG", ENAMETOOLONG, "File name too long");\r
+#else\r
+#ifdef WSAENAMETOOLONG\r
+ inscode(d, ds, de, "ENAMETOOLONG", WSAENAMETOOLONG, "File name too long");\r
+#endif\r
+#endif\r
+#ifdef ENOTTY\r
+ inscode(d, ds, de, "ENOTTY", ENOTTY, "Not a typewriter");\r
+#endif\r
+#ifdef ERESTART\r
+ inscode(d, ds, de, "ERESTART", ERESTART, "Interrupted system call should be restarted");\r
+#endif\r
+#ifdef ESOCKTNOSUPPORT\r
+ inscode(d, ds, de, "ESOCKTNOSUPPORT", ESOCKTNOSUPPORT, "Socket type not supported");\r
+#else\r
+#ifdef WSAESOCKTNOSUPPORT\r
+ inscode(d, ds, de, "ESOCKTNOSUPPORT", WSAESOCKTNOSUPPORT, "Socket type not supported");\r
+#endif\r
+#endif\r
+#ifdef ETIME\r
+ inscode(d, ds, de, "ETIME", ETIME, "Timer expired");\r
+#endif\r
+#ifdef EBFONT\r
+ inscode(d, ds, de, "EBFONT", EBFONT, "Bad font file format");\r
+#endif\r
+#ifdef EDEADLOCK\r
+ inscode(d, ds, de, "EDEADLOCK", EDEADLOCK, "Error EDEADLOCK");\r
+#endif\r
+#ifdef ETOOMANYREFS\r
+ inscode(d, ds, de, "ETOOMANYREFS", ETOOMANYREFS, "Too many references: cannot splice");\r
+#else\r
+#ifdef WSAETOOMANYREFS\r
+ inscode(d, ds, de, "ETOOMANYREFS", WSAETOOMANYREFS, "Too many references: cannot splice");\r
+#endif\r
+#endif\r
+#ifdef EMFILE\r
+ inscode(d, ds, de, "EMFILE", EMFILE, "Too many open files");\r
+#else\r
+#ifdef WSAEMFILE\r
+ inscode(d, ds, de, "EMFILE", WSAEMFILE, "Too many open files");\r
+#endif\r
+#endif\r
+#ifdef ETXTBSY\r
+ inscode(d, ds, de, "ETXTBSY", ETXTBSY, "Text file busy");\r
+#endif\r
+#ifdef EINPROGRESS\r
+ inscode(d, ds, de, "EINPROGRESS", EINPROGRESS, "Operation now in progress");\r
+#else\r
+#ifdef WSAEINPROGRESS\r
+ inscode(d, ds, de, "EINPROGRESS", WSAEINPROGRESS, "Operation now in progress");\r
+#endif\r
+#endif\r
+#ifdef ENXIO\r
+ inscode(d, ds, de, "ENXIO", ENXIO, "No such device or address");\r
+#endif\r
+#ifdef ENOPKG\r
+ inscode(d, ds, de, "ENOPKG", ENOPKG, "Package not installed");\r
+#endif\r
+#ifdef WSASY\r
+ inscode(d, ds, de, "WSASY", WSASY, "Error WSASY");\r
+#endif\r
+#ifdef WSAEHOSTDOWN\r
+ inscode(d, ds, de, "WSAEHOSTDOWN", WSAEHOSTDOWN, "Host is down");\r
+#endif\r
+#ifdef WSAENETDOWN\r
+ inscode(d, ds, de, "WSAENETDOWN", WSAENETDOWN, "Network is down");\r
+#endif\r
+#ifdef WSAENOTSOCK\r
+ inscode(d, ds, de, "WSAENOTSOCK", WSAENOTSOCK, "Socket operation on non-socket");\r
+#endif\r
+#ifdef WSAEHOSTUNREACH\r
+ inscode(d, ds, de, "WSAEHOSTUNREACH", WSAEHOSTUNREACH, "No route to host");\r
+#endif\r
+#ifdef WSAELOOP\r
+ inscode(d, ds, de, "WSAELOOP", WSAELOOP, "Too many symbolic links encountered");\r
+#endif\r
+#ifdef WSAEMFILE\r
+ inscode(d, ds, de, "WSAEMFILE", WSAEMFILE, "Too many open files");\r
+#endif\r
+#ifdef WSAESTALE\r
+ inscode(d, ds, de, "WSAESTALE", WSAESTALE, "Stale NFS file handle");\r
+#endif\r
+#ifdef WSAVERNOTSUPPORTED\r
+ inscode(d, ds, de, "WSAVERNOTSUPPORTED", WSAVERNOTSUPPORTED, "Error WSAVERNOTSUPPORTED");\r
+#endif\r
+#ifdef WSAENETUNREACH\r
+ inscode(d, ds, de, "WSAENETUNREACH", WSAENETUNREACH, "Network is unreachable");\r
+#endif\r
+#ifdef WSAEPROCLIM\r
+ inscode(d, ds, de, "WSAEPROCLIM", WSAEPROCLIM, "Error WSAEPROCLIM");\r
+#endif\r
+#ifdef WSAEFAULT\r
+ inscode(d, ds, de, "WSAEFAULT", WSAEFAULT, "Bad address");\r
+#endif\r
+#ifdef WSANOTINITIALISED\r
+ inscode(d, ds, de, "WSANOTINITIALISED", WSANOTINITIALISED, "Error WSANOTINITIALISED");\r
+#endif\r
+#ifdef WSAEUSERS\r
+ inscode(d, ds, de, "WSAEUSERS", WSAEUSERS, "Too many users");\r
+#endif\r
+#ifdef WSAMAKEASYNCREPL\r
+ inscode(d, ds, de, "WSAMAKEASYNCREPL", WSAMAKEASYNCREPL, "Error WSAMAKEASYNCREPL");\r
+#endif\r
+#ifdef WSAENOPROTOOPT\r
+ inscode(d, ds, de, "WSAENOPROTOOPT", WSAENOPROTOOPT, "Protocol not available");\r
+#endif\r
+#ifdef WSAECONNABORTED\r
+ inscode(d, ds, de, "WSAECONNABORTED", WSAECONNABORTED, "Software caused connection abort");\r
+#endif\r
+#ifdef WSAENAMETOOLONG\r
+ inscode(d, ds, de, "WSAENAMETOOLONG", WSAENAMETOOLONG, "File name too long");\r
+#endif\r
+#ifdef WSAENOTEMPTY\r
+ inscode(d, ds, de, "WSAENOTEMPTY", WSAENOTEMPTY, "Directory not empty");\r
+#endif\r
+#ifdef WSAESHUTDOWN\r
+ inscode(d, ds, de, "WSAESHUTDOWN", WSAESHUTDOWN, "Cannot send after transport endpoint shutdown");\r
+#endif\r
+#ifdef WSAEAFNOSUPPORT\r
+ inscode(d, ds, de, "WSAEAFNOSUPPORT", WSAEAFNOSUPPORT, "Address family not supported by protocol");\r
+#endif\r
+#ifdef WSAETOOMANYREFS\r
+ inscode(d, ds, de, "WSAETOOMANYREFS", WSAETOOMANYREFS, "Too many references: cannot splice");\r
+#endif\r
+#ifdef WSAEACCES\r
+ inscode(d, ds, de, "WSAEACCES", WSAEACCES, "Permission denied");\r
+#endif\r
+#ifdef WSATR\r
+ inscode(d, ds, de, "WSATR", WSATR, "Error WSATR");\r
+#endif\r
+#ifdef WSABASEERR\r
+ inscode(d, ds, de, "WSABASEERR", WSABASEERR, "Error WSABASEERR");\r
+#endif\r
+#ifdef WSADESCRIPTIO\r
+ inscode(d, ds, de, "WSADESCRIPTIO", WSADESCRIPTIO, "Error WSADESCRIPTIO");\r
+#endif\r
+#ifdef WSAEMSGSIZE\r
+ inscode(d, ds, de, "WSAEMSGSIZE", WSAEMSGSIZE, "Message too long");\r
+#endif\r
+#ifdef WSAEBADF\r
+ inscode(d, ds, de, "WSAEBADF", WSAEBADF, "Bad file number");\r
+#endif\r
+#ifdef WSAECONNRESET\r
+ inscode(d, ds, de, "WSAECONNRESET", WSAECONNRESET, "Connection reset by peer");\r
+#endif\r
+#ifdef WSAGETSELECTERRO\r
+ inscode(d, ds, de, "WSAGETSELECTERRO", WSAGETSELECTERRO, "Error WSAGETSELECTERRO");\r
+#endif\r
+#ifdef WSAETIMEDOUT\r
+ inscode(d, ds, de, "WSAETIMEDOUT", WSAETIMEDOUT, "Connection timed out");\r
+#endif\r
+#ifdef WSAENOBUFS\r
+ inscode(d, ds, de, "WSAENOBUFS", WSAENOBUFS, "No buffer space available");\r
+#endif\r
+#ifdef WSAEDISCON\r
+ inscode(d, ds, de, "WSAEDISCON", WSAEDISCON, "Error WSAEDISCON");\r
+#endif\r
+#ifdef WSAEINTR\r
+ inscode(d, ds, de, "WSAEINTR", WSAEINTR, "Interrupted system call");\r
+#endif\r
+#ifdef WSAEPROTOTYPE\r
+ inscode(d, ds, de, "WSAEPROTOTYPE", WSAEPROTOTYPE, "Protocol wrong type for socket");\r
+#endif\r
+#ifdef WSAHOS\r
+ inscode(d, ds, de, "WSAHOS", WSAHOS, "Error WSAHOS");\r
+#endif\r
+#ifdef WSAEADDRINUSE\r
+ inscode(d, ds, de, "WSAEADDRINUSE", WSAEADDRINUSE, "Address already in use");\r
+#endif\r
+#ifdef WSAEADDRNOTAVAIL\r
+ inscode(d, ds, de, "WSAEADDRNOTAVAIL", WSAEADDRNOTAVAIL, "Cannot assign requested address");\r
+#endif\r
+#ifdef WSAEALREADY\r
+ inscode(d, ds, de, "WSAEALREADY", WSAEALREADY, "Operation already in progress");\r
+#endif\r
+#ifdef WSAEPROTONOSUPPORT\r
+ inscode(d, ds, de, "WSAEPROTONOSUPPORT", WSAEPROTONOSUPPORT, "Protocol not supported");\r
+#endif\r
+#ifdef WSASYSNOTREADY\r
+ inscode(d, ds, de, "WSASYSNOTREADY", WSASYSNOTREADY, "Error WSASYSNOTREADY");\r
+#endif\r
+#ifdef WSAEWOULDBLOCK\r
+ inscode(d, ds, de, "WSAEWOULDBLOCK", WSAEWOULDBLOCK, "Operation would block");\r
+#endif\r
+#ifdef WSAEPFNOSUPPORT\r
+ inscode(d, ds, de, "WSAEPFNOSUPPORT", WSAEPFNOSUPPORT, "Protocol family not supported");\r
+#endif\r
+#ifdef WSAEOPNOTSUPP\r
+ inscode(d, ds, de, "WSAEOPNOTSUPP", WSAEOPNOTSUPP, "Operation not supported on transport endpoint");\r
+#endif\r
+#ifdef WSAEISCONN\r
+ inscode(d, ds, de, "WSAEISCONN", WSAEISCONN, "Transport endpoint is already connected");\r
+#endif\r
+#ifdef WSAEDQUOT\r
+ inscode(d, ds, de, "WSAEDQUOT", WSAEDQUOT, "Quota exceeded");\r
+#endif\r
+#ifdef WSAENOTCONN\r
+ inscode(d, ds, de, "WSAENOTCONN", WSAENOTCONN, "Transport endpoint is not connected");\r
+#endif\r
+#ifdef WSAEREMOTE\r
+ inscode(d, ds, de, "WSAEREMOTE", WSAEREMOTE, "Object is remote");\r
+#endif\r
+#ifdef WSAEINVAL\r
+ inscode(d, ds, de, "WSAEINVAL", WSAEINVAL, "Invalid argument");\r
+#endif\r
+#ifdef WSAEINPROGRESS\r
+ inscode(d, ds, de, "WSAEINPROGRESS", WSAEINPROGRESS, "Operation now in progress");\r
+#endif\r
+#ifdef WSAGETSELECTEVEN\r
+ inscode(d, ds, de, "WSAGETSELECTEVEN", WSAGETSELECTEVEN, "Error WSAGETSELECTEVEN");\r
+#endif\r
+#ifdef WSAESOCKTNOSUPPORT\r
+ inscode(d, ds, de, "WSAESOCKTNOSUPPORT", WSAESOCKTNOSUPPORT, "Socket type not supported");\r
+#endif\r
+#ifdef WSAGETASYNCERRO\r
+ inscode(d, ds, de, "WSAGETASYNCERRO", WSAGETASYNCERRO, "Error WSAGETASYNCERRO");\r
+#endif\r
+#ifdef WSAMAKESELECTREPL\r
+ inscode(d, ds, de, "WSAMAKESELECTREPL", WSAMAKESELECTREPL, "Error WSAMAKESELECTREPL");\r
+#endif\r
+#ifdef WSAGETASYNCBUFLE\r
+ inscode(d, ds, de, "WSAGETASYNCBUFLE", WSAGETASYNCBUFLE, "Error WSAGETASYNCBUFLE");\r
+#endif\r
+#ifdef WSAEDESTADDRREQ\r
+ inscode(d, ds, de, "WSAEDESTADDRREQ", WSAEDESTADDRREQ, "Destination address required");\r
+#endif\r
+#ifdef WSAECONNREFUSED\r
+ inscode(d, ds, de, "WSAECONNREFUSED", WSAECONNREFUSED, "Connection refused");\r
+#endif\r
+#ifdef WSAENETRESET\r
+ inscode(d, ds, de, "WSAENETRESET", WSAENETRESET, "Network dropped connection because of reset");\r
+#endif\r
+#ifdef WSAN\r
+ inscode(d, ds, de, "WSAN", WSAN, "Error WSAN");\r
+#endif\r
+#ifdef ENOTSUP\r
+ inscode(d, ds, de, "ENOTSUP", ENOTSUP, "Operation not supported");\r
+#endif\r
+\r
+ Py_DECREF(de);\r
+}\r
--- /dev/null
+/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd\r
+ See the file COPYING for copying permission.\r
+*/\r
+\r
+#ifndef Expat_External_INCLUDED\r
+#define Expat_External_INCLUDED 1\r
+\r
+/* External API definitions */\r
+\r
+/* Namespace external symbols to allow multiple libexpat version to\r
+ co-exist. */\r
+#include "pyexpatns.h"\r
+\r
+#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__)\r
+#define XML_USE_MSC_EXTENSIONS 1\r
+#endif\r
+\r
+/* Expat tries very hard to make the API boundary very specifically\r
+ defined. There are two macros defined to control this boundary;\r
+ each of these can be defined before including this header to\r
+ achieve some different behavior, but doing so it not recommended or\r
+ tested frequently.\r
+\r
+ XMLCALL - The calling convention to use for all calls across the\r
+ "library boundary." This will default to cdecl, and\r
+ try really hard to tell the compiler that's what we\r
+ want.\r
+\r
+ XMLIMPORT - Whatever magic is needed to note that a function is\r
+ to be imported from a dynamically loaded library\r
+ (.dll, .so, or .sl, depending on your platform).\r
+\r
+ The XMLCALL macro was added in Expat 1.95.7. The only one which is\r
+ expected to be directly useful in client code is XMLCALL.\r
+\r
+ Note that on at least some Unix versions, the Expat library must be\r
+ compiled with the cdecl calling convention as the default since\r
+ system headers may assume the cdecl convention.\r
+*/\r
+#ifndef XMLCALL\r
+#if defined(_MSC_VER)\r
+#define XMLCALL __cdecl\r
+#elif defined(__GNUC__) && defined(__i386) && !defined(__INTEL_COMPILER)\r
+#define XMLCALL __attribute__((cdecl))\r
+#else\r
+/* For any platform which uses this definition and supports more than\r
+ one calling convention, we need to extend this definition to\r
+ declare the convention used on that platform, if it's possible to\r
+ do so.\r
+\r
+ If this is the case for your platform, please file a bug report\r
+ with information on how to identify your platform via the C\r
+ pre-processor and how to specify the same calling convention as the\r
+ platform's malloc() implementation.\r
+*/\r
+#define XMLCALL\r
+#endif\r
+#endif /* not defined XMLCALL */\r
+\r
+\r
+#if !defined(XML_STATIC) && !defined(XMLIMPORT)\r
+#ifndef XML_BUILDING_EXPAT\r
+/* using Expat from an application */\r
+\r
+#ifdef XML_USE_MSC_EXTENSIONS\r
+#define XMLIMPORT __declspec(dllimport)\r
+#endif\r
+\r
+#endif\r
+#endif /* not defined XML_STATIC */\r
+\r
+\r
+/* If we didn't define it above, define it away: */\r
+#ifndef XMLIMPORT\r
+#define XMLIMPORT\r
+#endif\r
+\r
+\r
+#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#ifdef XML_UNICODE_WCHAR_T\r
+#define XML_UNICODE\r
+#endif\r
+\r
+#ifdef XML_UNICODE /* Information is UTF-16 encoded. */\r
+#ifdef XML_UNICODE_WCHAR_T\r
+typedef wchar_t XML_Char;\r
+typedef wchar_t XML_LChar;\r
+#else\r
+typedef unsigned short XML_Char;\r
+typedef char XML_LChar;\r
+#endif /* XML_UNICODE_WCHAR_T */\r
+#else /* Information is UTF-8 encoded. */\r
+typedef char XML_Char;\r
+typedef char XML_LChar;\r
+#endif /* XML_UNICODE */\r
+\r
+#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */\r
+#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400\r
+typedef __int64 XML_Index; \r
+typedef unsigned __int64 XML_Size;\r
+#else\r
+typedef long long XML_Index;\r
+typedef unsigned long long XML_Size;\r
+#endif\r
+#else\r
+typedef long XML_Index;\r
+typedef unsigned long XML_Size;\r
+#endif /* XML_LARGE_SIZE */\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* not Expat_External_INCLUDED */\r
--- /dev/null
+/** @file\r
+ Return the initial module search path.\r
+\r
+ Search in specified locations for the associated Python libraries.\r
+\r
+ Py_GetPath returns module_search_path.\r
+ Py_GetPrefix returns PREFIX\r
+ Py_GetExec_Prefix returns PREFIX\r
+ Py_GetProgramFullPath returns the full path to the python executable.\r
+\r
+ These are built dynamically so that the proper volume name can be prefixed\r
+ to the paths.\r
+\r
+ For the EDK II, UEFI, implementation of Python, PREFIX and EXEC_PREFIX\r
+ are set as follows:\r
+ PREFIX = /Efi/StdLib\r
+ EXEC_PREFIX = PREFIX\r
+\r
+ The following final paths are assumed:\r
+ /Efi/Tools/Python.efi The Python executable.\r
+ /Efi/StdLib/lib/python.VERSION The platform independent Python modules.\r
+ /Efi/StdLib/lib/python.VERSION/dynalib Dynamically loadable Python extension modules.\r
+\r
+ Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials are licensed and made available under\r
+ the terms and conditions of the BSD License that accompanies this distribution.\r
+ The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+**/\r
+#include <Python.h>\r
+#include <osdefs.h>\r
+#include <ctype.h>\r
+\r
+#ifdef __cplusplus\r
+ extern "C" {\r
+#endif\r
+\r
+/* VERSION must be at least two characters long. */\r
+#ifndef VERSION\r
+ #define VERSION "27"\r
+#endif\r
+\r
+#ifndef VPATH\r
+ #define VPATH "."\r
+#endif\r
+\r
+/* Search path entry delimiter */\r
+#ifdef DELIM\r
+ #define sDELIM ";"\r
+#endif\r
+\r
+#ifndef PREFIX\r
+ #define PREFIX "/Efi/StdLib"\r
+#endif\r
+\r
+#ifndef EXEC_PREFIX\r
+ #define EXEC_PREFIX PREFIX\r
+#endif\r
+\r
+#ifndef LIBPYTHON\r
+ #define LIBPYTHON "lib/python." VERSION\r
+#endif\r
+\r
+#ifndef PYTHONPATH\r
+ #ifdef HAVE_ENVIRONMENT_OPS\r
+ #define PYTHONPATH PREFIX LIBPYTHON sDELIM \\r
+ EXEC_PREFIX LIBPYTHON "/lib-dynload"\r
+ #else\r
+ #define PYTHONPATH LIBPYTHON\r
+ #endif\r
+#endif\r
+\r
+#ifndef LANDMARK\r
+#define LANDMARK "os.py"\r
+#endif\r
+\r
+static char prefix[MAXPATHLEN+1];\r
+static char exec_prefix[MAXPATHLEN+1];\r
+static char progpath[MAXPATHLEN+1];\r
+static char *module_search_path = NULL;\r
+static char lib_python[] = LIBPYTHON;\r
+static char volume_name[32] = { 0 };\r
+\r
+/** Determine if "ch" is a separator character.\r
+\r
+ @param[in] ch The character to test.\r
+\r
+ @retval TRUE ch is a separator character.\r
+ @retval FALSE ch is NOT a separator character.\r
+**/\r
+static int\r
+is_sep(char ch)\r
+{\r
+#ifdef ALTSEP\r
+ return ch == SEP || ch == ALTSEP;\r
+#else\r
+ return ch == SEP;\r
+#endif\r
+}\r
+\r
+/** Reduce a path by its last element.\r
+\r
+ The last element (everything to the right of the last separator character)\r
+ in the path, dir, is removed from the path. Parameter dir is modified in place.\r
+\r
+ @param[in,out] dir Pointer to the path to modify.\r
+**/\r
+static void\r
+reduce(char *dir)\r
+{\r
+ size_t i = strlen(dir);\r
+ while (i > 0 && !is_sep(dir[i]))\r
+ --i;\r
+ dir[i] = '\0';\r
+}\r
+\r
+#ifndef UEFI_C_SOURCE\r
+/** Does filename point to a file and not directory?\r
+\r
+ @param[in] filename The fully qualified path to the object to test.\r
+\r
+ @retval 0 Filename was not found, or is a directory.\r
+ @retval 1 Filename refers to a regular file.\r
+**/\r
+static int\r
+isfile(char *filename)\r
+{\r
+ struct stat buf;\r
+ if (stat(filename, &buf) != 0) {\r
+ return 0;\r
+ }\r
+ //if (!S_ISREG(buf.st_mode))\r
+ if (S_ISDIR(buf.st_mode)) {\r
+ return 0;\r
+ }\r
+ return 1;\r
+}\r
+\r
+/** Determine if filename refers to a Python module.\r
+\r
+ A Python module is indicated if the file exists, or if the file with\r
+ 'o' or 'c' appended exists.\r
+\r
+ @param[in] filename The fully qualified path to the object to test.\r
+\r
+ @retval 0\r
+**/\r
+static int\r
+ismodule(char *filename)\r
+{\r
+ if (isfile(filename)) {\r
+ //if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: file = \"%s\"\n", __func__, __LINE__, filename);\r
+ return 1;\r
+ }\r
+\r
+ /* Check for the compiled version of prefix. */\r
+ if (strlen(filename) < MAXPATHLEN) {\r
+ strcat(filename, Py_OptimizeFlag ? "o" : "c");\r
+ if (isfile(filename)) {\r
+ return 1;\r
+ }\r
+ }\r
+ return 0;\r
+}\r
+\r
+/** Does filename point to a directory?\r
+\r
+ @param[in] filename The fully qualified path to the object to test.\r
+\r
+ @retval 0 Filename was not found, or is not a regular file.\r
+ @retval 1 Filename refers to a directory.\r
+**/\r
+static int\r
+isdir(char *filename)\r
+{\r
+ struct stat buf;\r
+\r
+ if (stat(filename, &buf) != 0)\r
+ return 0;\r
+\r
+ if (!S_ISDIR(buf.st_mode))\r
+ return 0;\r
+\r
+ return 1;\r
+}\r
+#endif /* UEFI_C_SOURCE */\r
+\r
+/** Determine if a path is absolute, or not.\r
+ An absolute path consists of a volume name, "VOL:", followed by a rooted path,\r
+ "/path/elements". If both of these components are present, the path is absolute.\r
+\r
+ Let P be a pointer to the path to test.\r
+ Let A be a pointer to the first ':' in P.\r
+ Let B be a pointer to the first '/' or '\\' in P.\r
+\r
+ If A and B are not NULL\r
+ If (A-P+1) == (B-P) then the path is absolute.\r
+ Otherwise, the path is NOT absolute.\r
+\r
+ @param[in] path The path to test.\r
+\r
+ @retval -1 Path is absolute but lacking volume name.\r
+ @retval 0 Path is NOT absolute.\r
+ @retval 1 Path is absolute.\r
+*/\r
+static int\r
+is_absolute(char *path)\r
+{\r
+ char *A;\r
+ char *B;\r
+\r
+ A = strchr(path, ':');\r
+ B = strpbrk(path, "/\\");\r
+\r
+ if(B != NULL) {\r
+ if(A == NULL) {\r
+ if(B == path) {\r
+ return -1;\r
+ }\r
+ }\r
+ else {\r
+ if(((A - path) + 1) == (B - path)) {\r
+ return 1;\r
+ }\r
+ }\r
+ }\r
+ return 0;\r
+}\r
+\r
+\r
+/** Add a path component, by appending stuff to buffer.\r
+ buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a\r
+ NUL-terminated string with no more than MAXPATHLEN characters (not counting\r
+ the trailing NUL). It's a fatal error if it contains a string longer than\r
+ that (callers must be careful!). If these requirements are met, it's\r
+ guaranteed that buffer will still be a NUL-terminated string with no more\r
+ than MAXPATHLEN characters at exit. If stuff is too long, only as much of\r
+ stuff as fits will be appended.\r
+\r
+ @param[in,out] buffer The path to be extended.\r
+ @param[in] stuff The stuff to join onto the path.\r
+*/\r
+static void\r
+joinpath(char *buffer, char *stuff)\r
+{\r
+ size_t n, k;\r
+\r
+ k = 0;\r
+ if (is_absolute(stuff) == 1) {\r
+ n = 0;\r
+ }\r
+ else {\r
+ n = strlen(buffer);\r
+ if(n == 0) {\r
+ strncpy(buffer, volume_name, MAXPATHLEN);\r
+ n = strlen(buffer);\r
+ }\r
+ /* We must not use an else clause here because we want to test n again.\r
+ volume_name may have been empty.\r
+ */\r
+ if (n > 0 && n < MAXPATHLEN) {\r
+ if(!is_sep(buffer[n-1])) {\r
+ buffer[n++] = SEP;\r
+ }\r
+ if(is_sep(stuff[0])) ++stuff;\r
+ }\r
+ }\r
+ if (n > MAXPATHLEN)\r
+ Py_FatalError("buffer overflow in getpath.c's joinpath()");\r
+ k = strlen(stuff);\r
+ if (n + k > MAXPATHLEN)\r
+ k = MAXPATHLEN - n;\r
+ strncpy(buffer+n, stuff, k);\r
+ buffer[n+k] = '\0';\r
+}\r
+\r
+/** Is filename an executable file?\r
+\r
+ An executable file:\r
+ 1) exists\r
+ 2) is a file, not a directory\r
+ 3) has a name ending with ".efi"\r
+ 4) Only has a single '.' in the name.\r
+\r
+ If basename(filename) does not contain a '.', append ".efi" to filename\r
+ If filename ends in ".efi", it is executable, else it isn't.\r
+\r
+ This routine is used to when searching for the file named by argv[0].\r
+ As such, there is no need to search for extensions other than ".efi".\r
+\r
+ @param[in] filename The name of the file to test. It may, or may not, have an extension.\r
+\r
+ @retval 0 filename already has a path other than ".efi", or it doesn't exist, or is a directory.\r
+ @retval 1 filename refers to an executable file.\r
+**/\r
+static int\r
+isxfile(char *filename)\r
+{\r
+ struct stat buf;\r
+ char *bn;\r
+ char *newbn;\r
+ int bnlen;\r
+\r
+ bn = basename(filename); // Separate off the file name component\r
+ reduce(filename); // and isolate the path component\r
+ bnlen = strlen(bn);\r
+ newbn = strrchr(bn, '.'); // Does basename contain a period?\r
+ if(newbn == NULL) { // Does NOT contain a period.\r
+ newbn = &bn[bnlen];\r
+ strncpyX(newbn, ".efi", MAXPATHLEN - bnlen); // append ".efi" to basename\r
+ bnlen += 4;\r
+ }\r
+ else if(strcmp(newbn, ".efi") != 0) {\r
+ return 0; // File can not be executable.\r
+ }\r
+ joinpath(filename, bn); // Stitch path and file name back together\r
+\r
+ if (stat(filename, &buf) != 0) { // Now, verify that file exists\r
+ return 0;\r
+ }\r
+ if(S_ISDIR(buf.st_mode)) { // And it is not a directory.\r
+ return 0;\r
+ }\r
+\r
+ return 1;\r
+}\r
+\r
+/** Copy p into path, ensuring that the result is an absolute path.\r
+\r
+ copy_absolute requires that path be allocated at least\r
+ MAXPATHLEN + 1 bytes and that p be no more than MAXPATHLEN bytes.\r
+\r
+ @param[out] path Destination to receive the absolute path.\r
+ @param[in] p Path to be tested and possibly converted.\r
+**/\r
+static void\r
+copy_absolute(char *path, char *p)\r
+{\r
+ if (is_absolute(p) == 1)\r
+ strcpy(path, p);\r
+ else {\r
+ if (!getcwd(path, MAXPATHLEN)) {\r
+ /* unable to get the current directory */\r
+ if(volume_name[0] != 0) {\r
+ strcpy(path, volume_name);\r
+ joinpath(path, p);\r
+ }\r
+ else\r
+ strcpy(path, p);\r
+ return;\r
+ }\r
+ if (p[0] == '.' && is_sep(p[1]))\r
+ p += 2;\r
+ joinpath(path, p);\r
+ }\r
+}\r
+\r
+/** Modify path so that the result is an absolute path.\r
+ absolutize() requires that path be allocated at least MAXPATHLEN+1 bytes.\r
+\r
+ @param[in,out] path The path to be made absolute.\r
+*/\r
+static void\r
+absolutize(char *path)\r
+{\r
+ char buffer[MAXPATHLEN + 1];\r
+\r
+ if (is_absolute(path) == 1)\r
+ return;\r
+ copy_absolute(buffer, path);\r
+ strcpy(path, buffer);\r
+}\r
+\r
+/** Extract the volume name from a path.\r
+\r
+ @param[out] Dest Pointer to location in which to store the extracted volume name.\r
+ @param[in] path Pointer to the path to extract the volume name from.\r
+**/\r
+static void\r
+set_volume(char *Dest, char *path)\r
+{\r
+ size_t VolLen;\r
+\r
+ if(is_absolute(path)) {\r
+ VolLen = strcspn(path, "/\\:");\r
+ if((VolLen != 0) && (path[VolLen] == ':')) {\r
+ (void) strncpyX(Dest, path, VolLen + 1);\r
+ }\r
+ }\r
+}\r
+\r
+\r
+/** Determine paths.\r
+\r
+ Two directories must be found, the platform independent directory\r
+ (prefix), containing the common .py and .pyc files, and the platform\r
+ dependent directory (exec_prefix), containing the shared library\r
+ modules. Note that prefix and exec_prefix are the same directory\r
+ for UEFI installations.\r
+\r
+ Separate searches are carried out for prefix and exec_prefix.\r
+ Each search tries a number of different locations until a ``landmark''\r
+ file or directory is found. If no prefix or exec_prefix is found, a\r
+ warning message is issued and the preprocessor defined PREFIX and\r
+ EXEC_PREFIX are used (even though they may not work); python carries on\r
+ as best as is possible, but some imports may fail.\r
+\r
+ Before any searches are done, the location of the executable is\r
+ determined. If argv[0] has one or more slashes in it, it is used\r
+ unchanged. Otherwise, it must have been invoked from the shell's path,\r
+ so we search %PATH% for the named executable and use that. If the\r
+ executable was not found on %PATH% (or there was no %PATH% environment\r
+ variable), the original argv[0] string is used.\r
+\r
+ Finally, argv0_path is set to the directory containing the executable\r
+ (i.e. the last component is stripped).\r
+\r
+ With argv0_path in hand, we perform a number of steps. The same steps\r
+ are performed for prefix and for exec_prefix, but with a different\r
+ landmark.\r
+\r
+ The prefix landmark will always be lib/python.VERSION/os.py and the\r
+ exec_prefix will always be lib/python.VERSION/dynaload, where VERSION\r
+ is Python's version number as defined at the beginning of this file.\r
+\r
+ First. See if the %PYTHONHOME% environment variable points to the\r
+ installed location of the Python libraries. If %PYTHONHOME% is set, then\r
+ it points to prefix and exec_prefix. %PYTHONHOME% can be a single\r
+ directory, which is used for both, or the prefix and exec_prefix\r
+ directories separated by the DELIM character.\r
+\r
+ Next. Search the directories pointed to by the preprocessor variables\r
+ PREFIX and EXEC_PREFIX. These paths are prefixed with the volume name\r
+ extracted from argv0_path. The volume names correspond to the UEFI\r
+ shell "map" names.\r
+\r
+ That's it!\r
+\r
+ Well, almost. Once we have determined prefix and exec_prefix, the\r
+ preprocessor variable PYTHONPATH is used to construct a path. Each\r
+ relative path on PYTHONPATH is prefixed with prefix. Then the directory\r
+ containing the shared library modules is appended. The environment\r
+ variable $PYTHONPATH is inserted in front of it all. Finally, the\r
+ prefix and exec_prefix globals are tweaked so they reflect the values\r
+ expected by other code, by stripping the "lib/python$VERSION/..." stuff\r
+ off. This seems to make more sense given that currently the only\r
+ known use of sys.prefix and sys.exec_prefix is for the ILU installation\r
+ process to find the installed Python tree.\r
+\r
+ The final, fully resolved, paths should look something like:\r
+ fs0:/Efi/Tools/python.efi\r
+ fs0:/Efi/StdLib/lib/python27\r
+ fs0:/Efi/StdLib/lib/python27/dynaload\r
+\r
+**/\r
+static void\r
+calculate_path(void)\r
+{\r
+ extern char *Py_GetProgramName(void);\r
+\r
+ static char delimiter[2] = {DELIM, '\0'};\r
+ static char separator[2] = {SEP, '\0'};\r
+ char *pythonpath = PYTHONPATH;\r
+ char *rtpypath = Py_GETENV("PYTHONPATH");\r
+ //char *home = Py_GetPythonHome();\r
+ char *path = getenv("PATH");\r
+ char *prog = Py_GetProgramName();\r
+ char argv0_path[MAXPATHLEN+1];\r
+ char zip_path[MAXPATHLEN+1];\r
+ char *buf;\r
+ size_t bufsz;\r
+ size_t prefixsz;\r
+ char *defpath;\r
+\r
+\r
+/* ###########################################################################\r
+ Determine path to the Python.efi binary.\r
+ Produces progpath, argv0_path, and volume_name.\r
+########################################################################### */\r
+\r
+ /* If there is no slash in the argv0 path, then we have to\r
+ * assume python is on the user's $PATH, since there's no\r
+ * other way to find a directory to start the search from. If\r
+ * $PATH isn't exported, you lose.\r
+ */\r
+ if (strchr(prog, SEP))\r
+ strncpy(progpath, prog, MAXPATHLEN);\r
+ else if (path) {\r
+ while (1) {\r
+ char *delim = strchr(path, DELIM);\r
+\r
+ if (delim) {\r
+ size_t len = delim - path;\r
+ if (len > MAXPATHLEN)\r
+ len = MAXPATHLEN;\r
+ strncpy(progpath, path, len);\r
+ *(progpath + len) = '\0';\r
+ }\r
+ else\r
+ strncpy(progpath, path, MAXPATHLEN);\r
+\r
+ joinpath(progpath, prog);\r
+ if (isxfile(progpath))\r
+ break;\r
+\r
+ if (!delim) {\r
+ progpath[0] = '\0';\r
+ break;\r
+ }\r
+ path = delim + 1;\r
+ }\r
+ }\r
+ else\r
+ progpath[0] = '\0';\r
+ if ( (!is_absolute(progpath)) && (progpath[0] != '\0') )\r
+ absolutize(progpath);\r
+ strncpy(argv0_path, progpath, MAXPATHLEN);\r
+ argv0_path[MAXPATHLEN] = '\0';\r
+ set_volume(volume_name, argv0_path);\r
+\r
+ reduce(argv0_path);\r
+ /* At this point, argv0_path is guaranteed to be less than\r
+ MAXPATHLEN bytes long.\r
+ */\r
+\r
+/* ###########################################################################\r
+ Build the FULL prefix string, including volume name.\r
+ This is the full path to the platform independent libraries.\r
+########################################################################### */\r
+\r
+ strncpy(prefix, volume_name, MAXPATHLEN);\r
+ joinpath(prefix, PREFIX);\r
+ joinpath(prefix, lib_python);\r
+\r
+/* ###########################################################################\r
+ Build the FULL path to the zipped-up Python library.\r
+########################################################################### */\r
+\r
+ strncpy(zip_path, prefix, MAXPATHLEN);\r
+ zip_path[MAXPATHLEN] = '\0';\r
+ reduce(zip_path);\r
+ joinpath(zip_path, "python00.zip");\r
+ bufsz = strlen(zip_path); /* Replace "00" with version */\r
+ zip_path[bufsz - 6] = VERSION[0];\r
+ zip_path[bufsz - 5] = VERSION[1];\r
+\r
+/* ###########################################################################\r
+ Build the FULL path to dynamically loadable libraries.\r
+########################################################################### */\r
+\r
+ strncpy(exec_prefix, volume_name, MAXPATHLEN);\r
+ joinpath(exec_prefix, EXEC_PREFIX);\r
+ joinpath(exec_prefix, lib_python);\r
+ joinpath(exec_prefix, "lib-dynload");\r
+\r
+/* ###########################################################################\r
+ Build the module search path.\r
+########################################################################### */\r
+\r
+ /* Reduce prefix and exec_prefix to their essence,\r
+ * e.g. /usr/local/lib/python1.5 is reduced to /usr/local.\r
+ * If we're loading relative to the build directory,\r
+ * return the compiled-in defaults instead.\r
+ */\r
+ reduce(prefix);\r
+ reduce(prefix);\r
+ /* The prefix is the root directory, but reduce() chopped\r
+ * off the "/". */\r
+ if (!prefix[0]) {\r
+ strcpy(prefix, volume_name);\r
+ }\r
+ bufsz = strlen(prefix);\r
+ if(prefix[bufsz-1] == ':') {\r
+ prefix[bufsz] = SEP;\r
+ prefix[bufsz+1] = 0;\r
+ }\r
+\r
+ /* Calculate size of return buffer.\r
+ */\r
+ defpath = pythonpath;\r
+ bufsz = 0;\r
+\r
+ if (rtpypath)\r
+ bufsz += strlen(rtpypath) + 1;\r
+\r
+ prefixsz = strlen(prefix) + 1;\r
+\r
+ while (1) {\r
+ char *delim = strchr(defpath, DELIM);\r
+\r
+ if (is_absolute(defpath) == 0)\r
+ /* Paths are relative to prefix */\r
+ bufsz += prefixsz;\r
+\r
+ if (delim)\r
+ bufsz += delim - defpath + 1;\r
+ else {\r
+ bufsz += strlen(defpath) + 1;\r
+ break;\r
+ }\r
+ defpath = delim + 1;\r
+ }\r
+\r
+ bufsz += strlen(zip_path) + 1;\r
+ bufsz += strlen(exec_prefix) + 1;\r
+\r
+ /* This is the only malloc call in this file */\r
+ buf = (char *)PyMem_Malloc(bufsz);\r
+\r
+ if (buf == NULL) {\r
+ /* We can't exit, so print a warning and limp along */\r
+ fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n");\r
+ fprintf(stderr, "Using default static PYTHONPATH.\n");\r
+ module_search_path = PYTHONPATH;\r
+ }\r
+ else {\r
+ /* Run-time value of $PYTHONPATH goes first */\r
+ if (rtpypath) {\r
+ strcpy(buf, rtpypath);\r
+ strcat(buf, delimiter);\r
+ }\r
+ else\r
+ buf[0] = '\0';\r
+\r
+ /* Next is the default zip path */\r
+ strcat(buf, zip_path);\r
+ strcat(buf, delimiter);\r
+\r
+ /* Next goes merge of compile-time $PYTHONPATH with\r
+ * dynamically located prefix.\r
+ */\r
+ defpath = pythonpath;\r
+ while (1) {\r
+ char *delim = strchr(defpath, DELIM);\r
+\r
+ if (is_absolute(defpath) != 1) {\r
+ strcat(buf, prefix);\r
+ strcat(buf, separator);\r
+ }\r
+\r
+ if (delim) {\r
+ size_t len = delim - defpath + 1;\r
+ size_t end = strlen(buf) + len;\r
+ strncat(buf, defpath, len);\r
+ *(buf + end) = '\0';\r
+ }\r
+ else {\r
+ strcat(buf, defpath);\r
+ break;\r
+ }\r
+ defpath = delim + 1;\r
+ }\r
+ strcat(buf, delimiter);\r
+\r
+ /* Finally, on goes the directory for dynamic-load modules */\r
+ strcat(buf, exec_prefix);\r
+\r
+ /* And publish the results */\r
+ module_search_path = buf;\r
+ }\r
+ /* At this point, exec_prefix is set to VOL:/Efi/StdLib/lib/python.27/dynalib.\r
+ We want to get back to the root value, so we have to remove the final three\r
+ segments to get VOL:/Efi/StdLib. Because we don't know what VOL is, and\r
+ EXEC_PREFIX is also indeterminate, we just remove the three final segments.\r
+ */\r
+ reduce(exec_prefix);\r
+ reduce(exec_prefix);\r
+ reduce(exec_prefix);\r
+ if (!exec_prefix[0]) {\r
+ strcpy(exec_prefix, volume_name);\r
+ }\r
+ bufsz = strlen(exec_prefix);\r
+ if(exec_prefix[bufsz-1] == ':') {\r
+ exec_prefix[bufsz] = SEP;\r
+ exec_prefix[bufsz+1] = 0;\r
+ }\r
+ if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: module_search_path = \"%s\"\n", __func__, __LINE__, module_search_path);\r
+ if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: prefix = \"%s\"\n", __func__, __LINE__, prefix);\r
+ if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: exec_prefix = \"%s\"\n", __func__, __LINE__, exec_prefix);\r
+ if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: progpath = \"%s\"\n", __func__, __LINE__, progpath);\r
+}\r
+\r
+\r
+/* External interface */\r
+\r
+char *\r
+Py_GetPath(void)\r
+{\r
+ if (!module_search_path)\r
+ calculate_path();\r
+ return module_search_path;\r
+}\r
+\r
+char *\r
+Py_GetPrefix(void)\r
+{\r
+ if (!module_search_path)\r
+ calculate_path();\r
+ return prefix;\r
+}\r
+\r
+char *\r
+Py_GetExecPrefix(void)\r
+{\r
+ if (!module_search_path)\r
+ calculate_path();\r
+ return exec_prefix;\r
+}\r
+\r
+char *\r
+Py_GetProgramFullPath(void)\r
+{\r
+ if (!module_search_path)\r
+ calculate_path();\r
+ return progpath;\r
+}\r
+\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
--- /dev/null
+/* Python interpreter main program */\r
+\r
+#include "Python.h"\r
+#include "osdefs.h"\r
+#include "code.h" /* For CO_FUTURE_DIVISION */\r
+#include "import.h"\r
+\r
+#ifdef __VMS\r
+#include <unixlib.h>\r
+#endif\r
+\r
+#if defined(MS_WINDOWS) || defined(__CYGWIN__)\r
+#ifdef HAVE_FCNTL_H\r
+#include <fcntl.h>\r
+#endif\r
+#endif\r
+\r
+#if (defined(PYOS_OS2) && !defined(PYCC_GCC)) || defined(MS_WINDOWS)\r
+#define PYTHONHOMEHELP "<prefix>\\lib"\r
+#else\r
+#if defined(PYOS_OS2) && defined(PYCC_GCC)\r
+#define PYTHONHOMEHELP "<prefix>/Lib"\r
+#else\r
+#define PYTHONHOMEHELP "<prefix>/pythonX.X"\r
+#endif\r
+#endif\r
+\r
+#include "pygetopt.h"\r
+\r
+#define COPYRIGHT \\r
+ "Type \"help\", \"copyright\", \"credits\" or \"license\" " \\r
+ "for more information."\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/* For Py_GetArgcArgv(); set by main() */\r
+static char **orig_argv;\r
+static int orig_argc;\r
+\r
+/* command line options */\r
+#define BASE_OPTS "3bBc:dEhiJm:OQ:RsStuUvVW:xX?"\r
+\r
+#ifndef RISCOS\r
+#define PROGRAM_OPTS BASE_OPTS\r
+#else /*RISCOS*/\r
+/* extra option saying that we are running under a special task window\r
+ frontend; especially my_readline will behave different */\r
+#define PROGRAM_OPTS BASE_OPTS "w"\r
+/* corresponding flag */\r
+extern int Py_RISCOSWimpFlag;\r
+#endif /*RISCOS*/\r
+\r
+/* Short usage message (with %s for argv0) */\r
+static char *usage_line =\r
+"usage: %s [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";\r
+\r
+/* Long usage message, split into parts < 512 bytes */\r
+static char *usage_1 = "\\r
+Options and arguments (and corresponding environment variables):\n\\r
+-B : don't write .py[co] files on import; also PYTHONDONTWRITEBYTECODE=x\n\\r
+-c cmd : program passed in as string (terminates option list)\n\\r
+-d : debug output from parser; also PYTHONDEBUG=x\n\\r
+-E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\\r
+-h : print this help message and exit (also --help)\n\\r
+-i : inspect interactively after running script; forces a prompt even\n\\r
+";\r
+static char *usage_2 = "\\r
+ if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\\r
+-m mod : run library module as a script (terminates option list)\n\\r
+-O : optimize generated bytecode slightly; also PYTHONOPTIMIZE=x\n\\r
+-OO : remove doc-strings in addition to the -O optimizations\n\\r
+-R : use a pseudo-random salt to make hash() values of various types be\n\\r
+ unpredictable between separate invocations of the interpreter, as\n\\r
+ a defense against denial-of-service attacks\n\\r
+-Q arg : division options: -Qold (default), -Qwarn, -Qwarnall, -Qnew\n\\r
+-s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\\r
+-S : don't imply 'import site' on initialization\n\\r
+-t : issue warnings about inconsistent tab usage (-tt: issue errors)\n\\r
+";\r
+static char *usage_3 = "\\r
+-u : unbuffered binary stdout and stderr; also PYTHONUNBUFFERED=x\n\\r
+ see man page for details on internal buffering relating to '-u'\n\\r
+-v : verbose (trace import statements); also PYTHONVERBOSE=x\n\\r
+ can be supplied multiple times to increase verbosity\n\\r
+-V : print the Python version number and exit (also --version)\n\\r
+-W arg : warning control; arg is action:message:category:module:lineno\n\\r
+ also PYTHONWARNINGS=arg\n\\r
+-x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\\r
+";\r
+static char *usage_4 = "\\r
+-3 : warn about Python 3.x incompatibilities that 2to3 cannot trivially fix\n\\r
+file : program read from script file\n\\r
+- : program read from stdin (default; interactive mode if a tty)\n\\r
+arg ...: arguments passed to program in sys.argv[1:]\n\n\\r
+Other environment variables:\n\\r
+PYTHONSTARTUP: file executed on interactive startup (no default)\n\\r
+PYTHONPATH : '%c'-separated list of directories prefixed to the\n\\r
+ default module search path. The result is sys.path.\n\\r
+";\r
+static char *usage_5 = "\\r
+PYTHONHOME : alternate <prefix> directory (or <prefix>%c<exec_prefix>).\n\\r
+ The default module search path uses %s.\n\\r
+PYTHONCASEOK : ignore case in 'import' statements (Windows).\n\\r
+PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr.\n\\r
+";\r
+static char *usage_6 = "\\r
+PYTHONHASHSEED: if this variable is set to 'random', the effect is the same\n\\r
+ as specifying the -R option: a random value is used to seed the hashes of\n\\r
+ str, bytes and datetime objects. It can also be set to an integer\n\\r
+ in the range [0,4294967295] to get hash values with a predictable seed.\n\\r
+";\r
+\r
+\r
+static int\r
+usage(int exitcode, char* program)\r
+{\r
+ FILE *f = exitcode ? stderr : stdout;\r
+\r
+ fprintf(f, usage_line, program);\r
+ if (exitcode)\r
+ fprintf(f, "Try `python -h' for more information.\n");\r
+ else {\r
+ fputs(usage_1, f);\r
+ fputs(usage_2, f);\r
+ fputs(usage_3, f);\r
+ fprintf(f, usage_4, DELIM);\r
+ fprintf(f, usage_5, DELIM, PYTHONHOMEHELP);\r
+ fputs(usage_6, f);\r
+ }\r
+#if defined(__VMS)\r
+ if (exitcode == 0) {\r
+ /* suppress 'error' message */\r
+ return 1;\r
+ }\r
+ else {\r
+ /* STS$M_INHIB_MSG + SS$_ABORT */\r
+ return 0x1000002c;\r
+ }\r
+#else\r
+ return exitcode;\r
+#endif\r
+ /*NOTREACHED*/\r
+}\r
+\r
+static void RunStartupFile(PyCompilerFlags *cf)\r
+{\r
+ char *startup = Py_GETENV("PYTHONSTARTUP");\r
+ if (startup != NULL && startup[0] != '\0') {\r
+ FILE *fp = fopen(startup, "r");\r
+ if (fp != NULL) {\r
+ (void) PyRun_SimpleFileExFlags(fp, startup, 0, cf);\r
+ PyErr_Clear();\r
+ fclose(fp);\r
+ } else {\r
+ int save_errno;\r
+ save_errno = errno;\r
+ PySys_WriteStderr("Could not open PYTHONSTARTUP\n");\r
+ errno = save_errno;\r
+ PyErr_SetFromErrnoWithFilename(PyExc_IOError,\r
+ startup);\r
+ PyErr_Print();\r
+ PyErr_Clear();\r
+ }\r
+ }\r
+}\r
+\r
+\r
+static int RunModule(char *module, int set_argv0)\r
+{\r
+ PyObject *runpy, *runmodule, *runargs, *result;\r
+ runpy = PyImport_ImportModule("runpy");\r
+ if (runpy == NULL) {\r
+ fprintf(stderr, "Could not import runpy module\n");\r
+ return -1;\r
+ }\r
+ runmodule = PyObject_GetAttrString(runpy, "_run_module_as_main");\r
+ if (runmodule == NULL) {\r
+ fprintf(stderr, "Could not access runpy._run_module_as_main\n");\r
+ Py_DECREF(runpy);\r
+ return -1;\r
+ }\r
+ runargs = Py_BuildValue("(si)", module, set_argv0);\r
+ if (runargs == NULL) {\r
+ fprintf(stderr,\r
+ "Could not create arguments for runpy._run_module_as_main\n");\r
+ Py_DECREF(runpy);\r
+ Py_DECREF(runmodule);\r
+ return -1;\r
+ }\r
+ result = PyObject_Call(runmodule, runargs, NULL);\r
+ if (result == NULL) {\r
+ PyErr_Print();\r
+ }\r
+ Py_DECREF(runpy);\r
+ Py_DECREF(runmodule);\r
+ Py_DECREF(runargs);\r
+ if (result == NULL) {\r
+ return -1;\r
+ }\r
+ Py_DECREF(result);\r
+ return 0;\r
+}\r
+\r
+static int RunMainFromImporter(char *filename)\r
+{\r
+ PyObject *argv0 = NULL, *importer = NULL;\r
+\r
+ if ((argv0 = PyString_FromString(filename)) &&\r
+ (importer = PyImport_GetImporter(argv0)) &&\r
+ (importer->ob_type != &PyNullImporter_Type))\r
+ {\r
+ /* argv0 is usable as an import source, so\r
+ put it in sys.path[0] and import __main__ */\r
+ PyObject *sys_path = NULL;\r
+ if ((sys_path = PySys_GetObject("path")) &&\r
+ !PyList_SetItem(sys_path, 0, argv0))\r
+ {\r
+ Py_INCREF(argv0);\r
+ Py_DECREF(importer);\r
+ sys_path = NULL;\r
+ return RunModule("__main__", 0) != 0;\r
+ }\r
+ }\r
+ Py_XDECREF(argv0);\r
+ Py_XDECREF(importer);\r
+ if (PyErr_Occurred()) {\r
+ PyErr_Print();\r
+ return 1;\r
+ }\r
+ return -1;\r
+}\r
+\r
+\r
+/* Main program */\r
+\r
+int\r
+Py_Main(int argc, char **argv)\r
+{\r
+ int c;\r
+ int sts;\r
+ char *command = NULL;\r
+ char *filename = NULL;\r
+ char *module = NULL;\r
+ FILE *fp = stdin;\r
+ char *p;\r
+ int unbuffered = 0;\r
+ int skipfirstline = 0;\r
+ int stdin_is_interactive = 0;\r
+ int help = 0;\r
+ int version = 0;\r
+ int saw_unbuffered_flag = 0;\r
+ PyCompilerFlags cf;\r
+\r
+ cf.cf_flags = 0;\r
+\r
+ orig_argc = argc; /* For Py_GetArgcArgv() */\r
+ orig_argv = argv;\r
+\r
+#ifdef RISCOS\r
+ Py_RISCOSWimpFlag = 0;\r
+#endif\r
+\r
+ /* Hash randomization needed early for all string operations\r
+ (including -W and -X options). */\r
+ _PyOS_opterr = 0; /* prevent printing the error in 1st pass */\r
+ while ((c = _PyOS_GetOpt(argc, argv, PROGRAM_OPTS)) != EOF) {\r
+ if (c == 'm' || c == 'c') {\r
+ /* -c / -m is the last option: following arguments are\r
+ not interpreter options. */\r
+ break;\r
+ }\r
+ switch (c) {\r
+ case 'E':\r
+ Py_IgnoreEnvironmentFlag++;\r
+ break;\r
+ case 'R':\r
+ Py_HashRandomizationFlag++;\r
+ break;\r
+ }\r
+ }\r
+ /* The variable is only tested for existence here; _PyRandom_Init will\r
+ check its value further. */\r
+ if (!Py_HashRandomizationFlag &&\r
+ (p = Py_GETENV("PYTHONHASHSEED")) && *p != '\0')\r
+ Py_HashRandomizationFlag = 1;\r
+\r
+ _PyRandom_Init();\r
+\r
+ PySys_ResetWarnOptions();\r
+ _PyOS_ResetGetOpt();\r
+\r
+ while ((c = _PyOS_GetOpt(argc, argv, PROGRAM_OPTS)) != EOF) {\r
+ if (c == 'c') {\r
+ /* -c is the last option; following arguments\r
+ that look like options are left for the\r
+ command to interpret. */\r
+ command = (char *)malloc(strlen(_PyOS_optarg) + 2);\r
+ if (command == NULL)\r
+ Py_FatalError(\r
+ "not enough memory to copy -c argument");\r
+ strcpy(command, _PyOS_optarg);\r
+ strcat(command, "\n");\r
+ break;\r
+ }\r
+\r
+ if (c == 'm') {\r
+ /* -m is the last option; following arguments\r
+ that look like options are left for the\r
+ module to interpret. */\r
+ module = (char *)malloc(strlen(_PyOS_optarg) + 2);\r
+ if (module == NULL)\r
+ Py_FatalError(\r
+ "not enough memory to copy -m argument");\r
+ strcpy(module, _PyOS_optarg);\r
+ break;\r
+ }\r
+\r
+ switch (c) {\r
+ case 'b':\r
+ Py_BytesWarningFlag++;\r
+ break;\r
+\r
+ case 'd':\r
+ Py_DebugFlag++;\r
+ break;\r
+\r
+ case '3':\r
+ Py_Py3kWarningFlag++;\r
+ if (!Py_DivisionWarningFlag)\r
+ Py_DivisionWarningFlag = 1;\r
+ break;\r
+\r
+ case 'Q':\r
+ if (strcmp(_PyOS_optarg, "old") == 0) {\r
+ Py_DivisionWarningFlag = 0;\r
+ break;\r
+ }\r
+ if (strcmp(_PyOS_optarg, "warn") == 0) {\r
+ Py_DivisionWarningFlag = 1;\r
+ break;\r
+ }\r
+ if (strcmp(_PyOS_optarg, "warnall") == 0) {\r
+ Py_DivisionWarningFlag = 2;\r
+ break;\r
+ }\r
+ if (strcmp(_PyOS_optarg, "new") == 0) {\r
+ /* This only affects __main__ */\r
+ cf.cf_flags |= CO_FUTURE_DIVISION;\r
+ /* And this tells the eval loop to treat\r
+ BINARY_DIVIDE as BINARY_TRUE_DIVIDE */\r
+ _Py_QnewFlag = 1;\r
+ break;\r
+ }\r
+ fprintf(stderr,\r
+ "-Q option should be `-Qold', "\r
+ "`-Qwarn', `-Qwarnall', or `-Qnew' only\n");\r
+ return usage(2, argv[0]);\r
+ /* NOTREACHED */\r
+\r
+ case 'i':\r
+ Py_InspectFlag++;\r
+ Py_InteractiveFlag++;\r
+ break;\r
+\r
+ /* case 'J': reserved for Jython */\r
+\r
+ case 'O':\r
+ Py_OptimizeFlag++;\r
+ break;\r
+\r
+ case 'B':\r
+ Py_DontWriteBytecodeFlag++;\r
+ break;\r
+\r
+ case 's':\r
+ Py_NoUserSiteDirectory++;\r
+ break;\r
+\r
+ case 'S':\r
+ Py_NoSiteFlag++;\r
+ break;\r
+\r
+ case 'E':\r
+ /* Already handled above */\r
+ break;\r
+\r
+ case 't':\r
+ Py_TabcheckFlag++;\r
+ break;\r
+\r
+ case 'u':\r
+ unbuffered++;\r
+ saw_unbuffered_flag = 1;\r
+ break;\r
+\r
+ case 'v':\r
+ Py_VerboseFlag++;\r
+ break;\r
+\r
+#ifdef RISCOS\r
+ case 'w':\r
+ Py_RISCOSWimpFlag = 1;\r
+ break;\r
+#endif\r
+\r
+ case 'x':\r
+ skipfirstline = 1;\r
+ break;\r
+\r
+ /* case 'X': reserved for implementation-specific arguments */\r
+\r
+ case 'U':\r
+ Py_UnicodeFlag++;\r
+ break;\r
+ case 'h':\r
+ case '?':\r
+ help++;\r
+ break;\r
+ case 'V':\r
+ version++;\r
+ break;\r
+\r
+ case 'W':\r
+ PySys_AddWarnOption(_PyOS_optarg);\r
+ break;\r
+\r
+ case 'R':\r
+ /* Already handled above */\r
+ break;\r
+\r
+ /* This space reserved for other options */\r
+\r
+ default:\r
+ return usage(2, argv[0]);\r
+ /*NOTREACHED*/\r
+\r
+ }\r
+ }\r
+\r
+ if (help)\r
+ return usage(0, argv[0]);\r
+\r
+ if (version) {\r
+ fprintf(stderr, "Python %s\n", PY_VERSION);\r
+ return 0;\r
+ }\r
+\r
+ if (Py_Py3kWarningFlag && !Py_TabcheckFlag)\r
+ /* -3 implies -t (but not -tt) */\r
+ Py_TabcheckFlag = 1;\r
+\r
+ if (!Py_InspectFlag &&\r
+ (p = Py_GETENV("PYTHONINSPECT")) && *p != '\0')\r
+ Py_InspectFlag = 1;\r
+ if (!saw_unbuffered_flag &&\r
+ (p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0')\r
+ unbuffered = 1;\r
+\r
+ if (!Py_NoUserSiteDirectory &&\r
+ (p = Py_GETENV("PYTHONNOUSERSITE")) && *p != '\0')\r
+ Py_NoUserSiteDirectory = 1;\r
+\r
+ if ((p = Py_GETENV("PYTHONWARNINGS")) && *p != '\0') {\r
+ char *buf, *warning;\r
+\r
+ buf = (char *)malloc(strlen(p) + 1);\r
+ if (buf == NULL)\r
+ Py_FatalError(\r
+ "not enough memory to copy PYTHONWARNINGS");\r
+ strcpy(buf, p);\r
+ for (warning = strtok(buf, ",");\r
+ warning != NULL;\r
+ warning = strtok(NULL, ","))\r
+ PySys_AddWarnOption(warning);\r
+ free(buf);\r
+ }\r
+\r
+ if (command == NULL && module == NULL && _PyOS_optind < argc &&\r
+ strcmp(argv[_PyOS_optind], "-") != 0)\r
+ {\r
+#ifdef __VMS\r
+ filename = decc$translate_vms(argv[_PyOS_optind]);\r
+ if (filename == (char *)0 || filename == (char *)-1)\r
+ filename = argv[_PyOS_optind];\r
+\r
+#else\r
+ filename = argv[_PyOS_optind];\r
+#endif\r
+ }\r
+\r
+ stdin_is_interactive = Py_FdIsInteractive(stdin, (char *)0);\r
+\r
+ if (unbuffered) {\r
+#if defined(MS_WINDOWS) || defined(__CYGWIN__)\r
+ _setmode(fileno(stdin), O_BINARY);\r
+ _setmode(fileno(stdout), O_BINARY);\r
+#endif\r
+#ifdef HAVE_SETVBUF\r
+ setvbuf(stdin, (char *)NULL, _IONBF, BUFSIZ);\r
+ setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);\r
+ setvbuf(stderr, (char *)NULL, _IONBF, BUFSIZ);\r
+#else /* !HAVE_SETVBUF */\r
+ setbuf(stdin, (char *)NULL);\r
+ setbuf(stdout, (char *)NULL);\r
+ setbuf(stderr, (char *)NULL);\r
+#endif /* !HAVE_SETVBUF */\r
+ }\r
+ else if (Py_InteractiveFlag) {\r
+#ifdef MS_WINDOWS\r
+ /* Doesn't have to have line-buffered -- use unbuffered */\r
+ /* Any set[v]buf(stdin, ...) screws up Tkinter :-( */\r
+ setvbuf(stdout, (char *)NULL, _IONBF, BUFSIZ);\r
+#else /* !MS_WINDOWS */\r
+#ifdef HAVE_SETVBUF\r
+ setvbuf(stdin, (char *)NULL, _IOLBF, BUFSIZ);\r
+ setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);\r
+#endif /* HAVE_SETVBUF */\r
+#endif /* !MS_WINDOWS */\r
+ /* Leave stderr alone - it should be unbuffered anyway. */\r
+ }\r
+#ifdef __VMS\r
+ else {\r
+ setvbuf (stdout, (char *)NULL, _IOLBF, BUFSIZ);\r
+ }\r
+#endif /* __VMS */\r
+\r
+#ifdef __APPLE__\r
+ /* On MacOS X, when the Python interpreter is embedded in an\r
+ application bundle, it gets executed by a bootstrapping script\r
+ that does os.execve() with an argv[0] that's different from the\r
+ actual Python executable. This is needed to keep the Finder happy,\r
+ or rather, to work around Apple's overly strict requirements of\r
+ the process name. However, we still need a usable sys.executable,\r
+ so the actual executable path is passed in an environment variable.\r
+ See Lib/plat-mac/bundlebuiler.py for details about the bootstrap\r
+ script. */\r
+ if ((p = Py_GETENV("PYTHONEXECUTABLE")) && *p != '\0')\r
+ Py_SetProgramName(p);\r
+ else\r
+ Py_SetProgramName(argv[0]);\r
+#else\r
+ Py_SetProgramName(argv[0]);\r
+#endif\r
+ Py_Initialize();\r
+\r
+ if (Py_VerboseFlag ||\r
+ (command == NULL && filename == NULL && module == NULL && stdin_is_interactive)) {\r
+ fprintf(stderr, "Python %s on %s\n",\r
+ Py_GetVersion(), Py_GetPlatform());\r
+ if (!Py_NoSiteFlag)\r
+ fprintf(stderr, "%s\n", COPYRIGHT);\r
+ }\r
+\r
+ if (command != NULL) {\r
+ /* Backup _PyOS_optind and force sys.argv[0] = '-c' */\r
+ _PyOS_optind--;\r
+ argv[_PyOS_optind] = "-c";\r
+ }\r
+\r
+ if (module != NULL) {\r
+ /* Backup _PyOS_optind and force sys.argv[0] = '-c'\r
+ so that PySys_SetArgv correctly sets sys.path[0] to ''\r
+ rather than looking for a file called "-m". See\r
+ tracker issue #8202 for details. */\r
+ _PyOS_optind--;\r
+ argv[_PyOS_optind] = "-c";\r
+ }\r
+\r
+ PySys_SetArgv(argc-_PyOS_optind, argv+_PyOS_optind);\r
+\r
+ if ((Py_InspectFlag || (command == NULL && filename == NULL && module == NULL)) &&\r
+ isatty(fileno(stdin))) {\r
+ PyObject *v;\r
+ v = PyImport_ImportModule("readline");\r
+ if (v == NULL)\r
+ PyErr_Clear();\r
+ else\r
+ Py_DECREF(v);\r
+ }\r
+\r
+ if (command) {\r
+ sts = PyRun_SimpleStringFlags(command, &cf) != 0;\r
+ free(command);\r
+ } else if (module) {\r
+ sts = (RunModule(module, 1) != 0);\r
+ free(module);\r
+ }\r
+ else {\r
+\r
+ if (filename == NULL && stdin_is_interactive) {\r
+ Py_InspectFlag = 0; /* do exit on SystemExit */\r
+ RunStartupFile(&cf);\r
+ }\r
+ /* XXX */\r
+\r
+ sts = -1; /* keep track of whether we've already run __main__ */\r
+\r
+ if (filename != NULL) {\r
+ sts = RunMainFromImporter(filename);\r
+ }\r
+\r
+ if (sts==-1 && filename!=NULL) {\r
+ if ((fp = fopen(filename, "r")) == NULL) {\r
+ fprintf(stderr, "%s: can't open file '%s': [Errno %d] %s\n",\r
+ argv[0], filename, errno, strerror(errno));\r
+\r
+ return 2;\r
+ }\r
+ else if (skipfirstline) {\r
+ int ch;\r
+ /* Push back first newline so line numbers\r
+ remain the same */\r
+ while ((ch = getc(fp)) != EOF) {\r
+ if (ch == '\n') {\r
+ (void)ungetc(ch, fp);\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ {\r
+ /* XXX: does this work on Win/Win64? (see posix_fstat) */\r
+ struct stat sb;\r
+ if (fstat(fileno(fp), &sb) == 0 &&\r
+ S_ISDIR(sb.st_mode)) {\r
+ fprintf(stderr, "%s: '%s' is a directory, cannot continue\n", argv[0], filename);\r
+ fclose(fp);\r
+ return 1;\r
+ }\r
+ }\r
+ }\r
+\r
+ if (sts==-1) {\r
+ /* call pending calls like signal handlers (SIGINT) */\r
+ if (Py_MakePendingCalls() == -1) {\r
+ PyErr_Print();\r
+ sts = 1;\r
+ } else {\r
+ sts = PyRun_AnyFileExFlags(\r
+ fp,\r
+ filename == NULL ? "<stdin>" : filename,\r
+ filename != NULL, &cf) != 0;\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+ /* Check this environment variable at the end, to give programs the\r
+ * opportunity to set it from Python.\r
+ */\r
+ if (!Py_InspectFlag &&\r
+ (p = Py_GETENV("PYTHONINSPECT")) && *p != '\0')\r
+ {\r
+ Py_InspectFlag = 1;\r
+ }\r
+\r
+ if (Py_InspectFlag && stdin_is_interactive &&\r
+ (filename != NULL || command != NULL || module != NULL)) {\r
+ Py_InspectFlag = 0;\r
+ /* XXX */\r
+ sts = PyRun_AnyFileFlags(stdin, "<stdin>", &cf) != 0;\r
+ }\r
+\r
+ Py_Finalize();\r
+#ifdef RISCOS\r
+ if (Py_RISCOSWimpFlag)\r
+ fprintf(stderr, "\x0cq\x0c"); /* make frontend quit */\r
+#endif\r
+\r
+#ifdef __INSURE__\r
+ /* Insure++ is a memory analysis tool that aids in discovering\r
+ * memory leaks and other memory problems. On Python exit, the\r
+ * interned string dictionary is flagged as being in use at exit\r
+ * (which it is). Under normal circumstances, this is fine because\r
+ * the memory will be automatically reclaimed by the system. Under\r
+ * memory debugging, it's a huge source of useless noise, so we\r
+ * trade off slower shutdown for less distraction in the memory\r
+ * reports. -baw\r
+ */\r
+ _Py_ReleaseInternedStrings();\r
+#endif /* __INSURE__ */\r
+\r
+ return sts;\r
+}\r
+\r
+/* this is gonna seem *real weird*, but if you put some other code between\r
+ Py_Main() and Py_GetArgcArgv() you will need to adjust the test in the\r
+ while statement in Misc/gdbinit:ppystack */\r
+\r
+/* Make the *original* argc/argv available to other modules.\r
+ This is rare, but it is needed by the secureware extension. */\r
+\r
+void\r
+Py_GetArgcArgv(int *argc, char ***argv)\r
+{\r
+ *argc = orig_argc;\r
+ *argv = orig_argv;\r
+}\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
--- /dev/null
+/* select - Module containing unix select(2) call.\r
+ Under Unix, the file descriptors are small integers.\r
+ Under Win32, select only exists for sockets, and sockets may\r
+ have any value except INVALID_SOCKET.\r
+ Under BeOS, we suffer the same dichotomy as Win32; sockets can be anything\r
+ >= 0.\r
+*/\r
+\r
+#include "Python.h"\r
+#include <structmember.h>\r
+\r
+#ifdef __APPLE__\r
+ /* Perform runtime testing for a broken poll on OSX to make it easier\r
+ * to use the same binary on multiple releases of the OS.\r
+ */\r
+#undef HAVE_BROKEN_POLL\r
+#endif\r
+\r
+/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.\r
+ 64 is too small (too many people have bumped into that limit).\r
+ Here we boost it.\r
+ Users who want even more than the boosted limit should #define\r
+ FD_SETSIZE higher before this; e.g., via compiler /D switch.\r
+*/\r
+#if defined(MS_WINDOWS) && !defined(FD_SETSIZE)\r
+#define FD_SETSIZE 512\r
+#endif\r
+\r
+#if defined(HAVE_POLL_H)\r
+#include <poll.h>\r
+#elif defined(HAVE_SYS_POLL_H)\r
+#include <sys/poll.h>\r
+#endif\r
+\r
+#ifdef __sgi\r
+/* This is missing from unistd.h */\r
+extern void bzero(void *, int);\r
+#endif\r
+\r
+#ifdef HAVE_SYS_TYPES_H\r
+#include <sys/types.h>\r
+#endif\r
+\r
+#if defined(PYOS_OS2) && !defined(PYCC_GCC)\r
+#include <sys/time.h>\r
+#include <utils.h>\r
+#endif\r
+\r
+#ifdef MS_WINDOWS\r
+# include <winsock2.h>\r
+#else\r
+# define SOCKET int\r
+# ifdef __BEOS__\r
+# include <net/socket.h>\r
+# elif defined(__VMS)\r
+# include <socket.h>\r
+# endif\r
+#endif\r
+\r
+static PyObject *SelectError;\r
+\r
+/* list of Python objects and their file descriptor */\r
+typedef struct {\r
+ PyObject *obj; /* owned reference */\r
+ SOCKET fd;\r
+ int sentinel; /* -1 == sentinel */\r
+} pylist;\r
+\r
+static void\r
+reap_obj(pylist fd2obj[FD_SETSIZE + 1])\r
+{\r
+ int i;\r
+ for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) {\r
+ Py_CLEAR(fd2obj[i].obj);\r
+ }\r
+ fd2obj[0].sentinel = -1;\r
+}\r
+\r
+\r
+/* returns -1 and sets the Python exception if an error occurred, otherwise\r
+ returns a number >= 0\r
+*/\r
+static int\r
+seq2set(PyObject *seq, fd_set *set, pylist fd2obj[FD_SETSIZE + 1])\r
+{\r
+ int i;\r
+ int max = -1;\r
+ int index = 0;\r
+ PyObject* fast_seq = NULL;\r
+ PyObject* o = NULL;\r
+\r
+ fd2obj[0].obj = (PyObject*)0; /* set list to zero size */\r
+ FD_ZERO(set);\r
+\r
+ fast_seq = PySequence_Fast(seq, "arguments 1-3 must be sequences");\r
+ if (!fast_seq)\r
+ return -1;\r
+\r
+ for (i = 0; i < PySequence_Fast_GET_SIZE(fast_seq); i++) {\r
+ SOCKET v;\r
+\r
+ /* any intervening fileno() calls could decr this refcnt */\r
+ if (!(o = PySequence_Fast_GET_ITEM(fast_seq, i)))\r
+ return -1;\r
+\r
+ Py_INCREF(o);\r
+ v = PyObject_AsFileDescriptor( o );\r
+ if (v == -1) goto finally;\r
+\r
+#if defined(_MSC_VER)\r
+ max = 0; /* not used for Win32 */\r
+#else /* !_MSC_VER */\r
+ if (!_PyIsSelectable_fd(v)) {\r
+ PyErr_SetString(PyExc_ValueError,\r
+ "filedescriptor out of range in select()");\r
+ goto finally;\r
+ }\r
+ if (v > max)\r
+ max = v;\r
+#endif /* _MSC_VER */\r
+ FD_SET(v, set);\r
+\r
+ /* add object and its file descriptor to the list */\r
+ if (index >= FD_SETSIZE) {\r
+ PyErr_SetString(PyExc_ValueError,\r
+ "too many file descriptors in select()");\r
+ goto finally;\r
+ }\r
+ fd2obj[index].obj = o;\r
+ fd2obj[index].fd = v;\r
+ fd2obj[index].sentinel = 0;\r
+ fd2obj[++index].sentinel = -1;\r
+ }\r
+ Py_DECREF(fast_seq);\r
+ return max+1;\r
+\r
+ finally:\r
+ Py_XDECREF(o);\r
+ Py_DECREF(fast_seq);\r
+ return -1;\r
+}\r
+\r
+/* returns NULL and sets the Python exception if an error occurred */\r
+static PyObject *\r
+set2list(fd_set *set, pylist fd2obj[FD_SETSIZE + 1])\r
+{\r
+ int i, j, count=0;\r
+ PyObject *list, *o;\r
+ SOCKET fd;\r
+\r
+ for (j = 0; fd2obj[j].sentinel >= 0; j++) {\r
+ if (FD_ISSET(fd2obj[j].fd, set))\r
+ count++;\r
+ }\r
+ list = PyList_New(count);\r
+ if (!list)\r
+ return NULL;\r
+\r
+ i = 0;\r
+ for (j = 0; fd2obj[j].sentinel >= 0; j++) {\r
+ fd = fd2obj[j].fd;\r
+ if (FD_ISSET(fd, set)) {\r
+ o = fd2obj[j].obj;\r
+ fd2obj[j].obj = NULL;\r
+ /* transfer ownership */\r
+ if (PyList_SetItem(list, i, o) < 0)\r
+ goto finally;\r
+\r
+ i++;\r
+ }\r
+ }\r
+ return list;\r
+ finally:\r
+ Py_DECREF(list);\r
+ return NULL;\r
+}\r
+\r
+#undef SELECT_USES_HEAP\r
+#if FD_SETSIZE > 1024\r
+#define SELECT_USES_HEAP\r
+#endif /* FD_SETSIZE > 1024 */\r
+\r
+static PyObject *\r
+select_select(PyObject *self, PyObject *args)\r
+{\r
+#ifdef SELECT_USES_HEAP\r
+ pylist *rfd2obj, *wfd2obj, *efd2obj;\r
+#else /* !SELECT_USES_HEAP */\r
+ /* XXX: All this should probably be implemented as follows:\r
+ * - find the highest descriptor we're interested in\r
+ * - add one\r
+ * - that's the size\r
+ * See: Stevens, APitUE, $12.5.1\r
+ */\r
+ pylist rfd2obj[FD_SETSIZE + 1];\r
+ pylist wfd2obj[FD_SETSIZE + 1];\r
+ pylist efd2obj[FD_SETSIZE + 1];\r
+#endif /* SELECT_USES_HEAP */\r
+ PyObject *ifdlist, *ofdlist, *efdlist;\r
+ PyObject *ret = NULL;\r
+ PyObject *tout = Py_None;\r
+ fd_set ifdset, ofdset, efdset;\r
+ double timeout;\r
+ struct timeval tv, *tvp;\r
+ long seconds;\r
+ int imax, omax, emax, max;\r
+ int n;\r
+\r
+ /* convert arguments */\r
+ if (!PyArg_UnpackTuple(args, "select", 3, 4,\r
+ &ifdlist, &ofdlist, &efdlist, &tout))\r
+ return NULL;\r
+\r
+ if (tout == Py_None)\r
+ tvp = (struct timeval *)0;\r
+ else if (!PyNumber_Check(tout)) {\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "timeout must be a float or None");\r
+ return NULL;\r
+ }\r
+ else {\r
+ timeout = PyFloat_AsDouble(tout);\r
+ if (timeout == -1 && PyErr_Occurred())\r
+ return NULL;\r
+ if (timeout > (double)LONG_MAX) {\r
+ PyErr_SetString(PyExc_OverflowError,\r
+ "timeout period too long");\r
+ return NULL;\r
+ }\r
+ seconds = (long)timeout;\r
+ timeout = timeout - (double)seconds;\r
+ tv.tv_sec = seconds;\r
+ tv.tv_usec = (long)(timeout * 1E6);\r
+ tvp = &tv;\r
+ }\r
+\r
+\r
+#ifdef SELECT_USES_HEAP\r
+ /* Allocate memory for the lists */\r
+ rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);\r
+ wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);\r
+ efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1);\r
+ if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) {\r
+ if (rfd2obj) PyMem_DEL(rfd2obj);\r
+ if (wfd2obj) PyMem_DEL(wfd2obj);\r
+ if (efd2obj) PyMem_DEL(efd2obj);\r
+ return PyErr_NoMemory();\r
+ }\r
+#endif /* SELECT_USES_HEAP */\r
+ /* Convert sequences to fd_sets, and get maximum fd number\r
+ * propagates the Python exception set in seq2set()\r
+ */\r
+ rfd2obj[0].sentinel = -1;\r
+ wfd2obj[0].sentinel = -1;\r
+ efd2obj[0].sentinel = -1;\r
+ if ((imax=seq2set(ifdlist, &ifdset, rfd2obj)) < 0)\r
+ goto finally;\r
+ if ((omax=seq2set(ofdlist, &ofdset, wfd2obj)) < 0)\r
+ goto finally;\r
+ if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0)\r
+ goto finally;\r
+ max = imax;\r
+ if (omax > max) max = omax;\r
+ if (emax > max) max = emax;\r
+\r
+ Py_BEGIN_ALLOW_THREADS\r
+ n = select(max, &ifdset, &ofdset, &efdset, tvp);\r
+ Py_END_ALLOW_THREADS\r
+\r
+#ifdef MS_WINDOWS\r
+ if (n == SOCKET_ERROR) {\r
+ PyErr_SetExcFromWindowsErr(SelectError, WSAGetLastError());\r
+ }\r
+#else\r
+ if (n < 0) {\r
+ PyErr_SetFromErrno(SelectError);\r
+ }\r
+#endif\r
+ else {\r
+ /* any of these three calls can raise an exception. it's more\r
+ convenient to test for this after all three calls... but\r
+ is that acceptable?\r
+ */\r
+ ifdlist = set2list(&ifdset, rfd2obj);\r
+ ofdlist = set2list(&ofdset, wfd2obj);\r
+ efdlist = set2list(&efdset, efd2obj);\r
+ if (PyErr_Occurred())\r
+ ret = NULL;\r
+ else\r
+ ret = PyTuple_Pack(3, ifdlist, ofdlist, efdlist);\r
+\r
+ Py_DECREF(ifdlist);\r
+ Py_DECREF(ofdlist);\r
+ Py_DECREF(efdlist);\r
+ }\r
+\r
+ finally:\r
+ reap_obj(rfd2obj);\r
+ reap_obj(wfd2obj);\r
+ reap_obj(efd2obj);\r
+#ifdef SELECT_USES_HEAP\r
+ PyMem_DEL(rfd2obj);\r
+ PyMem_DEL(wfd2obj);\r
+ PyMem_DEL(efd2obj);\r
+#endif /* SELECT_USES_HEAP */\r
+ return ret;\r
+}\r
+\r
+#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)\r
+/*\r
+ * poll() support\r
+ */\r
+\r
+typedef struct {\r
+ PyObject_HEAD\r
+ PyObject *dict;\r
+ int ufd_uptodate;\r
+ int ufd_len;\r
+ struct pollfd *ufds;\r
+ int poll_running;\r
+} pollObject;\r
+\r
+static PyTypeObject poll_Type;\r
+\r
+/* Update the malloc'ed array of pollfds to match the dictionary\r
+ contained within a pollObject. Return 1 on success, 0 on an error.\r
+*/\r
+\r
+static int\r
+update_ufd_array(pollObject *self)\r
+{\r
+ Py_ssize_t i, pos;\r
+ PyObject *key, *value;\r
+ struct pollfd *old_ufds = self->ufds;\r
+\r
+ self->ufd_len = PyDict_Size(self->dict);\r
+ PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);\r
+ if (self->ufds == NULL) {\r
+ self->ufds = old_ufds;\r
+ PyErr_NoMemory();\r
+ return 0;\r
+ }\r
+\r
+ i = pos = 0;\r
+ while (PyDict_Next(self->dict, &pos, &key, &value)) {\r
+ assert(i < self->ufd_len);\r
+ /* Never overflow */\r
+ self->ufds[i].fd = (int)PyInt_AsLong(key);\r
+ self->ufds[i].events = (short)(unsigned short)PyInt_AsLong(value);\r
+ i++;\r
+ }\r
+ assert(i == self->ufd_len);\r
+ self->ufd_uptodate = 1;\r
+ return 1;\r
+}\r
+\r
+static int\r
+ushort_converter(PyObject *obj, void *ptr)\r
+{\r
+ unsigned long uval;\r
+\r
+ uval = PyLong_AsUnsignedLong(obj);\r
+ if (uval == (unsigned long)-1 && PyErr_Occurred())\r
+ return 0;\r
+ if (uval > USHRT_MAX) {\r
+ PyErr_SetString(PyExc_OverflowError,\r
+ "Python int too large for C unsigned short");\r
+ return 0;\r
+ }\r
+\r
+ *(unsigned short *)ptr = Py_SAFE_DOWNCAST(uval, unsigned long, unsigned short);\r
+ return 1;\r
+}\r
+\r
+PyDoc_STRVAR(poll_register_doc,\r
+"register(fd [, eventmask] ) -> None\n\n\\r
+Register a file descriptor with the polling object.\n\\r
+fd -- either an integer, or an object with a fileno() method returning an\n\\r
+ int.\n\\r
+events -- an optional bitmask describing the type of events to check for");\r
+\r
+static PyObject *\r
+poll_register(pollObject *self, PyObject *args)\r
+{\r
+ PyObject *o, *key, *value;\r
+ int fd;\r
+ unsigned short events = POLLIN | POLLPRI | POLLOUT;\r
+ int err;\r
+\r
+ if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events))\r
+ return NULL;\r
+\r
+ fd = PyObject_AsFileDescriptor(o);\r
+ if (fd == -1) return NULL;\r
+\r
+ /* Add entry to the internal dictionary: the key is the\r
+ file descriptor, and the value is the event mask. */\r
+ key = PyInt_FromLong(fd);\r
+ if (key == NULL)\r
+ return NULL;\r
+ value = PyInt_FromLong(events);\r
+ if (value == NULL) {\r
+ Py_DECREF(key);\r
+ return NULL;\r
+ }\r
+ err = PyDict_SetItem(self->dict, key, value);\r
+ Py_DECREF(key);\r
+ Py_DECREF(value);\r
+ if (err < 0)\r
+ return NULL;\r
+\r
+ self->ufd_uptodate = 0;\r
+\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+\r
+PyDoc_STRVAR(poll_modify_doc,\r
+"modify(fd, eventmask) -> None\n\n\\r
+Modify an already registered file descriptor.\n\\r
+fd -- either an integer, or an object with a fileno() method returning an\n\\r
+ int.\n\\r
+events -- an optional bitmask describing the type of events to check for");\r
+\r
+static PyObject *\r
+poll_modify(pollObject *self, PyObject *args)\r
+{\r
+ PyObject *o, *key, *value;\r
+ int fd;\r
+ unsigned short events;\r
+ int err;\r
+\r
+ if (!PyArg_ParseTuple(args, "OO&:modify", &o, ushort_converter, &events))\r
+ return NULL;\r
+\r
+ fd = PyObject_AsFileDescriptor(o);\r
+ if (fd == -1) return NULL;\r
+\r
+ /* Modify registered fd */\r
+ key = PyInt_FromLong(fd);\r
+ if (key == NULL)\r
+ return NULL;\r
+ if (PyDict_GetItem(self->dict, key) == NULL) {\r
+ errno = ENOENT;\r
+ PyErr_SetFromErrno(PyExc_IOError);\r
+ return NULL;\r
+ }\r
+ value = PyInt_FromLong(events);\r
+ if (value == NULL) {\r
+ Py_DECREF(key);\r
+ return NULL;\r
+ }\r
+ err = PyDict_SetItem(self->dict, key, value);\r
+ Py_DECREF(key);\r
+ Py_DECREF(value);\r
+ if (err < 0)\r
+ return NULL;\r
+\r
+ self->ufd_uptodate = 0;\r
+\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+\r
+\r
+PyDoc_STRVAR(poll_unregister_doc,\r
+"unregister(fd) -> None\n\n\\r
+Remove a file descriptor being tracked by the polling object.");\r
+\r
+static PyObject *\r
+poll_unregister(pollObject *self, PyObject *o)\r
+{\r
+ PyObject *key;\r
+ int fd;\r
+\r
+ fd = PyObject_AsFileDescriptor( o );\r
+ if (fd == -1)\r
+ return NULL;\r
+\r
+ /* Check whether the fd is already in the array */\r
+ key = PyInt_FromLong(fd);\r
+ if (key == NULL)\r
+ return NULL;\r
+\r
+ if (PyDict_DelItem(self->dict, key) == -1) {\r
+ Py_DECREF(key);\r
+ /* This will simply raise the KeyError set by PyDict_DelItem\r
+ if the file descriptor isn't registered. */\r
+ return NULL;\r
+ }\r
+\r
+ Py_DECREF(key);\r
+ self->ufd_uptodate = 0;\r
+\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+\r
+PyDoc_STRVAR(poll_poll_doc,\r
+"poll( [timeout] ) -> list of (fd, event) 2-tuples\n\n\\r
+Polls the set of registered file descriptors, returning a list containing \n\\r
+any descriptors that have events or errors to report.");\r
+\r
+static PyObject *\r
+poll_poll(pollObject *self, PyObject *args)\r
+{\r
+ PyObject *result_list = NULL, *tout = NULL;\r
+ int timeout = 0, poll_result, i, j;\r
+ PyObject *value = NULL, *num = NULL;\r
+\r
+ if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {\r
+ return NULL;\r
+ }\r
+\r
+ /* Check values for timeout */\r
+ if (tout == NULL || tout == Py_None)\r
+ timeout = -1;\r
+ else if (!PyNumber_Check(tout)) {\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "timeout must be an integer or None");\r
+ return NULL;\r
+ }\r
+ else {\r
+ tout = PyNumber_Int(tout);\r
+ if (!tout)\r
+ return NULL;\r
+ timeout = _PyInt_AsInt(tout);\r
+ Py_DECREF(tout);\r
+ if (timeout == -1 && PyErr_Occurred())\r
+ return NULL;\r
+ }\r
+\r
+ /* Avoid concurrent poll() invocation, issue 8865 */\r
+ if (self->poll_running) {\r
+ PyErr_SetString(PyExc_RuntimeError,\r
+ "concurrent poll() invocation");\r
+ return NULL;\r
+ }\r
+\r
+ /* Ensure the ufd array is up to date */\r
+ if (!self->ufd_uptodate)\r
+ if (update_ufd_array(self) == 0)\r
+ return NULL;\r
+\r
+ self->poll_running = 1;\r
+\r
+ /* call poll() */\r
+ Py_BEGIN_ALLOW_THREADS\r
+ poll_result = poll(self->ufds, self->ufd_len, timeout);\r
+ Py_END_ALLOW_THREADS\r
+\r
+ self->poll_running = 0;\r
+\r
+ if (poll_result < 0) {\r
+ PyErr_SetFromErrno(SelectError);\r
+ return NULL;\r
+ }\r
+\r
+ /* build the result list */\r
+\r
+ result_list = PyList_New(poll_result);\r
+ if (!result_list)\r
+ return NULL;\r
+ else {\r
+ for (i = 0, j = 0; j < poll_result; j++) {\r
+ /* skip to the next fired descriptor */\r
+ while (!self->ufds[i].revents) {\r
+ i++;\r
+ }\r
+ /* if we hit a NULL return, set value to NULL\r
+ and break out of loop; code at end will\r
+ clean up result_list */\r
+ value = PyTuple_New(2);\r
+ if (value == NULL)\r
+ goto error;\r
+ num = PyInt_FromLong(self->ufds[i].fd);\r
+ if (num == NULL) {\r
+ Py_DECREF(value);\r
+ goto error;\r
+ }\r
+ PyTuple_SET_ITEM(value, 0, num);\r
+\r
+ /* The &0xffff is a workaround for AIX. 'revents'\r
+ is a 16-bit short, and IBM assigned POLLNVAL\r
+ to be 0x8000, so the conversion to int results\r
+ in a negative number. See SF bug #923315. */\r
+ num = PyInt_FromLong(self->ufds[i].revents & 0xffff);\r
+ if (num == NULL) {\r
+ Py_DECREF(value);\r
+ goto error;\r
+ }\r
+ PyTuple_SET_ITEM(value, 1, num);\r
+ if ((PyList_SetItem(result_list, j, value)) == -1) {\r
+ Py_DECREF(value);\r
+ goto error;\r
+ }\r
+ i++;\r
+ }\r
+ }\r
+ return result_list;\r
+\r
+ error:\r
+ Py_DECREF(result_list);\r
+ return NULL;\r
+}\r
+\r
+static PyMethodDef poll_methods[] = {\r
+ {"register", (PyCFunction)poll_register,\r
+ METH_VARARGS, poll_register_doc},\r
+ {"modify", (PyCFunction)poll_modify,\r
+ METH_VARARGS, poll_modify_doc},\r
+ {"unregister", (PyCFunction)poll_unregister,\r
+ METH_O, poll_unregister_doc},\r
+ {"poll", (PyCFunction)poll_poll,\r
+ METH_VARARGS, poll_poll_doc},\r
+ {NULL, NULL} /* sentinel */\r
+};\r
+\r
+static pollObject *\r
+newPollObject(void)\r
+{\r
+ pollObject *self;\r
+ self = PyObject_New(pollObject, &poll_Type);\r
+ if (self == NULL)\r
+ return NULL;\r
+ /* ufd_uptodate is a Boolean, denoting whether the\r
+ array pointed to by ufds matches the contents of the dictionary. */\r
+ self->ufd_uptodate = 0;\r
+ self->ufds = NULL;\r
+ self->poll_running = 0;\r
+ self->dict = PyDict_New();\r
+ if (self->dict == NULL) {\r
+ Py_DECREF(self);\r
+ return NULL;\r
+ }\r
+ return self;\r
+}\r
+\r
+static void\r
+poll_dealloc(pollObject *self)\r
+{\r
+ if (self->ufds != NULL)\r
+ PyMem_DEL(self->ufds);\r
+ Py_XDECREF(self->dict);\r
+ PyObject_Del(self);\r
+}\r
+\r
+static PyObject *\r
+poll_getattr(pollObject *self, char *name)\r
+{\r
+ return Py_FindMethod(poll_methods, (PyObject *)self, name);\r
+}\r
+\r
+static PyTypeObject poll_Type = {\r
+ /* The ob_type field must be initialized in the module init function\r
+ * to be portable to Windows without using C++. */\r
+ PyVarObject_HEAD_INIT(NULL, 0)\r
+ "select.poll", /*tp_name*/\r
+ sizeof(pollObject), /*tp_basicsize*/\r
+ 0, /*tp_itemsize*/\r
+ /* methods */\r
+ (destructor)poll_dealloc, /*tp_dealloc*/\r
+ 0, /*tp_print*/\r
+ (getattrfunc)poll_getattr, /*tp_getattr*/\r
+ 0, /*tp_setattr*/\r
+ 0, /*tp_compare*/\r
+ 0, /*tp_repr*/\r
+ 0, /*tp_as_number*/\r
+ 0, /*tp_as_sequence*/\r
+ 0, /*tp_as_mapping*/\r
+ 0, /*tp_hash*/\r
+};\r
+\r
+PyDoc_STRVAR(poll_doc,\r
+"Returns a polling object, which supports registering and\n\\r
+unregistering file descriptors, and then polling them for I/O events.");\r
+\r
+static PyObject *\r
+select_poll(PyObject *self, PyObject *unused)\r
+{\r
+ return (PyObject *)newPollObject();\r
+}\r
+\r
+#ifdef __APPLE__\r
+/*\r
+ * On some systems poll() sets errno on invalid file descriptors. We test\r
+ * for this at runtime because this bug may be fixed or introduced between\r
+ * OS releases.\r
+ */\r
+static int select_have_broken_poll(void)\r
+{\r
+ int poll_test;\r
+ int filedes[2];\r
+\r
+ struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };\r
+\r
+ /* Create a file descriptor to make invalid */\r
+ if (pipe(filedes) < 0) {\r
+ return 1;\r
+ }\r
+ poll_struct.fd = filedes[0];\r
+ close(filedes[0]);\r
+ close(filedes[1]);\r
+ poll_test = poll(&poll_struct, 1, 0);\r
+ if (poll_test < 0) {\r
+ return 1;\r
+ } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {\r
+ return 1;\r
+ }\r
+ return 0;\r
+}\r
+#endif /* __APPLE__ */\r
+\r
+#endif /* HAVE_POLL */\r
+\r
+#ifdef HAVE_EPOLL\r
+/* **************************************************************************\r
+ * epoll interface for Linux 2.6\r
+ *\r
+ * Written by Christian Heimes\r
+ * Inspired by Twisted's _epoll.pyx and select.poll()\r
+ */\r
+\r
+#ifdef HAVE_SYS_EPOLL_H\r
+#include <sys/epoll.h>\r
+#endif\r
+\r
+typedef struct {\r
+ PyObject_HEAD\r
+ SOCKET epfd; /* epoll control file descriptor */\r
+} pyEpoll_Object;\r
+\r
+static PyTypeObject pyEpoll_Type;\r
+#define pyepoll_CHECK(op) (PyObject_TypeCheck((op), &pyEpoll_Type))\r
+\r
+static PyObject *\r
+pyepoll_err_closed(void)\r
+{\r
+ PyErr_SetString(PyExc_ValueError, "I/O operation on closed epoll fd");\r
+ return NULL;\r
+}\r
+\r
+static int\r
+pyepoll_internal_close(pyEpoll_Object *self)\r
+{\r
+ int save_errno = 0;\r
+ if (self->epfd >= 0) {\r
+ int epfd = self->epfd;\r
+ self->epfd = -1;\r
+ Py_BEGIN_ALLOW_THREADS\r
+ if (close(epfd) < 0)\r
+ save_errno = errno;\r
+ Py_END_ALLOW_THREADS\r
+ }\r
+ return save_errno;\r
+}\r
+\r
+static PyObject *\r
+newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd)\r
+{\r
+ pyEpoll_Object *self;\r
+\r
+ if (sizehint == -1) {\r
+ sizehint = FD_SETSIZE-1;\r
+ }\r
+ else if (sizehint < 1) {\r
+ PyErr_Format(PyExc_ValueError,\r
+ "sizehint must be greater zero, got %d",\r
+ sizehint);\r
+ return NULL;\r
+ }\r
+\r
+ assert(type != NULL && type->tp_alloc != NULL);\r
+ self = (pyEpoll_Object *) type->tp_alloc(type, 0);\r
+ if (self == NULL)\r
+ return NULL;\r
+\r
+ if (fd == -1) {\r
+ Py_BEGIN_ALLOW_THREADS\r
+ self->epfd = epoll_create(sizehint);\r
+ Py_END_ALLOW_THREADS\r
+ }\r
+ else {\r
+ self->epfd = fd;\r
+ }\r
+ if (self->epfd < 0) {\r
+ Py_DECREF(self);\r
+ PyErr_SetFromErrno(PyExc_IOError);\r
+ return NULL;\r
+ }\r
+ return (PyObject *)self;\r
+}\r
+\r
+\r
+static PyObject *\r
+pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
+{\r
+ int sizehint = -1;\r
+ static char *kwlist[] = {"sizehint", NULL};\r
+\r
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:epoll", kwlist,\r
+ &sizehint))\r
+ return NULL;\r
+\r
+ return newPyEpoll_Object(type, sizehint, -1);\r
+}\r
+\r
+\r
+static void\r
+pyepoll_dealloc(pyEpoll_Object *self)\r
+{\r
+ (void)pyepoll_internal_close(self);\r
+ Py_TYPE(self)->tp_free(self);\r
+}\r
+\r
+static PyObject*\r
+pyepoll_close(pyEpoll_Object *self)\r
+{\r
+ errno = pyepoll_internal_close(self);\r
+ if (errno < 0) {\r
+ PyErr_SetFromErrno(PyExc_IOError);\r
+ return NULL;\r
+ }\r
+ Py_RETURN_NONE;\r
+}\r
+\r
+PyDoc_STRVAR(pyepoll_close_doc,\r
+"close() -> None\n\\r
+\n\\r
+Close the epoll control file descriptor. Further operations on the epoll\n\\r
+object will raise an exception.");\r
+\r
+static PyObject*\r
+pyepoll_get_closed(pyEpoll_Object *self)\r
+{\r
+ if (self->epfd < 0)\r
+ Py_RETURN_TRUE;\r
+ else\r
+ Py_RETURN_FALSE;\r
+}\r
+\r
+static PyObject*\r
+pyepoll_fileno(pyEpoll_Object *self)\r
+{\r
+ if (self->epfd < 0)\r
+ return pyepoll_err_closed();\r
+ return PyInt_FromLong(self->epfd);\r
+}\r
+\r
+PyDoc_STRVAR(pyepoll_fileno_doc,\r
+"fileno() -> int\n\\r
+\n\\r
+Return the epoll control file descriptor.");\r
+\r
+static PyObject*\r
+pyepoll_fromfd(PyObject *cls, PyObject *args)\r
+{\r
+ SOCKET fd;\r
+\r
+ if (!PyArg_ParseTuple(args, "i:fromfd", &fd))\r
+ return NULL;\r
+\r
+ return newPyEpoll_Object((PyTypeObject*)cls, -1, fd);\r
+}\r
+\r
+PyDoc_STRVAR(pyepoll_fromfd_doc,\r
+"fromfd(fd) -> epoll\n\\r
+\n\\r
+Create an epoll object from a given control fd.");\r
+\r
+static PyObject *\r
+pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events)\r
+{\r
+ struct epoll_event ev;\r
+ int result;\r
+ int fd;\r
+\r
+ if (epfd < 0)\r
+ return pyepoll_err_closed();\r
+\r
+ fd = PyObject_AsFileDescriptor(pfd);\r
+ if (fd == -1) {\r
+ return NULL;\r
+ }\r
+\r
+ switch(op) {\r
+ case EPOLL_CTL_ADD:\r
+ case EPOLL_CTL_MOD:\r
+ ev.events = events;\r
+ ev.data.fd = fd;\r
+ Py_BEGIN_ALLOW_THREADS\r
+ result = epoll_ctl(epfd, op, fd, &ev);\r
+ Py_END_ALLOW_THREADS\r
+ break;\r
+ case EPOLL_CTL_DEL:\r
+ /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL\r
+ * operation required a non-NULL pointer in event, even\r
+ * though this argument is ignored. */\r
+ Py_BEGIN_ALLOW_THREADS\r
+ result = epoll_ctl(epfd, op, fd, &ev);\r
+ if (errno == EBADF) {\r
+ /* fd already closed */\r
+ result = 0;\r
+ errno = 0;\r
+ }\r
+ Py_END_ALLOW_THREADS\r
+ break;\r
+ default:\r
+ result = -1;\r
+ errno = EINVAL;\r
+ }\r
+\r
+ if (result < 0) {\r
+ PyErr_SetFromErrno(PyExc_IOError);\r
+ return NULL;\r
+ }\r
+ Py_RETURN_NONE;\r
+}\r
+\r
+static PyObject *\r
+pyepoll_register(pyEpoll_Object *self, PyObject *args, PyObject *kwds)\r
+{\r
+ PyObject *pfd;\r
+ unsigned int events = EPOLLIN | EPOLLOUT | EPOLLPRI;\r
+ static char *kwlist[] = {"fd", "eventmask", NULL};\r
+\r
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|I:register", kwlist,\r
+ &pfd, &events)) {\r
+ return NULL;\r
+ }\r
+\r
+ return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_ADD, pfd, events);\r
+}\r
+\r
+PyDoc_STRVAR(pyepoll_register_doc,\r
+"register(fd[, eventmask]) -> None\n\\r
+\n\\r
+Registers a new fd or raises an IOError if the fd is already registered.\n\\r
+fd is the target file descriptor of the operation.\n\\r
+events is a bit set composed of the various EPOLL constants; the default\n\\r
+is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\\r
+\n\\r
+The epoll interface supports all file descriptors that support poll.");\r
+\r
+static PyObject *\r
+pyepoll_modify(pyEpoll_Object *self, PyObject *args, PyObject *kwds)\r
+{\r
+ PyObject *pfd;\r
+ unsigned int events;\r
+ static char *kwlist[] = {"fd", "eventmask", NULL};\r
+\r
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "OI:modify", kwlist,\r
+ &pfd, &events)) {\r
+ return NULL;\r
+ }\r
+\r
+ return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_MOD, pfd, events);\r
+}\r
+\r
+PyDoc_STRVAR(pyepoll_modify_doc,\r
+"modify(fd, eventmask) -> None\n\\r
+\n\\r
+fd is the target file descriptor of the operation\n\\r
+events is a bit set composed of the various EPOLL constants");\r
+\r
+static PyObject *\r
+pyepoll_unregister(pyEpoll_Object *self, PyObject *args, PyObject *kwds)\r
+{\r
+ PyObject *pfd;\r
+ static char *kwlist[] = {"fd", NULL};\r
+\r
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:unregister", kwlist,\r
+ &pfd)) {\r
+ return NULL;\r
+ }\r
+\r
+ return pyepoll_internal_ctl(self->epfd, EPOLL_CTL_DEL, pfd, 0);\r
+}\r
+\r
+PyDoc_STRVAR(pyepoll_unregister_doc,\r
+"unregister(fd) -> None\n\\r
+\n\\r
+fd is the target file descriptor of the operation.");\r
+\r
+static PyObject *\r
+pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds)\r
+{\r
+ double dtimeout = -1.;\r
+ int timeout;\r
+ int maxevents = -1;\r
+ int nfds, i;\r
+ PyObject *elist = NULL, *etuple = NULL;\r
+ struct epoll_event *evs = NULL;\r
+ static char *kwlist[] = {"timeout", "maxevents", NULL};\r
+\r
+ if (self->epfd < 0)\r
+ return pyepoll_err_closed();\r
+\r
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist,\r
+ &dtimeout, &maxevents)) {\r
+ return NULL;\r
+ }\r
+\r
+ if (dtimeout < 0) {\r
+ timeout = -1;\r
+ }\r
+ else if (dtimeout * 1000.0 > INT_MAX) {\r
+ PyErr_SetString(PyExc_OverflowError,\r
+ "timeout is too large");\r
+ return NULL;\r
+ }\r
+ else {\r
+ timeout = (int)(dtimeout * 1000.0);\r
+ }\r
+\r
+ if (maxevents == -1) {\r
+ maxevents = FD_SETSIZE-1;\r
+ }\r
+ else if (maxevents < 1) {\r
+ PyErr_Format(PyExc_ValueError,\r
+ "maxevents must be greater than 0, got %d",\r
+ maxevents);\r
+ return NULL;\r
+ }\r
+\r
+ evs = PyMem_New(struct epoll_event, maxevents);\r
+ if (evs == NULL) {\r
+ Py_DECREF(self);\r
+ PyErr_NoMemory();\r
+ return NULL;\r
+ }\r
+\r
+ Py_BEGIN_ALLOW_THREADS\r
+ nfds = epoll_wait(self->epfd, evs, maxevents, timeout);\r
+ Py_END_ALLOW_THREADS\r
+ if (nfds < 0) {\r
+ PyErr_SetFromErrno(PyExc_IOError);\r
+ goto error;\r
+ }\r
+\r
+ elist = PyList_New(nfds);\r
+ if (elist == NULL) {\r
+ goto error;\r
+ }\r
+\r
+ for (i = 0; i < nfds; i++) {\r
+ etuple = Py_BuildValue("iI", evs[i].data.fd, evs[i].events);\r
+ if (etuple == NULL) {\r
+ Py_CLEAR(elist);\r
+ goto error;\r
+ }\r
+ PyList_SET_ITEM(elist, i, etuple);\r
+ }\r
+\r
+ error:\r
+ PyMem_Free(evs);\r
+ return elist;\r
+}\r
+\r
+PyDoc_STRVAR(pyepoll_poll_doc,\r
+"poll([timeout=-1[, maxevents=-1]]) -> [(fd, events), (...)]\n\\r
+\n\\r
+Wait for events on the epoll file descriptor for a maximum time of timeout\n\\r
+in seconds (as float). -1 makes poll wait indefinitely.\n\\r
+Up to maxevents are returned to the caller.");\r
+\r
+static PyMethodDef pyepoll_methods[] = {\r
+ {"fromfd", (PyCFunction)pyepoll_fromfd,\r
+ METH_VARARGS | METH_CLASS, pyepoll_fromfd_doc},\r
+ {"close", (PyCFunction)pyepoll_close, METH_NOARGS,\r
+ pyepoll_close_doc},\r
+ {"fileno", (PyCFunction)pyepoll_fileno, METH_NOARGS,\r
+ pyepoll_fileno_doc},\r
+ {"modify", (PyCFunction)pyepoll_modify,\r
+ METH_VARARGS | METH_KEYWORDS, pyepoll_modify_doc},\r
+ {"register", (PyCFunction)pyepoll_register,\r
+ METH_VARARGS | METH_KEYWORDS, pyepoll_register_doc},\r
+ {"unregister", (PyCFunction)pyepoll_unregister,\r
+ METH_VARARGS | METH_KEYWORDS, pyepoll_unregister_doc},\r
+ {"poll", (PyCFunction)pyepoll_poll,\r
+ METH_VARARGS | METH_KEYWORDS, pyepoll_poll_doc},\r
+ {NULL, NULL},\r
+};\r
+\r
+static PyGetSetDef pyepoll_getsetlist[] = {\r
+ {"closed", (getter)pyepoll_get_closed, NULL,\r
+ "True if the epoll handler is closed"},\r
+ {0},\r
+};\r
+\r
+PyDoc_STRVAR(pyepoll_doc,\r
+"select.epoll([sizehint=-1])\n\\r
+\n\\r
+Returns an epolling object\n\\r
+\n\\r
+sizehint must be a positive integer or -1 for the default size. The\n\\r
+sizehint is used to optimize internal data structures. It doesn't limit\n\\r
+the maximum number of monitored events.");\r
+\r
+static PyTypeObject pyEpoll_Type = {\r
+ PyVarObject_HEAD_INIT(NULL, 0)\r
+ "select.epoll", /* tp_name */\r
+ sizeof(pyEpoll_Object), /* tp_basicsize */\r
+ 0, /* tp_itemsize */\r
+ (destructor)pyepoll_dealloc, /* tp_dealloc */\r
+ 0, /* tp_print */\r
+ 0, /* tp_getattr */\r
+ 0, /* tp_setattr */\r
+ 0, /* tp_compare */\r
+ 0, /* tp_repr */\r
+ 0, /* tp_as_number */\r
+ 0, /* tp_as_sequence */\r
+ 0, /* tp_as_mapping */\r
+ 0, /* tp_hash */\r
+ 0, /* tp_call */\r
+ 0, /* tp_str */\r
+ PyObject_GenericGetAttr, /* tp_getattro */\r
+ 0, /* tp_setattro */\r
+ 0, /* tp_as_buffer */\r
+ Py_TPFLAGS_DEFAULT, /* tp_flags */\r
+ pyepoll_doc, /* tp_doc */\r
+ 0, /* tp_traverse */\r
+ 0, /* tp_clear */\r
+ 0, /* tp_richcompare */\r
+ 0, /* tp_weaklistoffset */\r
+ 0, /* tp_iter */\r
+ 0, /* tp_iternext */\r
+ pyepoll_methods, /* tp_methods */\r
+ 0, /* tp_members */\r
+ pyepoll_getsetlist, /* tp_getset */\r
+ 0, /* tp_base */\r
+ 0, /* tp_dict */\r
+ 0, /* tp_descr_get */\r
+ 0, /* tp_descr_set */\r
+ 0, /* tp_dictoffset */\r
+ 0, /* tp_init */\r
+ 0, /* tp_alloc */\r
+ pyepoll_new, /* tp_new */\r
+ 0, /* tp_free */\r
+};\r
+\r
+#endif /* HAVE_EPOLL */\r
+\r
+#ifdef HAVE_KQUEUE\r
+/* **************************************************************************\r
+ * kqueue interface for BSD\r
+ *\r
+ * Copyright (c) 2000 Doug White, 2006 James Knight, 2007 Christian Heimes\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ */\r
+\r
+#ifdef HAVE_SYS_EVENT_H\r
+#include <sys/event.h>\r
+#endif\r
+\r
+PyDoc_STRVAR(kqueue_event_doc,\r
+"kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)\n\\r
+\n\\r
+This object is the equivalent of the struct kevent for the C API.\n\\r
+\n\\r
+See the kqueue manpage for more detailed information about the meaning\n\\r
+of the arguments.\n\\r
+\n\\r
+One minor note: while you might hope that udata could store a\n\\r
+reference to a python object, it cannot, because it is impossible to\n\\r
+keep a proper reference count of the object once it's passed into the\n\\r
+kernel. Therefore, I have restricted it to only storing an integer. I\n\\r
+recommend ignoring it and simply using the 'ident' field to key off\n\\r
+of. You could also set up a dictionary on the python side to store a\n\\r
+udata->object mapping.");\r
+\r
+typedef struct {\r
+ PyObject_HEAD\r
+ struct kevent e;\r
+} kqueue_event_Object;\r
+\r
+static PyTypeObject kqueue_event_Type;\r
+\r
+#define kqueue_event_Check(op) (PyObject_TypeCheck((op), &kqueue_event_Type))\r
+\r
+typedef struct {\r
+ PyObject_HEAD\r
+ SOCKET kqfd; /* kqueue control fd */\r
+} kqueue_queue_Object;\r
+\r
+static PyTypeObject kqueue_queue_Type;\r
+\r
+#define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type))\r
+\r
+#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P)\r
+# error uintptr_t does not match void *!\r
+#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG)\r
+# define T_UINTPTRT T_ULONGLONG\r
+# define T_INTPTRT T_LONGLONG\r
+# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong\r
+# define UINTPTRT_FMT_UNIT "K"\r
+# define INTPTRT_FMT_UNIT "L"\r
+#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG)\r
+# define T_UINTPTRT T_ULONG\r
+# define T_INTPTRT T_LONG\r
+# define PyLong_AsUintptr_t PyLong_AsUnsignedLong\r
+# define UINTPTRT_FMT_UNIT "k"\r
+# define INTPTRT_FMT_UNIT "l"\r
+#elif (SIZEOF_UINTPTR_T == SIZEOF_INT)\r
+# define T_UINTPTRT T_UINT\r
+# define T_INTPTRT T_INT\r
+# define PyLong_AsUintptr_t PyLong_AsUnsignedLong\r
+# define UINTPTRT_FMT_UNIT "I"\r
+# define INTPTRT_FMT_UNIT "i"\r
+#else\r
+# error uintptr_t does not match int, long, or long long!\r
+#endif\r
+\r
+/*\r
+ * kevent is not standard and its members vary across BSDs.\r
+ */\r
+#if !defined(__OpenBSD__)\r
+# define IDENT_TYPE T_UINTPTRT\r
+# define IDENT_CAST Py_intptr_t\r
+# define DATA_TYPE T_INTPTRT\r
+# define DATA_FMT_UNIT INTPTRT_FMT_UNIT\r
+# define IDENT_AsType PyLong_AsUintptr_t\r
+#else\r
+# define IDENT_TYPE T_UINT\r
+# define IDENT_CAST int\r
+# define DATA_TYPE T_INT\r
+# define DATA_FMT_UNIT "i"\r
+# define IDENT_AsType PyLong_AsUnsignedLong\r
+#endif\r
+\r
+/* Unfortunately, we can't store python objects in udata, because\r
+ * kevents in the kernel can be removed without warning, which would\r
+ * forever lose the refcount on the object stored with it.\r
+ */\r
+\r
+#define KQ_OFF(x) offsetof(kqueue_event_Object, x)\r
+static struct PyMemberDef kqueue_event_members[] = {\r
+ {"ident", IDENT_TYPE, KQ_OFF(e.ident)},\r
+ {"filter", T_SHORT, KQ_OFF(e.filter)},\r
+ {"flags", T_USHORT, KQ_OFF(e.flags)},\r
+ {"fflags", T_UINT, KQ_OFF(e.fflags)},\r
+ {"data", DATA_TYPE, KQ_OFF(e.data)},\r
+ {"udata", T_UINTPTRT, KQ_OFF(e.udata)},\r
+ {NULL} /* Sentinel */\r
+};\r
+#undef KQ_OFF\r
+\r
+static PyObject *\r
+\r
+kqueue_event_repr(kqueue_event_Object *s)\r
+{\r
+ char buf[1024];\r
+ PyOS_snprintf(\r
+ buf, sizeof(buf),\r
+ "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x "\r
+ "data=0x%zd udata=%p>",\r
+ (size_t)(s->e.ident), s->e.filter, s->e.flags,\r
+ s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata);\r
+ return PyString_FromString(buf);\r
+}\r
+\r
+static int\r
+kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds)\r
+{\r
+ PyObject *pfd;\r
+ static char *kwlist[] = {"ident", "filter", "flags", "fflags",\r
+ "data", "udata", NULL};\r
+ static char *fmt = "O|hHI" DATA_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent";\r
+\r
+ EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */\r
+\r
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,\r
+ &pfd, &(self->e.filter), &(self->e.flags),\r
+ &(self->e.fflags), &(self->e.data), &(self->e.udata))) {\r
+ return -1;\r
+ }\r
+\r
+ if (PyLong_Check(pfd)\r
+#if IDENT_TYPE == T_UINT\r
+ && PyLong_AsUnsignedLong(pfd) <= UINT_MAX\r
+#endif\r
+ ) {\r
+ self->e.ident = IDENT_AsType(pfd);\r
+ }\r
+ else {\r
+ self->e.ident = PyObject_AsFileDescriptor(pfd);\r
+ }\r
+ if (PyErr_Occurred()) {\r
+ return -1;\r
+ }\r
+ return 0;\r
+}\r
+\r
+static PyObject *\r
+kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o,\r
+ int op)\r
+{\r
+ Py_intptr_t result = 0;\r
+\r
+ if (!kqueue_event_Check(o)) {\r
+ if (op == Py_EQ || op == Py_NE) {\r
+ PyObject *res = op == Py_EQ ? Py_False : Py_True;\r
+ Py_INCREF(res);\r
+ return res;\r
+ }\r
+ PyErr_Format(PyExc_TypeError,\r
+ "can't compare %.200s to %.200s",\r
+ Py_TYPE(s)->tp_name, Py_TYPE(o)->tp_name);\r
+ return NULL;\r
+ }\r
+ if (((result = (IDENT_CAST)(s->e.ident - o->e.ident)) == 0) &&\r
+ ((result = s->e.filter - o->e.filter) == 0) &&\r
+ ((result = s->e.flags - o->e.flags) == 0) &&\r
+ ((result = (int)(s->e.fflags - o->e.fflags)) == 0) &&\r
+ ((result = s->e.data - o->e.data) == 0) &&\r
+ ((result = s->e.udata - o->e.udata) == 0)\r
+ ) {\r
+ result = 0;\r
+ }\r
+\r
+ switch (op) {\r
+ case Py_EQ:\r
+ result = (result == 0);\r
+ break;\r
+ case Py_NE:\r
+ result = (result != 0);\r
+ break;\r
+ case Py_LE:\r
+ result = (result <= 0);\r
+ break;\r
+ case Py_GE:\r
+ result = (result >= 0);\r
+ break;\r
+ case Py_LT:\r
+ result = (result < 0);\r
+ break;\r
+ case Py_GT:\r
+ result = (result > 0);\r
+ break;\r
+ }\r
+ return PyBool_FromLong((long)result);\r
+}\r
+\r
+static PyTypeObject kqueue_event_Type = {\r
+ PyVarObject_HEAD_INIT(NULL, 0)\r
+ "select.kevent", /* tp_name */\r
+ sizeof(kqueue_event_Object), /* tp_basicsize */\r
+ 0, /* tp_itemsize */\r
+ 0, /* tp_dealloc */\r
+ 0, /* tp_print */\r
+ 0, /* tp_getattr */\r
+ 0, /* tp_setattr */\r
+ 0, /* tp_compare */\r
+ (reprfunc)kqueue_event_repr, /* tp_repr */\r
+ 0, /* tp_as_number */\r
+ 0, /* tp_as_sequence */\r
+ 0, /* tp_as_mapping */\r
+ 0, /* tp_hash */\r
+ 0, /* tp_call */\r
+ 0, /* tp_str */\r
+ 0, /* tp_getattro */\r
+ 0, /* tp_setattro */\r
+ 0, /* tp_as_buffer */\r
+ Py_TPFLAGS_DEFAULT, /* tp_flags */\r
+ kqueue_event_doc, /* tp_doc */\r
+ 0, /* tp_traverse */\r
+ 0, /* tp_clear */\r
+ (richcmpfunc)kqueue_event_richcompare, /* tp_richcompare */\r
+ 0, /* tp_weaklistoffset */\r
+ 0, /* tp_iter */\r
+ 0, /* tp_iternext */\r
+ 0, /* tp_methods */\r
+ kqueue_event_members, /* tp_members */\r
+ 0, /* tp_getset */\r
+ 0, /* tp_base */\r
+ 0, /* tp_dict */\r
+ 0, /* tp_descr_get */\r
+ 0, /* tp_descr_set */\r
+ 0, /* tp_dictoffset */\r
+ (initproc)kqueue_event_init, /* tp_init */\r
+ 0, /* tp_alloc */\r
+ 0, /* tp_new */\r
+ 0, /* tp_free */\r
+};\r
+\r
+static PyObject *\r
+kqueue_queue_err_closed(void)\r
+{\r
+ PyErr_SetString(PyExc_ValueError, "I/O operation on closed kqueue fd");\r
+ return NULL;\r
+}\r
+\r
+static int\r
+kqueue_queue_internal_close(kqueue_queue_Object *self)\r
+{\r
+ int save_errno = 0;\r
+ if (self->kqfd >= 0) {\r
+ int kqfd = self->kqfd;\r
+ self->kqfd = -1;\r
+ Py_BEGIN_ALLOW_THREADS\r
+ if (close(kqfd) < 0)\r
+ save_errno = errno;\r
+ Py_END_ALLOW_THREADS\r
+ }\r
+ return save_errno;\r
+}\r
+\r
+static PyObject *\r
+newKqueue_Object(PyTypeObject *type, SOCKET fd)\r
+{\r
+ kqueue_queue_Object *self;\r
+ assert(type != NULL && type->tp_alloc != NULL);\r
+ self = (kqueue_queue_Object *) type->tp_alloc(type, 0);\r
+ if (self == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ if (fd == -1) {\r
+ Py_BEGIN_ALLOW_THREADS\r
+ self->kqfd = kqueue();\r
+ Py_END_ALLOW_THREADS\r
+ }\r
+ else {\r
+ self->kqfd = fd;\r
+ }\r
+ if (self->kqfd < 0) {\r
+ Py_DECREF(self);\r
+ PyErr_SetFromErrno(PyExc_IOError);\r
+ return NULL;\r
+ }\r
+ return (PyObject *)self;\r
+}\r
+\r
+static PyObject *\r
+kqueue_queue_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
+{\r
+\r
+ if ((args != NULL && PyObject_Size(args)) ||\r
+ (kwds != NULL && PyObject_Size(kwds))) {\r
+ PyErr_SetString(PyExc_ValueError,\r
+ "select.kqueue doesn't accept arguments");\r
+ return NULL;\r
+ }\r
+\r
+ return newKqueue_Object(type, -1);\r
+}\r
+\r
+static void\r
+kqueue_queue_dealloc(kqueue_queue_Object *self)\r
+{\r
+ kqueue_queue_internal_close(self);\r
+ Py_TYPE(self)->tp_free(self);\r
+}\r
+\r
+static PyObject*\r
+kqueue_queue_close(kqueue_queue_Object *self)\r
+{\r
+ errno = kqueue_queue_internal_close(self);\r
+ if (errno < 0) {\r
+ PyErr_SetFromErrno(PyExc_IOError);\r
+ return NULL;\r
+ }\r
+ Py_RETURN_NONE;\r
+}\r
+\r
+PyDoc_STRVAR(kqueue_queue_close_doc,\r
+"close() -> None\n\\r
+\n\\r
+Close the kqueue control file descriptor. Further operations on the kqueue\n\\r
+object will raise an exception.");\r
+\r
+static PyObject*\r
+kqueue_queue_get_closed(kqueue_queue_Object *self)\r
+{\r
+ if (self->kqfd < 0)\r
+ Py_RETURN_TRUE;\r
+ else\r
+ Py_RETURN_FALSE;\r
+}\r
+\r
+static PyObject*\r
+kqueue_queue_fileno(kqueue_queue_Object *self)\r
+{\r
+ if (self->kqfd < 0)\r
+ return kqueue_queue_err_closed();\r
+ return PyInt_FromLong(self->kqfd);\r
+}\r
+\r
+PyDoc_STRVAR(kqueue_queue_fileno_doc,\r
+"fileno() -> int\n\\r
+\n\\r
+Return the kqueue control file descriptor.");\r
+\r
+static PyObject*\r
+kqueue_queue_fromfd(PyObject *cls, PyObject *args)\r
+{\r
+ SOCKET fd;\r
+\r
+ if (!PyArg_ParseTuple(args, "i:fromfd", &fd))\r
+ return NULL;\r
+\r
+ return newKqueue_Object((PyTypeObject*)cls, fd);\r
+}\r
+\r
+PyDoc_STRVAR(kqueue_queue_fromfd_doc,\r
+"fromfd(fd) -> kqueue\n\\r
+\n\\r
+Create a kqueue object from a given control fd.");\r
+\r
+static PyObject *\r
+kqueue_queue_control(kqueue_queue_Object *self, PyObject *args)\r
+{\r
+ int nevents = 0;\r
+ int gotevents = 0;\r
+ int nchanges = 0;\r
+ int i = 0;\r
+ PyObject *otimeout = NULL;\r
+ PyObject *ch = NULL;\r
+ PyObject *it = NULL, *ei = NULL;\r
+ PyObject *result = NULL;\r
+ struct kevent *evl = NULL;\r
+ struct kevent *chl = NULL;\r
+ struct timespec timeoutspec;\r
+ struct timespec *ptimeoutspec;\r
+\r
+ if (self->kqfd < 0)\r
+ return kqueue_queue_err_closed();\r
+\r
+ if (!PyArg_ParseTuple(args, "Oi|O:control", &ch, &nevents, &otimeout))\r
+ return NULL;\r
+\r
+ if (nevents < 0) {\r
+ PyErr_Format(PyExc_ValueError,\r
+ "Length of eventlist must be 0 or positive, got %d",\r
+ nevents);\r
+ return NULL;\r
+ }\r
+\r
+ if (otimeout == Py_None || otimeout == NULL) {\r
+ ptimeoutspec = NULL;\r
+ }\r
+ else if (PyNumber_Check(otimeout)) {\r
+ double timeout;\r
+ long seconds;\r
+\r
+ timeout = PyFloat_AsDouble(otimeout);\r
+ if (timeout == -1 && PyErr_Occurred())\r
+ return NULL;\r
+ if (timeout > (double)LONG_MAX) {\r
+ PyErr_SetString(PyExc_OverflowError,\r
+ "timeout period too long");\r
+ return NULL;\r
+ }\r
+ if (timeout < 0) {\r
+ PyErr_SetString(PyExc_ValueError,\r
+ "timeout must be positive or None");\r
+ return NULL;\r
+ }\r
+\r
+ seconds = (long)timeout;\r
+ timeout = timeout - (double)seconds;\r
+ timeoutspec.tv_sec = seconds;\r
+ timeoutspec.tv_nsec = (long)(timeout * 1E9);\r
+ ptimeoutspec = &timeoutspec;\r
+ }\r
+ else {\r
+ PyErr_Format(PyExc_TypeError,\r
+ "timeout argument must be an number "\r
+ "or None, got %.200s",\r
+ Py_TYPE(otimeout)->tp_name);\r
+ return NULL;\r
+ }\r
+\r
+ if (ch != NULL && ch != Py_None) {\r
+ it = PyObject_GetIter(ch);\r
+ if (it == NULL) {\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "changelist is not iterable");\r
+ return NULL;\r
+ }\r
+ nchanges = PyObject_Size(ch);\r
+ if (nchanges < 0) {\r
+ goto error;\r
+ }\r
+\r
+ chl = PyMem_New(struct kevent, nchanges);\r
+ if (chl == NULL) {\r
+ PyErr_NoMemory();\r
+ goto error;\r
+ }\r
+ i = 0;\r
+ while ((ei = PyIter_Next(it)) != NULL) {\r
+ if (!kqueue_event_Check(ei)) {\r
+ Py_DECREF(ei);\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "changelist must be an iterable of "\r
+ "select.kevent objects");\r
+ goto error;\r
+ } else {\r
+ chl[i++] = ((kqueue_event_Object *)ei)->e;\r
+ }\r
+ Py_DECREF(ei);\r
+ }\r
+ }\r
+ Py_CLEAR(it);\r
+\r
+ /* event list */\r
+ if (nevents) {\r
+ evl = PyMem_New(struct kevent, nevents);\r
+ if (evl == NULL) {\r
+ PyErr_NoMemory();\r
+ goto error;\r
+ }\r
+ }\r
+\r
+ Py_BEGIN_ALLOW_THREADS\r
+ gotevents = kevent(self->kqfd, chl, nchanges,\r
+ evl, nevents, ptimeoutspec);\r
+ Py_END_ALLOW_THREADS\r
+\r
+ if (gotevents == -1) {\r
+ PyErr_SetFromErrno(PyExc_OSError);\r
+ goto error;\r
+ }\r
+\r
+ result = PyList_New(gotevents);\r
+ if (result == NULL) {\r
+ goto error;\r
+ }\r
+\r
+ for (i = 0; i < gotevents; i++) {\r
+ kqueue_event_Object *ch;\r
+\r
+ ch = PyObject_New(kqueue_event_Object, &kqueue_event_Type);\r
+ if (ch == NULL) {\r
+ goto error;\r
+ }\r
+ ch->e = evl[i];\r
+ PyList_SET_ITEM(result, i, (PyObject *)ch);\r
+ }\r
+ PyMem_Free(chl);\r
+ PyMem_Free(evl);\r
+ return result;\r
+\r
+ error:\r
+ PyMem_Free(chl);\r
+ PyMem_Free(evl);\r
+ Py_XDECREF(result);\r
+ Py_XDECREF(it);\r
+ return NULL;\r
+}\r
+\r
+PyDoc_STRVAR(kqueue_queue_control_doc,\r
+"control(changelist, max_events[, timeout=None]) -> eventlist\n\\r
+\n\\r
+Calls the kernel kevent function.\n\\r
+- changelist must be a list of kevent objects describing the changes\n\\r
+ to be made to the kernel's watch list or None.\n\\r
+- max_events lets you specify the maximum number of events that the\n\\r
+ kernel will return.\n\\r
+- timeout is the maximum time to wait in seconds, or else None,\n\\r
+ to wait forever. timeout accepts floats for smaller timeouts, too.");\r
+\r
+\r
+static PyMethodDef kqueue_queue_methods[] = {\r
+ {"fromfd", (PyCFunction)kqueue_queue_fromfd,\r
+ METH_VARARGS | METH_CLASS, kqueue_queue_fromfd_doc},\r
+ {"close", (PyCFunction)kqueue_queue_close, METH_NOARGS,\r
+ kqueue_queue_close_doc},\r
+ {"fileno", (PyCFunction)kqueue_queue_fileno, METH_NOARGS,\r
+ kqueue_queue_fileno_doc},\r
+ {"control", (PyCFunction)kqueue_queue_control,\r
+ METH_VARARGS , kqueue_queue_control_doc},\r
+ {NULL, NULL},\r
+};\r
+\r
+static PyGetSetDef kqueue_queue_getsetlist[] = {\r
+ {"closed", (getter)kqueue_queue_get_closed, NULL,\r
+ "True if the kqueue handler is closed"},\r
+ {0},\r
+};\r
+\r
+PyDoc_STRVAR(kqueue_queue_doc,\r
+"Kqueue syscall wrapper.\n\\r
+\n\\r
+For example, to start watching a socket for input:\n\\r
+>>> kq = kqueue()\n\\r
+>>> sock = socket()\n\\r
+>>> sock.connect((host, port))\n\\r
+>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_ADD)], 0)\n\\r
+\n\\r
+To wait one second for it to become writeable:\n\\r
+>>> kq.control(None, 1, 1000)\n\\r
+\n\\r
+To stop listening:\n\\r
+>>> kq.control([kevent(sock, KQ_FILTER_WRITE, KQ_EV_DELETE)], 0)");\r
+\r
+static PyTypeObject kqueue_queue_Type = {\r
+ PyVarObject_HEAD_INIT(NULL, 0)\r
+ "select.kqueue", /* tp_name */\r
+ sizeof(kqueue_queue_Object), /* tp_basicsize */\r
+ 0, /* tp_itemsize */\r
+ (destructor)kqueue_queue_dealloc, /* tp_dealloc */\r
+ 0, /* tp_print */\r
+ 0, /* tp_getattr */\r
+ 0, /* tp_setattr */\r
+ 0, /* tp_compare */\r
+ 0, /* tp_repr */\r
+ 0, /* tp_as_number */\r
+ 0, /* tp_as_sequence */\r
+ 0, /* tp_as_mapping */\r
+ 0, /* tp_hash */\r
+ 0, /* tp_call */\r
+ 0, /* tp_str */\r
+ 0, /* tp_getattro */\r
+ 0, /* tp_setattro */\r
+ 0, /* tp_as_buffer */\r
+ Py_TPFLAGS_DEFAULT, /* tp_flags */\r
+ kqueue_queue_doc, /* tp_doc */\r
+ 0, /* tp_traverse */\r
+ 0, /* tp_clear */\r
+ 0, /* tp_richcompare */\r
+ 0, /* tp_weaklistoffset */\r
+ 0, /* tp_iter */\r
+ 0, /* tp_iternext */\r
+ kqueue_queue_methods, /* tp_methods */\r
+ 0, /* tp_members */\r
+ kqueue_queue_getsetlist, /* tp_getset */\r
+ 0, /* tp_base */\r
+ 0, /* tp_dict */\r
+ 0, /* tp_descr_get */\r
+ 0, /* tp_descr_set */\r
+ 0, /* tp_dictoffset */\r
+ 0, /* tp_init */\r
+ 0, /* tp_alloc */\r
+ kqueue_queue_new, /* tp_new */\r
+ 0, /* tp_free */\r
+};\r
+\r
+#endif /* HAVE_KQUEUE */\r
+/* ************************************************************************ */\r
+\r
+PyDoc_STRVAR(select_doc,\r
+"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\\r
+\n\\r
+Wait until one or more file descriptors are ready for some kind of I/O.\n\\r
+The first three arguments are sequences of file descriptors to be waited for:\n\\r
+rlist -- wait until ready for reading\n\\r
+wlist -- wait until ready for writing\n\\r
+xlist -- wait for an ``exceptional condition''\n\\r
+If only one kind of condition is required, pass [] for the other lists.\n\\r
+A file descriptor is either a socket or file object, or a small integer\n\\r
+gotten from a fileno() method call on one of those.\n\\r
+\n\\r
+The optional 4th argument specifies a timeout in seconds; it may be\n\\r
+a floating point number to specify fractions of seconds. If it is absent\n\\r
+or None, the call will never time out.\n\\r
+\n\\r
+The return value is a tuple of three lists corresponding to the first three\n\\r
+arguments; each contains the subset of the corresponding file descriptors\n\\r
+that are ready.\n\\r
+\n\\r
+*** IMPORTANT NOTICE ***\n\\r
+On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\\r
+descriptors can be used.");\r
+\r
+static PyMethodDef select_methods[] = {\r
+ {"select", select_select, METH_VARARGS, select_doc},\r
+#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)\r
+ {"poll", select_poll, METH_NOARGS, poll_doc},\r
+#endif /* HAVE_POLL */\r
+ {0, 0}, /* sentinel */\r
+};\r
+\r
+PyDoc_STRVAR(module_doc,\r
+"This module supports asynchronous I/O on multiple file descriptors.\n\\r
+\n\\r
+*** IMPORTANT NOTICE ***\n\\r
+On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");\r
+\r
+PyMODINIT_FUNC\r
+initselect(void)\r
+{\r
+ PyObject *m;\r
+ m = Py_InitModule3("select", select_methods, module_doc);\r
+ if (m == NULL)\r
+ return;\r
+\r
+ SelectError = PyErr_NewException("select.error", NULL, NULL);\r
+ Py_INCREF(SelectError);\r
+ PyModule_AddObject(m, "error", SelectError);\r
+\r
+#ifdef PIPE_BUF\r
+#ifdef HAVE_BROKEN_PIPE_BUF\r
+#undef PIPE_BUF\r
+#define PIPE_BUF 512\r
+#endif\r
+ PyModule_AddIntConstant(m, "PIPE_BUF", PIPE_BUF);\r
+#endif\r
+\r
+#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)\r
+#ifdef __APPLE__\r
+ if (select_have_broken_poll()) {\r
+ if (PyObject_DelAttrString(m, "poll") == -1) {\r
+ PyErr_Clear();\r
+ }\r
+ } else {\r
+#else\r
+ {\r
+#endif\r
+ Py_TYPE(&poll_Type) = &PyType_Type;\r
+ PyModule_AddIntConstant(m, "POLLIN", POLLIN);\r
+ PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);\r
+ PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);\r
+ PyModule_AddIntConstant(m, "POLLERR", POLLERR);\r
+ PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);\r
+ PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);\r
+\r
+#ifdef POLLRDNORM\r
+ PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);\r
+#endif\r
+#ifdef POLLRDBAND\r
+ PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);\r
+#endif\r
+#ifdef POLLWRNORM\r
+ PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);\r
+#endif\r
+#ifdef POLLWRBAND\r
+ PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);\r
+#endif\r
+#ifdef POLLMSG\r
+ PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);\r
+#endif\r
+ }\r
+#endif /* HAVE_POLL */\r
+\r
+#ifdef HAVE_EPOLL\r
+ Py_TYPE(&pyEpoll_Type) = &PyType_Type;\r
+ if (PyType_Ready(&pyEpoll_Type) < 0)\r
+ return;\r
+\r
+ Py_INCREF(&pyEpoll_Type);\r
+ PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);\r
+\r
+ PyModule_AddIntConstant(m, "EPOLLIN", EPOLLIN);\r
+ PyModule_AddIntConstant(m, "EPOLLOUT", EPOLLOUT);\r
+ PyModule_AddIntConstant(m, "EPOLLPRI", EPOLLPRI);\r
+ PyModule_AddIntConstant(m, "EPOLLERR", EPOLLERR);\r
+ PyModule_AddIntConstant(m, "EPOLLHUP", EPOLLHUP);\r
+ PyModule_AddIntConstant(m, "EPOLLET", EPOLLET);\r
+#ifdef EPOLLONESHOT\r
+ /* Kernel 2.6.2+ */\r
+ PyModule_AddIntConstant(m, "EPOLLONESHOT", EPOLLONESHOT);\r
+#endif\r
+ /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */\r
+ PyModule_AddIntConstant(m, "EPOLLRDNORM", EPOLLRDNORM);\r
+ PyModule_AddIntConstant(m, "EPOLLRDBAND", EPOLLRDBAND);\r
+ PyModule_AddIntConstant(m, "EPOLLWRNORM", EPOLLWRNORM);\r
+ PyModule_AddIntConstant(m, "EPOLLWRBAND", EPOLLWRBAND);\r
+ PyModule_AddIntConstant(m, "EPOLLMSG", EPOLLMSG);\r
+#endif /* HAVE_EPOLL */\r
+\r
+#ifdef HAVE_KQUEUE\r
+ kqueue_event_Type.tp_new = PyType_GenericNew;\r
+ Py_TYPE(&kqueue_event_Type) = &PyType_Type;\r
+ if(PyType_Ready(&kqueue_event_Type) < 0)\r
+ return;\r
+\r
+ Py_INCREF(&kqueue_event_Type);\r
+ PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);\r
+\r
+ Py_TYPE(&kqueue_queue_Type) = &PyType_Type;\r
+ if(PyType_Ready(&kqueue_queue_Type) < 0)\r
+ return;\r
+ Py_INCREF(&kqueue_queue_Type);\r
+ PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);\r
+\r
+ /* event filters */\r
+ PyModule_AddIntConstant(m, "KQ_FILTER_READ", EVFILT_READ);\r
+ PyModule_AddIntConstant(m, "KQ_FILTER_WRITE", EVFILT_WRITE);\r
+ PyModule_AddIntConstant(m, "KQ_FILTER_AIO", EVFILT_AIO);\r
+ PyModule_AddIntConstant(m, "KQ_FILTER_VNODE", EVFILT_VNODE);\r
+ PyModule_AddIntConstant(m, "KQ_FILTER_PROC", EVFILT_PROC);\r
+#ifdef EVFILT_NETDEV\r
+ PyModule_AddIntConstant(m, "KQ_FILTER_NETDEV", EVFILT_NETDEV);\r
+#endif\r
+ PyModule_AddIntConstant(m, "KQ_FILTER_SIGNAL", EVFILT_SIGNAL);\r
+ PyModule_AddIntConstant(m, "KQ_FILTER_TIMER", EVFILT_TIMER);\r
+\r
+ /* event flags */\r
+ PyModule_AddIntConstant(m, "KQ_EV_ADD", EV_ADD);\r
+ PyModule_AddIntConstant(m, "KQ_EV_DELETE", EV_DELETE);\r
+ PyModule_AddIntConstant(m, "KQ_EV_ENABLE", EV_ENABLE);\r
+ PyModule_AddIntConstant(m, "KQ_EV_DISABLE", EV_DISABLE);\r
+ PyModule_AddIntConstant(m, "KQ_EV_ONESHOT", EV_ONESHOT);\r
+ PyModule_AddIntConstant(m, "KQ_EV_CLEAR", EV_CLEAR);\r
+\r
+ PyModule_AddIntConstant(m, "KQ_EV_SYSFLAGS", EV_SYSFLAGS);\r
+ PyModule_AddIntConstant(m, "KQ_EV_FLAG1", EV_FLAG1);\r
+\r
+ PyModule_AddIntConstant(m, "KQ_EV_EOF", EV_EOF);\r
+ PyModule_AddIntConstant(m, "KQ_EV_ERROR", EV_ERROR);\r
+\r
+ /* READ WRITE filter flag */\r
+ PyModule_AddIntConstant(m, "KQ_NOTE_LOWAT", NOTE_LOWAT);\r
+\r
+ /* VNODE filter flags */\r
+ PyModule_AddIntConstant(m, "KQ_NOTE_DELETE", NOTE_DELETE);\r
+ PyModule_AddIntConstant(m, "KQ_NOTE_WRITE", NOTE_WRITE);\r
+ PyModule_AddIntConstant(m, "KQ_NOTE_EXTEND", NOTE_EXTEND);\r
+ PyModule_AddIntConstant(m, "KQ_NOTE_ATTRIB", NOTE_ATTRIB);\r
+ PyModule_AddIntConstant(m, "KQ_NOTE_LINK", NOTE_LINK);\r
+ PyModule_AddIntConstant(m, "KQ_NOTE_RENAME", NOTE_RENAME);\r
+ PyModule_AddIntConstant(m, "KQ_NOTE_REVOKE", NOTE_REVOKE);\r
+\r
+ /* PROC filter flags */\r
+ PyModule_AddIntConstant(m, "KQ_NOTE_EXIT", NOTE_EXIT);\r
+ PyModule_AddIntConstant(m, "KQ_NOTE_FORK", NOTE_FORK);\r
+ PyModule_AddIntConstant(m, "KQ_NOTE_EXEC", NOTE_EXEC);\r
+ PyModule_AddIntConstant(m, "KQ_NOTE_PCTRLMASK", NOTE_PCTRLMASK);\r
+ PyModule_AddIntConstant(m, "KQ_NOTE_PDATAMASK", NOTE_PDATAMASK);\r
+\r
+ PyModule_AddIntConstant(m, "KQ_NOTE_TRACK", NOTE_TRACK);\r
+ PyModule_AddIntConstant(m, "KQ_NOTE_CHILD", NOTE_CHILD);\r
+ PyModule_AddIntConstant(m, "KQ_NOTE_TRACKERR", NOTE_TRACKERR);\r
+\r
+ /* NETDEV filter flags */\r
+#ifdef EVFILT_NETDEV\r
+ PyModule_AddIntConstant(m, "KQ_NOTE_LINKUP", NOTE_LINKUP);\r
+ PyModule_AddIntConstant(m, "KQ_NOTE_LINKDOWN", NOTE_LINKDOWN);\r
+ PyModule_AddIntConstant(m, "KQ_NOTE_LINKINV", NOTE_LINKINV);\r
+#endif\r
+\r
+#endif /* HAVE_KQUEUE */\r
+}\r
--- /dev/null
+/* gzguts.h -- zlib internal header definitions for gz* operations\r
+ * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler\r
+ * For conditions of distribution and use, see copyright notice in zlib.h\r
+ */\r
+\r
+#ifdef _LARGEFILE64_SOURCE\r
+# ifndef _LARGEFILE_SOURCE\r
+# define _LARGEFILE_SOURCE 1\r
+# endif\r
+# ifdef _FILE_OFFSET_BITS\r
+# undef _FILE_OFFSET_BITS\r
+# endif\r
+#endif\r
+\r
+#ifdef HAVE_HIDDEN\r
+# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))\r
+#else\r
+# define ZLIB_INTERNAL\r
+#endif\r
+\r
+#include <stdio.h>\r
+#include "zlib.h"\r
+#ifdef STDC\r
+# include <string.h>\r
+# include <stdlib.h>\r
+# include <limits.h>\r
+#endif\r
+#include <fcntl.h>\r
+\r
+#ifdef _WIN32\r
+# include <stddef.h>\r
+#endif\r
+\r
+#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32)\r
+# include <io.h>\r
+#endif\r
+\r
+#ifdef WINAPI_FAMILY\r
+# define open _open\r
+# define read _read\r
+# define write _write\r
+# define close _close\r
+#endif\r
+\r
+#ifdef NO_DEFLATE /* for compatibility with old definition */\r
+# define NO_GZCOMPRESS\r
+#endif\r
+\r
+#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)\r
+# ifndef HAVE_VSNPRINTF\r
+# define HAVE_VSNPRINTF\r
+# endif\r
+#endif\r
+\r
+#if defined(__CYGWIN__)\r
+# ifndef HAVE_VSNPRINTF\r
+# define HAVE_VSNPRINTF\r
+# endif\r
+#endif\r
+\r
+#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410)\r
+# ifndef HAVE_VSNPRINTF\r
+# define HAVE_VSNPRINTF\r
+# endif\r
+#endif\r
+\r
+#ifndef HAVE_VSNPRINTF\r
+# ifdef MSDOS\r
+/* vsnprintf may exist on some MS-DOS compilers (DJGPP?),\r
+ but for now we just assume it doesn't. */\r
+# define NO_vsnprintf\r
+# endif\r
+# ifdef __TURBOC__\r
+# define NO_vsnprintf\r
+# endif\r
+# ifdef WIN32\r
+/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */\r
+# if !defined(vsnprintf) && !defined(NO_vsnprintf)\r
+# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 )\r
+# define vsnprintf _vsnprintf\r
+# endif\r
+# endif\r
+# endif\r
+# ifdef __SASC\r
+# define NO_vsnprintf\r
+# endif\r
+# ifdef VMS\r
+# define NO_vsnprintf\r
+# endif\r
+# ifdef __OS400__\r
+# define NO_vsnprintf\r
+# endif\r
+# ifdef __MVS__\r
+# define NO_vsnprintf\r
+# endif\r
+#endif\r
+\r
+/* unlike snprintf (which is required in C99, yet still not supported by\r
+ Microsoft more than a decade later!), _snprintf does not guarantee null\r
+ termination of the result -- however this is only used in gzlib.c where\r
+ the result is assured to fit in the space provided */\r
+#ifdef _MSC_VER\r
+# define snprintf _snprintf\r
+#endif\r
+\r
+#ifndef local\r
+# define local static\r
+#endif\r
+/* compile with -Dlocal if your debugger can't find static symbols */\r
+\r
+/* gz* functions always use library allocation functions */\r
+#ifndef STDC\r
+ extern voidp malloc OF((uInt size));\r
+ extern void free OF((voidpf ptr));\r
+#endif\r
+\r
+/* get errno and strerror definition */\r
+#if defined UNDER_CE\r
+# include <windows.h>\r
+# define zstrerror() gz_strwinerror((DWORD)GetLastError())\r
+#else\r
+# ifndef NO_STRERROR\r
+# include <errno.h>\r
+# define zstrerror() strerror(errno)\r
+# else\r
+# define zstrerror() "stdio error (consult errno)"\r
+# endif\r
+#endif\r
+\r
+/* provide prototypes for these when building zlib without LFS */\r
+#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0\r
+ ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));\r
+ ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));\r
+ ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));\r
+ ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));\r
+#endif\r
+\r
+/* default memLevel */\r
+#if MAX_MEM_LEVEL >= 8\r
+# define DEF_MEM_LEVEL 8\r
+#else\r
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL\r
+#endif\r
+\r
+/* default i/o buffer size -- double this for output when reading (this and\r
+ twice this must be able to fit in an unsigned type) */\r
+#define GZBUFSIZE 8192\r
+\r
+/* gzip modes, also provide a little integrity check on the passed structure */\r
+#define GZ_NONE 0\r
+#define GZ_READ 7247\r
+#define GZ_WRITE 31153\r
+#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */\r
+\r
+/* values for gz_state how */\r
+#define LOOK 0 /* look for a gzip header */\r
+#define COPY 1 /* copy input directly */\r
+#define GZIP 2 /* decompress a gzip stream */\r
+\r
+/* internal gzip file state data structure */\r
+typedef struct {\r
+ /* exposed contents for gzgetc() macro */\r
+ struct gzFile_s x; /* "x" for exposed */\r
+ /* x.have: number of bytes available at x.next */\r
+ /* x.next: next output data to deliver or write */\r
+ /* x.pos: current position in uncompressed data */\r
+ /* used for both reading and writing */\r
+ int mode; /* see gzip modes above */\r
+ int fd; /* file descriptor */\r
+ char *path; /* path or fd for error messages */\r
+ unsigned size; /* buffer size, zero if not allocated yet */\r
+ unsigned want; /* requested buffer size, default is GZBUFSIZE */\r
+ unsigned char *in; /* input buffer */\r
+ unsigned char *out; /* output buffer (double-sized when reading) */\r
+ int direct; /* 0 if processing gzip, 1 if transparent */\r
+ /* just for reading */\r
+ int how; /* 0: get header, 1: copy, 2: decompress */\r
+ z_off64_t start; /* where the gzip data started, for rewinding */\r
+ int eof; /* true if end of input file reached */\r
+ int past; /* true if read requested past end */\r
+ /* just for writing */\r
+ int level; /* compression level */\r
+ int strategy; /* compression strategy */\r
+ /* seek request */\r
+ z_off64_t skip; /* amount to skip (already rewound if backwards) */\r
+ int seek; /* true if seek request pending */\r
+ /* error information */\r
+ int err; /* error code */\r
+ char *msg; /* error message */\r
+ /* zlib inflate or deflate stream */\r
+ z_stream strm; /* stream structure in-place (not a pointer) */\r
+} gz_state;\r
+typedef gz_state FAR *gz_statep;\r
+\r
+/* shared functions */\r
+void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *));\r
+#if defined UNDER_CE\r
+char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error));\r
+#endif\r
+\r
+/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t\r
+ value -- needed when comparing unsigned to z_off64_t, which is signed\r
+ (possible z_off64_t types off_t, off64_t, and long are all signed) */\r
+#ifdef INT_MAX\r
+# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX)\r
+#else\r
+unsigned ZLIB_INTERNAL gz_intmax OF((void));\r
+# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())\r
+#endif\r
--- /dev/null
+/* zutil.h -- internal interface and configuration of the compression library\r
+ * Copyright (C) 1995-2013 Jean-loup Gailly.\r
+ * For conditions of distribution and use, see copyright notice in zlib.h\r
+ */\r
+\r
+/* WARNING: this file should *not* be used by applications. It is\r
+ part of the implementation of the compression library and is\r
+ subject to change. Applications should only use zlib.h.\r
+ */\r
+\r
+/* @(#) $Id$ */\r
+\r
+#ifndef ZUTIL_H\r
+#define ZUTIL_H\r
+\r
+#ifdef HAVE_HIDDEN\r
+# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))\r
+#else\r
+# define ZLIB_INTERNAL\r
+#endif\r
+\r
+#include "zlib.h"\r
+\r
+#if defined(STDC) && !defined(Z_SOLO)\r
+# if !(defined(_WIN32_WCE) && defined(_MSC_VER))\r
+# include <stddef.h>\r
+# endif\r
+# include <string.h>\r
+# include <stdlib.h>\r
+#endif\r
+\r
+#ifdef Z_SOLO\r
+ typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */\r
+#endif\r
+\r
+#ifndef local\r
+# define local static\r
+#endif\r
+/* compile with -Dlocal if your debugger can't find static symbols */\r
+\r
+typedef unsigned char uch;\r
+typedef uch FAR uchf;\r
+typedef unsigned short ush;\r
+typedef ush FAR ushf;\r
+typedef unsigned long ulg;\r
+\r
+extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */\r
+/* (size given to avoid silly warnings with Visual C++) */\r
+\r
+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]\r
+\r
+#define ERR_RETURN(strm,err) \\r
+ return (strm->msg = ERR_MSG(err), (err))\r
+/* To be used only when the state is known to be valid */\r
+\r
+ /* common constants */\r
+\r
+#ifndef DEF_WBITS\r
+# define DEF_WBITS MAX_WBITS\r
+#endif\r
+/* default windowBits for decompression. MAX_WBITS is for compression only */\r
+\r
+#if MAX_MEM_LEVEL >= 8\r
+# define DEF_MEM_LEVEL 8\r
+#else\r
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL\r
+#endif\r
+/* default memLevel */\r
+\r
+#define STORED_BLOCK 0\r
+#define STATIC_TREES 1\r
+#define DYN_TREES 2\r
+/* The three kinds of block type */\r
+\r
+#define MIN_MATCH 3\r
+#define MAX_MATCH 258\r
+/* The minimum and maximum match lengths */\r
+\r
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */\r
+\r
+ /* target dependencies */\r
+\r
+#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))\r
+# define OS_CODE 0x00\r
+# ifndef Z_SOLO\r
+# if defined(__TURBOC__) || defined(__BORLANDC__)\r
+# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))\r
+ /* Allow compilation with ANSI keywords only enabled */\r
+ void _Cdecl farfree( void *block );\r
+ void *_Cdecl farmalloc( unsigned long nbytes );\r
+# else\r
+# include <alloc.h>\r
+# endif\r
+# else /* MSC or DJGPP */\r
+# include <malloc.h>\r
+# endif\r
+# endif\r
+#endif\r
+\r
+#ifdef AMIGA\r
+# define OS_CODE 0x01\r
+#endif\r
+\r
+#if defined(VAXC) || defined(VMS)\r
+# define OS_CODE 0x02\r
+# define F_OPEN(name, mode) \\r
+ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")\r
+#endif\r
+\r
+#if defined(ATARI) || defined(atarist)\r
+# define OS_CODE 0x05\r
+#endif\r
+\r
+#ifdef OS2\r
+# define OS_CODE 0x06\r
+# if defined(M_I86) && !defined(Z_SOLO)\r
+# include <malloc.h>\r
+# endif\r
+#endif\r
+\r
+#if defined(MACOS) || defined(TARGET_OS_MAC)\r
+# define OS_CODE 0x07\r
+# ifndef Z_SOLO\r
+# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os\r
+# include <unix.h> /* for fdopen */\r
+# else\r
+# ifndef fdopen\r
+# define fdopen(fd,mode) NULL /* No fdopen() */\r
+# endif\r
+# endif\r
+# endif\r
+#endif\r
+\r
+#ifdef TOPS20\r
+# define OS_CODE 0x0a\r
+#endif\r
+\r
+#ifdef WIN32\r
+# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */\r
+# define OS_CODE 0x0b\r
+# endif\r
+#endif\r
+\r
+#ifdef __50SERIES /* Prime/PRIMOS */\r
+# define OS_CODE 0x0f\r
+#endif\r
+\r
+#if defined(_BEOS_) || defined(RISCOS)\r
+# define fdopen(fd,mode) NULL /* No fdopen() */\r
+#endif\r
+\r
+#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX\r
+# if defined(_WIN32_WCE)\r
+# define fdopen(fd,mode) NULL /* No fdopen() */\r
+# ifndef _PTRDIFF_T_DEFINED\r
+ typedef int ptrdiff_t;\r
+# define _PTRDIFF_T_DEFINED\r
+# endif\r
+# else\r
+# define fdopen(fd,type) _fdopen(fd,type)\r
+# endif\r
+#endif\r
+\r
+#if defined(__BORLANDC__) && !defined(MSDOS)\r
+ #pragma warn -8004\r
+ #pragma warn -8008\r
+ #pragma warn -8066\r
+#endif\r
+\r
+/* provide prototypes for these when building zlib without LFS */\r
+#if !defined(_WIN32) && \\r
+ (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)\r
+ ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));\r
+ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));\r
+#endif\r
+\r
+ /* common defaults */\r
+\r
+#ifndef OS_CODE\r
+# define OS_CODE 0x03 /* assume Unix */\r
+#endif\r
+\r
+#ifndef F_OPEN\r
+# define F_OPEN(name, mode) fopen((name), (mode))\r
+#endif\r
+\r
+ /* functions */\r
+\r
+#if defined(pyr) || defined(Z_SOLO)\r
+# define NO_MEMCPY\r
+#endif\r
+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)\r
+ /* Use our own functions for small and medium model with MSC <= 5.0.\r
+ * You may have to use the same strategy for Borland C (untested).\r
+ * The __SC__ check is for Symantec.\r
+ */\r
+# define NO_MEMCPY\r
+#endif\r
+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)\r
+# define HAVE_MEMCPY\r
+#endif\r
+#ifdef HAVE_MEMCPY\r
+# ifdef SMALL_MEDIUM /* MSDOS small or medium model */\r
+# define zmemcpy _fmemcpy\r
+# define zmemcmp _fmemcmp\r
+# define zmemzero(dest, len) _fmemset(dest, 0, len)\r
+# else\r
+# define zmemcpy memcpy\r
+# define zmemcmp memcmp\r
+# define zmemzero(dest, len) memset(dest, 0, len)\r
+# endif\r
+#else\r
+ void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));\r
+ int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));\r
+ void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len));\r
+#endif\r
+\r
+/* Diagnostic functions */\r
+#ifdef DEBUG\r
+# include <stdio.h>\r
+ extern int ZLIB_INTERNAL z_verbose;\r
+ extern void ZLIB_INTERNAL z_error OF((char *m));\r
+# define Assert(cond,msg) {if(!(cond)) z_error(msg);}\r
+# define Trace(x) {if (z_verbose>=0) fprintf x ;}\r
+# define Tracev(x) {if (z_verbose>0) fprintf x ;}\r
+# define Tracevv(x) {if (z_verbose>1) fprintf x ;}\r
+# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}\r
+# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}\r
+#else\r
+# define Assert(cond,msg)\r
+# define Trace(x)\r
+# define Tracev(x)\r
+# define Tracevv(x)\r
+# define Tracec(c,x)\r
+# define Tracecv(c,x)\r
+#endif\r
+\r
+#ifndef Z_SOLO\r
+ voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,\r
+ unsigned size));\r
+ void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr));\r
+#endif\r
+\r
+#define ZALLOC(strm, items, size) \\r
+ (*((strm)->zalloc))((strm)->opaque, (items), (size))\r
+#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))\r
+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}\r
+\r
+/* Reverse the bytes in a 32-bit value */\r
+#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \\r
+ (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))\r
+\r
+#endif /* ZUTIL_H */\r
--- /dev/null
+/* Long (arbitrary precision) integer object implementation */\r
+\r
+/* XXX The functional organization of this file is terrible */\r
+\r
+#include "Python.h"\r
+#include "longintrepr.h"\r
+#include "structseq.h"\r
+\r
+#include <float.h>\r
+#include <ctype.h>\r
+#include <stddef.h>\r
+\r
+/* For long multiplication, use the O(N**2) school algorithm unless\r
+ * both operands contain more than KARATSUBA_CUTOFF digits (this\r
+ * being an internal Python long digit, in base PyLong_BASE).\r
+ */\r
+#define KARATSUBA_CUTOFF 70\r
+#define KARATSUBA_SQUARE_CUTOFF (2 * KARATSUBA_CUTOFF)\r
+\r
+/* For exponentiation, use the binary left-to-right algorithm\r
+ * unless the exponent contains more than FIVEARY_CUTOFF digits.\r
+ * In that case, do 5 bits at a time. The potential drawback is that\r
+ * a table of 2**5 intermediate results is computed.\r
+ */\r
+#define FIVEARY_CUTOFF 8\r
+\r
+#define ABS(x) ((x) < 0 ? -(x) : (x))\r
+\r
+#undef MIN\r
+#undef MAX\r
+#define MAX(x, y) ((x) < (y) ? (y) : (x))\r
+#define MIN(x, y) ((x) > (y) ? (y) : (x))\r
+\r
+#define SIGCHECK(PyTryBlock) \\r
+ do { \\r
+ if (--_Py_Ticker < 0) { \\r
+ _Py_Ticker = _Py_CheckInterval; \\r
+ if (PyErr_CheckSignals()) PyTryBlock \\r
+ } \\r
+ } while(0)\r
+\r
+/* Normalize (remove leading zeros from) a long int object.\r
+ Doesn't attempt to free the storage--in most cases, due to the nature\r
+ of the algorithms used, this could save at most be one word anyway. */\r
+\r
+static PyLongObject *\r
+long_normalize(register PyLongObject *v)\r
+{\r
+ Py_ssize_t j = ABS(Py_SIZE(v));\r
+ Py_ssize_t i = j;\r
+\r
+ while (i > 0 && v->ob_digit[i-1] == 0)\r
+ --i;\r
+ if (i != j)\r
+ Py_SIZE(v) = (Py_SIZE(v) < 0) ? -(i) : i;\r
+ return v;\r
+}\r
+\r
+/* Allocate a new long int object with size digits.\r
+ Return NULL and set exception if we run out of memory. */\r
+\r
+#define MAX_LONG_DIGITS \\r
+ ((PY_SSIZE_T_MAX - offsetof(PyLongObject, ob_digit))/sizeof(digit))\r
+\r
+PyLongObject *\r
+_PyLong_New(Py_ssize_t size)\r
+{\r
+ if (size > (Py_ssize_t)MAX_LONG_DIGITS) {\r
+ PyErr_SetString(PyExc_OverflowError,\r
+ "too many digits in integer");\r
+ return NULL;\r
+ }\r
+ /* coverity[ampersand_in_size] */\r
+ /* XXX(nnorwitz): PyObject_NEW_VAR / _PyObject_VAR_SIZE need to detect\r
+ overflow */\r
+ return PyObject_NEW_VAR(PyLongObject, &PyLong_Type, size);\r
+}\r
+\r
+PyObject *\r
+_PyLong_Copy(PyLongObject *src)\r
+{\r
+ PyLongObject *result;\r
+ Py_ssize_t i;\r
+\r
+ assert(src != NULL);\r
+ i = src->ob_size;\r
+ if (i < 0)\r
+ i = -(i);\r
+ result = _PyLong_New(i);\r
+ if (result != NULL) {\r
+ result->ob_size = src->ob_size;\r
+ while (--i >= 0)\r
+ result->ob_digit[i] = src->ob_digit[i];\r
+ }\r
+ return (PyObject *)result;\r
+}\r
+\r
+/* Create a new long int object from a C long int */\r
+\r
+PyObject *\r
+PyLong_FromLong(long ival)\r
+{\r
+ PyLongObject *v;\r
+ unsigned long abs_ival;\r
+ unsigned long t; /* unsigned so >> doesn't propagate sign bit */\r
+ int ndigits = 0;\r
+ int negative = 0;\r
+\r
+ if (ival < 0) {\r
+ /* if LONG_MIN == -LONG_MAX-1 (true on most platforms) then\r
+ ANSI C says that the result of -ival is undefined when ival\r
+ == LONG_MIN. Hence the following workaround. */\r
+ abs_ival = (unsigned long)(-1-ival) + 1;\r
+ negative = 1;\r
+ }\r
+ else {\r
+ abs_ival = (unsigned long)ival;\r
+ }\r
+\r
+ /* Count the number of Python digits.\r
+ We used to pick 5 ("big enough for anything"), but that's a\r
+ waste of time and space given that 5*15 = 75 bits are rarely\r
+ needed. */\r
+ t = abs_ival;\r
+ while (t) {\r
+ ++ndigits;\r
+ t >>= PyLong_SHIFT;\r
+ }\r
+ v = _PyLong_New(ndigits);\r
+ if (v != NULL) {\r
+ digit *p = v->ob_digit;\r
+ v->ob_size = negative ? -ndigits : ndigits;\r
+ t = abs_ival;\r
+ while (t) {\r
+ *p++ = (digit)(t & PyLong_MASK);\r
+ t >>= PyLong_SHIFT;\r
+ }\r
+ }\r
+ return (PyObject *)v;\r
+}\r
+\r
+/* Create a new long int object from a C unsigned long int */\r
+\r
+PyObject *\r
+PyLong_FromUnsignedLong(unsigned long ival)\r
+{\r
+ PyLongObject *v;\r
+ unsigned long t;\r
+ int ndigits = 0;\r
+\r
+ /* Count the number of Python digits. */\r
+ t = (unsigned long)ival;\r
+ while (t) {\r
+ ++ndigits;\r
+ t >>= PyLong_SHIFT;\r
+ }\r
+ v = _PyLong_New(ndigits);\r
+ if (v != NULL) {\r
+ digit *p = v->ob_digit;\r
+ Py_SIZE(v) = ndigits;\r
+ while (ival) {\r
+ *p++ = (digit)(ival & PyLong_MASK);\r
+ ival >>= PyLong_SHIFT;\r
+ }\r
+ }\r
+ return (PyObject *)v;\r
+}\r
+\r
+/* Create a new long int object from a C double */\r
+\r
+PyObject *\r
+PyLong_FromDouble(double dval)\r
+{\r
+ PyLongObject *v;\r
+ double frac;\r
+ int i, ndig, expo, neg;\r
+ neg = 0;\r
+ if (Py_IS_INFINITY(dval)) {\r
+ PyErr_SetString(PyExc_OverflowError,\r
+ "cannot convert float infinity to integer");\r
+ return NULL;\r
+ }\r
+ if (Py_IS_NAN(dval)) {\r
+ PyErr_SetString(PyExc_ValueError,\r
+ "cannot convert float NaN to integer");\r
+ return NULL;\r
+ }\r
+ if (dval < 0.0) {\r
+ neg = 1;\r
+ dval = -dval;\r
+ }\r
+ frac = frexp(dval, &expo); /* dval = frac*2**expo; 0.0 <= frac < 1.0 */\r
+ if (expo <= 0)\r
+ return PyLong_FromLong(0L);\r
+ ndig = (expo-1) / PyLong_SHIFT + 1; /* Number of 'digits' in result */\r
+ v = _PyLong_New(ndig);\r
+ if (v == NULL)\r
+ return NULL;\r
+ frac = ldexp(frac, (expo-1) % PyLong_SHIFT + 1);\r
+ for (i = ndig; --i >= 0; ) {\r
+ digit bits = (digit)frac;\r
+ v->ob_digit[i] = bits;\r
+ frac = frac - (double)bits;\r
+ frac = ldexp(frac, PyLong_SHIFT);\r
+ }\r
+ if (neg)\r
+ Py_SIZE(v) = -(Py_SIZE(v));\r
+ return (PyObject *)v;\r
+}\r
+\r
+/* Checking for overflow in PyLong_AsLong is a PITA since C doesn't define\r
+ * anything about what happens when a signed integer operation overflows,\r
+ * and some compilers think they're doing you a favor by being "clever"\r
+ * then. The bit pattern for the largest postive signed long is\r
+ * (unsigned long)LONG_MAX, and for the smallest negative signed long\r
+ * it is abs(LONG_MIN), which we could write -(unsigned long)LONG_MIN.\r
+ * However, some other compilers warn about applying unary minus to an\r
+ * unsigned operand. Hence the weird "0-".\r
+ */\r
+#define PY_ABS_LONG_MIN (0-(unsigned long)LONG_MIN)\r
+#define PY_ABS_SSIZE_T_MIN (0-(size_t)PY_SSIZE_T_MIN)\r
+\r
+/* Get a C long int from a Python long or Python int object.\r
+ On overflow, returns -1 and sets *overflow to 1 or -1 depending\r
+ on the sign of the result. Otherwise *overflow is 0.\r
+\r
+ For other errors (e.g., type error), returns -1 and sets an error\r
+ condition.\r
+*/\r
+\r
+long\r
+PyLong_AsLongAndOverflow(PyObject *vv, int *overflow)\r
+{\r
+ /* This version by Tim Peters */\r
+ register PyLongObject *v;\r
+ unsigned long x, prev;\r
+ long res;\r
+ Py_ssize_t i;\r
+ int sign;\r
+ int do_decref = 0; /* if nb_int was called */\r
+\r
+ *overflow = 0;\r
+ if (vv == NULL) {\r
+ PyErr_BadInternalCall();\r
+ return -1;\r
+ }\r
+\r
+ if(PyInt_Check(vv))\r
+ return PyInt_AsLong(vv);\r
+\r
+ if (!PyLong_Check(vv)) {\r
+ PyNumberMethods *nb;\r
+ nb = vv->ob_type->tp_as_number;\r
+ if (nb == NULL || nb->nb_int == NULL) {\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "an integer is required");\r
+ return -1;\r
+ }\r
+ vv = (*nb->nb_int) (vv);\r
+ if (vv == NULL)\r
+ return -1;\r
+ do_decref = 1;\r
+ if(PyInt_Check(vv)) {\r
+ res = PyInt_AsLong(vv);\r
+ goto exit;\r
+ }\r
+ if (!PyLong_Check(vv)) {\r
+ Py_DECREF(vv);\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "nb_int should return int object");\r
+ return -1;\r
+ }\r
+ }\r
+\r
+ res = -1;\r
+ v = (PyLongObject *)vv;\r
+ i = Py_SIZE(v);\r
+\r
+ switch (i) {\r
+ case -1:\r
+ res = -(sdigit)v->ob_digit[0];\r
+ break;\r
+ case 0:\r
+ res = 0;\r
+ break;\r
+ case 1:\r
+ res = v->ob_digit[0];\r
+ break;\r
+ default:\r
+ sign = 1;\r
+ x = 0;\r
+ if (i < 0) {\r
+ sign = -1;\r
+ i = -(i);\r
+ }\r
+ while (--i >= 0) {\r
+ prev = x;\r
+ x = (x << PyLong_SHIFT) + v->ob_digit[i];\r
+ if ((x >> PyLong_SHIFT) != prev) {\r
+ *overflow = sign;\r
+ goto exit;\r
+ }\r
+ }\r
+ /* Haven't lost any bits, but casting to long requires extra\r
+ * care (see comment above).\r
+ */\r
+ if (x <= (unsigned long)LONG_MAX) {\r
+ res = (long)x * sign;\r
+ }\r
+ else if (sign < 0 && x == PY_ABS_LONG_MIN) {\r
+ res = LONG_MIN;\r
+ }\r
+ else {\r
+ *overflow = sign;\r
+ /* res is already set to -1 */\r
+ }\r
+ }\r
+ exit:\r
+ if (do_decref) {\r
+ Py_DECREF(vv);\r
+ }\r
+ return res;\r
+}\r
+\r
+/* Get a C long int from a long int object.\r
+ Returns -1 and sets an error condition if overflow occurs. */\r
+\r
+long\r
+PyLong_AsLong(PyObject *obj)\r
+{\r
+ int overflow;\r
+ long result = PyLong_AsLongAndOverflow(obj, &overflow);\r
+ if (overflow) {\r
+ /* XXX: could be cute and give a different\r
+ message for overflow == -1 */\r
+ PyErr_SetString(PyExc_OverflowError,\r
+ "Python int too large to convert to C long");\r
+ }\r
+ return result;\r
+}\r
+\r
+/* Get a C int from a long int object or any object that has an __int__\r
+ method. Return -1 and set an error if overflow occurs. */\r
+\r
+int\r
+_PyLong_AsInt(PyObject *obj)\r
+{\r
+ int overflow;\r
+ long result = PyLong_AsLongAndOverflow(obj, &overflow);\r
+ if (overflow || result > INT_MAX || result < INT_MIN) {\r
+ /* XXX: could be cute and give a different\r
+ message for overflow == -1 */\r
+ PyErr_SetString(PyExc_OverflowError,\r
+ "Python int too large to convert to C int");\r
+ return -1;\r
+ }\r
+ return (int)result;\r
+}\r
+\r
+/* Get a Py_ssize_t from a long int object.\r
+ Returns -1 and sets an error condition if overflow occurs. */\r
+\r
+Py_ssize_t\r
+PyLong_AsSsize_t(PyObject *vv) {\r
+ register PyLongObject *v;\r
+ size_t x, prev;\r
+ Py_ssize_t i;\r
+ int sign;\r
+\r
+ if (vv == NULL || !PyLong_Check(vv)) {\r
+ PyErr_BadInternalCall();\r
+ return -1;\r
+ }\r
+ v = (PyLongObject *)vv;\r
+ i = v->ob_size;\r
+ sign = 1;\r
+ x = 0;\r
+ if (i < 0) {\r
+ sign = -1;\r
+ i = -(i);\r
+ }\r
+ while (--i >= 0) {\r
+ prev = x;\r
+ x = (x << PyLong_SHIFT) | v->ob_digit[i];\r
+ if ((x >> PyLong_SHIFT) != prev)\r
+ goto overflow;\r
+ }\r
+ /* Haven't lost any bits, but casting to a signed type requires\r
+ * extra care (see comment above).\r
+ */\r
+ if (x <= (size_t)PY_SSIZE_T_MAX) {\r
+ return (Py_ssize_t)x * sign;\r
+ }\r
+ else if (sign < 0 && x == PY_ABS_SSIZE_T_MIN) {\r
+ return PY_SSIZE_T_MIN;\r
+ }\r
+ /* else overflow */\r
+\r
+ overflow:\r
+ PyErr_SetString(PyExc_OverflowError,\r
+ "long int too large to convert to int");\r
+ return -1;\r
+}\r
+\r
+/* Get a C unsigned long int from a long int object.\r
+ Returns -1 and sets an error condition if overflow occurs. */\r
+\r
+unsigned long\r
+PyLong_AsUnsignedLong(PyObject *vv)\r
+{\r
+ register PyLongObject *v;\r
+ unsigned long x, prev;\r
+ Py_ssize_t i;\r
+\r
+ if (vv == NULL || !PyLong_Check(vv)) {\r
+ if (vv != NULL && PyInt_Check(vv)) {\r
+ long val = PyInt_AsLong(vv);\r
+ if (val < 0) {\r
+ PyErr_SetString(PyExc_OverflowError,\r
+ "can't convert negative value "\r
+ "to unsigned long");\r
+ return (unsigned long) -1;\r
+ }\r
+ return val;\r
+ }\r
+ PyErr_BadInternalCall();\r
+ return (unsigned long) -1;\r
+ }\r
+ v = (PyLongObject *)vv;\r
+ i = Py_SIZE(v);\r
+ x = 0;\r
+ if (i < 0) {\r
+ PyErr_SetString(PyExc_OverflowError,\r
+ "can't convert negative value to unsigned long");\r
+ return (unsigned long) -1;\r
+ }\r
+ while (--i >= 0) {\r
+ prev = x;\r
+ x = (x << PyLong_SHIFT) | v->ob_digit[i];\r
+ if ((x >> PyLong_SHIFT) != prev) {\r
+ PyErr_SetString(PyExc_OverflowError,\r
+ "long int too large to convert");\r
+ return (unsigned long) -1;\r
+ }\r
+ }\r
+ return x;\r
+}\r
+\r
+/* Get a C unsigned long int from a long int object, ignoring the high bits.\r
+ Returns -1 and sets an error condition if an error occurs. */\r
+\r
+unsigned long\r
+PyLong_AsUnsignedLongMask(PyObject *vv)\r
+{\r
+ register PyLongObject *v;\r
+ unsigned long x;\r
+ Py_ssize_t i;\r
+ int sign;\r
+\r
+ if (vv == NULL || !PyLong_Check(vv)) {\r
+ if (vv != NULL && PyInt_Check(vv))\r
+ return PyInt_AsUnsignedLongMask(vv);\r
+ PyErr_BadInternalCall();\r
+ return (unsigned long) -1;\r
+ }\r
+ v = (PyLongObject *)vv;\r
+ i = v->ob_size;\r
+ sign = 1;\r
+ x = 0;\r
+ if (i < 0) {\r
+ sign = -1;\r
+ i = -i;\r
+ }\r
+ while (--i >= 0) {\r
+ x = (x << PyLong_SHIFT) | v->ob_digit[i];\r
+ }\r
+ return x * sign;\r
+}\r
+\r
+int\r
+_PyLong_Sign(PyObject *vv)\r
+{\r
+ PyLongObject *v = (PyLongObject *)vv;\r
+\r
+ assert(v != NULL);\r
+ assert(PyLong_Check(v));\r
+\r
+ return Py_SIZE(v) == 0 ? 0 : (Py_SIZE(v) < 0 ? -1 : 1);\r
+}\r
+\r
+size_t\r
+_PyLong_NumBits(PyObject *vv)\r
+{\r
+ PyLongObject *v = (PyLongObject *)vv;\r
+ size_t result = 0;\r
+ Py_ssize_t ndigits;\r
+\r
+ assert(v != NULL);\r
+ assert(PyLong_Check(v));\r
+ ndigits = ABS(Py_SIZE(v));\r
+ assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0);\r
+ if (ndigits > 0) {\r
+ digit msd = v->ob_digit[ndigits - 1];\r
+\r
+ result = (ndigits - 1) * PyLong_SHIFT;\r
+ if (result / PyLong_SHIFT != (size_t)(ndigits - 1))\r
+ goto Overflow;\r
+ do {\r
+ ++result;\r
+ if (result == 0)\r
+ goto Overflow;\r
+ msd >>= 1;\r
+ } while (msd);\r
+ }\r
+ return result;\r
+\r
+ Overflow:\r
+ PyErr_SetString(PyExc_OverflowError, "long has too many bits "\r
+ "to express in a platform size_t");\r
+ return (size_t)-1;\r
+}\r
+\r
+PyObject *\r
+_PyLong_FromByteArray(const unsigned char* bytes, size_t n,\r
+ int little_endian, int is_signed)\r
+{\r
+ const unsigned char* pstartbyte; /* LSB of bytes */\r
+ int incr; /* direction to move pstartbyte */\r
+ const unsigned char* pendbyte; /* MSB of bytes */\r
+ size_t numsignificantbytes; /* number of bytes that matter */\r
+ Py_ssize_t ndigits; /* number of Python long digits */\r
+ PyLongObject* v; /* result */\r
+ Py_ssize_t idigit = 0; /* next free index in v->ob_digit */\r
+\r
+ if (n == 0)\r
+ return PyLong_FromLong(0L);\r
+\r
+ if (little_endian) {\r
+ pstartbyte = bytes;\r
+ pendbyte = bytes + n - 1;\r
+ incr = 1;\r
+ }\r
+ else {\r
+ pstartbyte = bytes + n - 1;\r
+ pendbyte = bytes;\r
+ incr = -1;\r
+ }\r
+\r
+ if (is_signed)\r
+ is_signed = *pendbyte >= 0x80;\r
+\r
+ /* Compute numsignificantbytes. This consists of finding the most\r
+ significant byte. Leading 0 bytes are insignificant if the number\r
+ is positive, and leading 0xff bytes if negative. */\r
+ {\r
+ size_t i;\r
+ const unsigned char* p = pendbyte;\r
+ const int pincr = -incr; /* search MSB to LSB */\r
+ const unsigned char insignficant = is_signed ? 0xff : 0x00;\r
+\r
+ for (i = 0; i < n; ++i, p += pincr) {\r
+ if (*p != insignficant)\r
+ break;\r
+ }\r
+ numsignificantbytes = n - i;\r
+ /* 2's-comp is a bit tricky here, e.g. 0xff00 == -0x0100, so\r
+ actually has 2 significant bytes. OTOH, 0xff0001 ==\r
+ -0x00ffff, so we wouldn't *need* to bump it there; but we\r
+ do for 0xffff = -0x0001. To be safe without bothering to\r
+ check every case, bump it regardless. */\r
+ if (is_signed && numsignificantbytes < n)\r
+ ++numsignificantbytes;\r
+ }\r
+\r
+ /* How many Python long digits do we need? We have\r
+ 8*numsignificantbytes bits, and each Python long digit has\r
+ PyLong_SHIFT bits, so it's the ceiling of the quotient. */\r
+ /* catch overflow before it happens */\r
+ if (numsignificantbytes > (PY_SSIZE_T_MAX - PyLong_SHIFT) / 8) {\r
+ PyErr_SetString(PyExc_OverflowError,\r
+ "byte array too long to convert to int");\r
+ return NULL;\r
+ }\r
+ ndigits = (numsignificantbytes * 8 + PyLong_SHIFT - 1) / PyLong_SHIFT;\r
+ v = _PyLong_New(ndigits);\r
+ if (v == NULL)\r
+ return NULL;\r
+\r
+ /* Copy the bits over. The tricky parts are computing 2's-comp on\r
+ the fly for signed numbers, and dealing with the mismatch between\r
+ 8-bit bytes and (probably) 15-bit Python digits.*/\r
+ {\r
+ size_t i;\r
+ twodigits carry = 1; /* for 2's-comp calculation */\r
+ twodigits accum = 0; /* sliding register */\r
+ unsigned int accumbits = 0; /* number of bits in accum */\r
+ const unsigned char* p = pstartbyte;\r
+\r
+ for (i = 0; i < numsignificantbytes; ++i, p += incr) {\r
+ twodigits thisbyte = *p;\r
+ /* Compute correction for 2's comp, if needed. */\r
+ if (is_signed) {\r
+ thisbyte = (0xff ^ thisbyte) + carry;\r
+ carry = thisbyte >> 8;\r
+ thisbyte &= 0xff;\r
+ }\r
+ /* Because we're going LSB to MSB, thisbyte is\r
+ more significant than what's already in accum,\r
+ so needs to be prepended to accum. */\r
+ accum |= (twodigits)thisbyte << accumbits;\r
+ accumbits += 8;\r
+ if (accumbits >= PyLong_SHIFT) {\r
+ /* There's enough to fill a Python digit. */\r
+ assert(idigit < ndigits);\r
+ v->ob_digit[idigit] = (digit)(accum & PyLong_MASK);\r
+ ++idigit;\r
+ accum >>= PyLong_SHIFT;\r
+ accumbits -= PyLong_SHIFT;\r
+ assert(accumbits < PyLong_SHIFT);\r
+ }\r
+ }\r
+ assert(accumbits < PyLong_SHIFT);\r
+ if (accumbits) {\r
+ assert(idigit < ndigits);\r
+ v->ob_digit[idigit] = (digit)accum;\r
+ ++idigit;\r
+ }\r
+ }\r
+\r
+ Py_SIZE(v) = is_signed ? -idigit : idigit;\r
+ return (PyObject *)long_normalize(v);\r
+}\r
+\r
+int\r
+_PyLong_AsByteArray(PyLongObject* v,\r
+ unsigned char* bytes, size_t n,\r
+ int little_endian, int is_signed)\r
+{\r
+ Py_ssize_t i; /* index into v->ob_digit */\r
+ Py_ssize_t ndigits; /* |v->ob_size| */\r
+ twodigits accum; /* sliding register */\r
+ unsigned int accumbits; /* # bits in accum */\r
+ int do_twos_comp; /* store 2's-comp? is_signed and v < 0 */\r
+ digit carry; /* for computing 2's-comp */\r
+ size_t j; /* # bytes filled */\r
+ unsigned char* p; /* pointer to next byte in bytes */\r
+ int pincr; /* direction to move p */\r
+\r
+ assert(v != NULL && PyLong_Check(v));\r
+\r
+ if (Py_SIZE(v) < 0) {\r
+ ndigits = -(Py_SIZE(v));\r
+ if (!is_signed) {\r
+ PyErr_SetString(PyExc_OverflowError,\r
+ "can't convert negative long to unsigned");\r
+ return -1;\r
+ }\r
+ do_twos_comp = 1;\r
+ }\r
+ else {\r
+ ndigits = Py_SIZE(v);\r
+ do_twos_comp = 0;\r
+ }\r
+\r
+ if (little_endian) {\r
+ p = bytes;\r
+ pincr = 1;\r
+ }\r
+ else {\r
+ p = bytes + n - 1;\r
+ pincr = -1;\r
+ }\r
+\r
+ /* Copy over all the Python digits.\r
+ It's crucial that every Python digit except for the MSD contribute\r
+ exactly PyLong_SHIFT bits to the total, so first assert that the long is\r
+ normalized. */\r
+ assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0);\r
+ j = 0;\r
+ accum = 0;\r
+ accumbits = 0;\r
+ carry = do_twos_comp ? 1 : 0;\r
+ for (i = 0; i < ndigits; ++i) {\r
+ digit thisdigit = v->ob_digit[i];\r
+ if (do_twos_comp) {\r
+ thisdigit = (thisdigit ^ PyLong_MASK) + carry;\r
+ carry = thisdigit >> PyLong_SHIFT;\r
+ thisdigit &= PyLong_MASK;\r
+ }\r
+ /* Because we're going LSB to MSB, thisdigit is more\r
+ significant than what's already in accum, so needs to be\r
+ prepended to accum. */\r
+ accum |= (twodigits)thisdigit << accumbits;\r
+\r
+ /* The most-significant digit may be (probably is) at least\r
+ partly empty. */\r
+ if (i == ndigits - 1) {\r
+ /* Count # of sign bits -- they needn't be stored,\r
+ * although for signed conversion we need later to\r
+ * make sure at least one sign bit gets stored. */\r
+ digit s = do_twos_comp ? thisdigit ^ PyLong_MASK : thisdigit;\r
+ while (s != 0) {\r
+ s >>= 1;\r
+ accumbits++;\r
+ }\r
+ }\r
+ else\r
+ accumbits += PyLong_SHIFT;\r
+\r
+ /* Store as many bytes as possible. */\r
+ while (accumbits >= 8) {\r
+ if (j >= n)\r
+ goto Overflow;\r
+ ++j;\r
+ *p = (unsigned char)(accum & 0xff);\r
+ p += pincr;\r
+ accumbits -= 8;\r
+ accum >>= 8;\r
+ }\r
+ }\r
+\r
+ /* Store the straggler (if any). */\r
+ assert(accumbits < 8);\r
+ assert(carry == 0); /* else do_twos_comp and *every* digit was 0 */\r
+ if (accumbits > 0) {\r
+ if (j >= n)\r
+ goto Overflow;\r
+ ++j;\r
+ if (do_twos_comp) {\r
+ /* Fill leading bits of the byte with sign bits\r
+ (appropriately pretending that the long had an\r
+ infinite supply of sign bits). */\r
+ accum |= (~(twodigits)0) << accumbits;\r
+ }\r
+ *p = (unsigned char)(accum & 0xff);\r
+ p += pincr;\r
+ }\r
+ else if (j == n && n > 0 && is_signed) {\r
+ /* The main loop filled the byte array exactly, so the code\r
+ just above didn't get to ensure there's a sign bit, and the\r
+ loop below wouldn't add one either. Make sure a sign bit\r
+ exists. */\r
+ unsigned char msb = *(p - pincr);\r
+ int sign_bit_set = msb >= 0x80;\r
+ assert(accumbits == 0);\r
+ if (sign_bit_set == do_twos_comp)\r
+ return 0;\r
+ else\r
+ goto Overflow;\r
+ }\r
+\r
+ /* Fill remaining bytes with copies of the sign bit. */\r
+ {\r
+ unsigned char signbyte = do_twos_comp ? 0xffU : 0U;\r
+ for ( ; j < n; ++j, p += pincr)\r
+ *p = signbyte;\r
+ }\r
+\r
+ return 0;\r
+\r
+ Overflow:\r
+ PyErr_SetString(PyExc_OverflowError, "long too big to convert");\r
+ return -1;\r
+\r
+}\r
+\r
+/* Create a new long (or int) object from a C pointer */\r
+\r
+PyObject *\r
+PyLong_FromVoidPtr(void *p)\r
+{\r
+#if SIZEOF_VOID_P <= SIZEOF_LONG\r
+ if ((long)p < 0)\r
+ return PyLong_FromUnsignedLong((unsigned long)p);\r
+ return PyInt_FromLong((long)p);\r
+#else\r
+\r
+#ifndef HAVE_LONG_LONG\r
+# error "PyLong_FromVoidPtr: sizeof(void*) > sizeof(long), but no long long"\r
+#endif\r
+#if SIZEOF_LONG_LONG < SIZEOF_VOID_P\r
+# error "PyLong_FromVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)"\r
+#endif\r
+ /* optimize null pointers */\r
+ if (p == NULL)\r
+ return PyInt_FromLong(0);\r
+ return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)p);\r
+\r
+#endif /* SIZEOF_VOID_P <= SIZEOF_LONG */\r
+}\r
+\r
+/* Get a C pointer from a long object (or an int object in some cases) */\r
+\r
+void *\r
+PyLong_AsVoidPtr(PyObject *vv)\r
+{\r
+ /* This function will allow int or long objects. If vv is neither,\r
+ then the PyLong_AsLong*() functions will raise the exception:\r
+ PyExc_SystemError, "bad argument to internal function"\r
+ */\r
+#if SIZEOF_VOID_P <= SIZEOF_LONG\r
+ long x;\r
+\r
+ if (PyInt_Check(vv))\r
+ x = PyInt_AS_LONG(vv);\r
+ else if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0)\r
+ x = PyLong_AsLong(vv);\r
+ else\r
+ x = PyLong_AsUnsignedLong(vv);\r
+#else\r
+\r
+#ifndef HAVE_LONG_LONG\r
+# error "PyLong_AsVoidPtr: sizeof(void*) > sizeof(long), but no long long"\r
+#endif\r
+#if SIZEOF_LONG_LONG < SIZEOF_VOID_P\r
+# error "PyLong_AsVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)"\r
+#endif\r
+ PY_LONG_LONG x;\r
+\r
+ if (PyInt_Check(vv))\r
+ x = PyInt_AS_LONG(vv);\r
+ else if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0)\r
+ x = PyLong_AsLongLong(vv);\r
+ else\r
+ x = PyLong_AsUnsignedLongLong(vv);\r
+\r
+#endif /* SIZEOF_VOID_P <= SIZEOF_LONG */\r
+\r
+ if (x == -1 && PyErr_Occurred())\r
+ return NULL;\r
+ return (void *)x;\r
+}\r
+\r
+#ifdef HAVE_LONG_LONG\r
+\r
+/* Initial PY_LONG_LONG support by Chris Herborth (chrish@qnx.com), later\r
+ * rewritten to use the newer PyLong_{As,From}ByteArray API.\r
+ */\r
+\r
+#define IS_LITTLE_ENDIAN (int)*(unsigned char*)&one\r
+#define PY_ABS_LLONG_MIN (0-(unsigned PY_LONG_LONG)PY_LLONG_MIN)\r
+\r
+/* Create a new long int object from a C PY_LONG_LONG int. */\r
+\r
+PyObject *\r
+PyLong_FromLongLong(PY_LONG_LONG ival)\r
+{\r
+ PyLongObject *v;\r
+ unsigned PY_LONG_LONG abs_ival;\r
+ unsigned PY_LONG_LONG t; /* unsigned so >> doesn't propagate sign bit */\r
+ int ndigits = 0;\r
+ int negative = 0;\r
+\r
+ if (ival < 0) {\r
+ /* avoid signed overflow on negation; see comments\r
+ in PyLong_FromLong above. */\r
+ abs_ival = (unsigned PY_LONG_LONG)(-1-ival) + 1;\r
+ negative = 1;\r
+ }\r
+ else {\r
+ abs_ival = (unsigned PY_LONG_LONG)ival;\r
+ }\r
+\r
+ /* Count the number of Python digits.\r
+ We used to pick 5 ("big enough for anything"), but that's a\r
+ waste of time and space given that 5*15 = 75 bits are rarely\r
+ needed. */\r
+ t = abs_ival;\r
+ while (t) {\r
+ ++ndigits;\r
+ t >>= PyLong_SHIFT;\r
+ }\r
+ v = _PyLong_New(ndigits);\r
+ if (v != NULL) {\r
+ digit *p = v->ob_digit;\r
+ Py_SIZE(v) = negative ? -ndigits : ndigits;\r
+ t = abs_ival;\r
+ while (t) {\r
+ *p++ = (digit)(t & PyLong_MASK);\r
+ t >>= PyLong_SHIFT;\r
+ }\r
+ }\r
+ return (PyObject *)v;\r
+}\r
+\r
+/* Create a new long int object from a C unsigned PY_LONG_LONG int. */\r
+\r
+PyObject *\r
+PyLong_FromUnsignedLongLong(unsigned PY_LONG_LONG ival)\r
+{\r
+ PyLongObject *v;\r
+ unsigned PY_LONG_LONG t;\r
+ int ndigits = 0;\r
+\r
+ /* Count the number of Python digits. */\r
+ t = (unsigned PY_LONG_LONG)ival;\r
+ while (t) {\r
+ ++ndigits;\r
+ t >>= PyLong_SHIFT;\r
+ }\r
+ v = _PyLong_New(ndigits);\r
+ if (v != NULL) {\r
+ digit *p = v->ob_digit;\r
+ Py_SIZE(v) = ndigits;\r
+ while (ival) {\r
+ *p++ = (digit)(ival & PyLong_MASK);\r
+ ival >>= PyLong_SHIFT;\r
+ }\r
+ }\r
+ return (PyObject *)v;\r
+}\r
+\r
+/* Create a new long int object from a C Py_ssize_t. */\r
+\r
+PyObject *\r
+PyLong_FromSsize_t(Py_ssize_t ival)\r
+{\r
+ Py_ssize_t bytes = ival;\r
+ int one = 1;\r
+ return _PyLong_FromByteArray((unsigned char *)&bytes,\r
+ SIZEOF_SIZE_T, IS_LITTLE_ENDIAN, 1);\r
+}\r
+\r
+/* Create a new long int object from a C size_t. */\r
+\r
+PyObject *\r
+PyLong_FromSize_t(size_t ival)\r
+{\r
+ size_t bytes = ival;\r
+ int one = 1;\r
+ return _PyLong_FromByteArray((unsigned char *)&bytes,\r
+ SIZEOF_SIZE_T, IS_LITTLE_ENDIAN, 0);\r
+}\r
+\r
+/* Get a C PY_LONG_LONG int from a long int object.\r
+ Return -1 and set an error if overflow occurs. */\r
+\r
+PY_LONG_LONG\r
+PyLong_AsLongLong(PyObject *vv)\r
+{\r
+ PY_LONG_LONG bytes;\r
+ int one = 1;\r
+ int res;\r
+\r
+ if (vv == NULL) {\r
+ PyErr_BadInternalCall();\r
+ return -1;\r
+ }\r
+ if (!PyLong_Check(vv)) {\r
+ PyNumberMethods *nb;\r
+ PyObject *io;\r
+ if (PyInt_Check(vv))\r
+ return (PY_LONG_LONG)PyInt_AsLong(vv);\r
+ if ((nb = vv->ob_type->tp_as_number) == NULL ||\r
+ nb->nb_int == NULL) {\r
+ PyErr_SetString(PyExc_TypeError, "an integer is required");\r
+ return -1;\r
+ }\r
+ io = (*nb->nb_int) (vv);\r
+ if (io == NULL)\r
+ return -1;\r
+ if (PyInt_Check(io)) {\r
+ bytes = PyInt_AsLong(io);\r
+ Py_DECREF(io);\r
+ return bytes;\r
+ }\r
+ if (PyLong_Check(io)) {\r
+ bytes = PyLong_AsLongLong(io);\r
+ Py_DECREF(io);\r
+ return bytes;\r
+ }\r
+ Py_DECREF(io);\r
+ PyErr_SetString(PyExc_TypeError, "integer conversion failed");\r
+ return -1;\r
+ }\r
+\r
+ res = _PyLong_AsByteArray((PyLongObject *)vv, (unsigned char *)&bytes,\r
+ SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 1);\r
+\r
+ /* Plan 9 can't handle PY_LONG_LONG in ? : expressions */\r
+ if (res < 0)\r
+ return (PY_LONG_LONG)-1;\r
+ else\r
+ return bytes;\r
+}\r
+\r
+/* Get a C unsigned PY_LONG_LONG int from a long int object.\r
+ Return -1 and set an error if overflow occurs. */\r
+\r
+unsigned PY_LONG_LONG\r
+PyLong_AsUnsignedLongLong(PyObject *vv)\r
+{\r
+ unsigned PY_LONG_LONG bytes;\r
+ int one = 1;\r
+ int res;\r
+\r
+ if (vv == NULL || !PyLong_Check(vv)) {\r
+ PyErr_BadInternalCall();\r
+ return (unsigned PY_LONG_LONG)-1;\r
+ }\r
+\r
+ res = _PyLong_AsByteArray((PyLongObject *)vv, (unsigned char *)&bytes,\r
+ SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 0);\r
+\r
+ /* Plan 9 can't handle PY_LONG_LONG in ? : expressions */\r
+ if (res < 0)\r
+ return (unsigned PY_LONG_LONG)res;\r
+ else\r
+ return bytes;\r
+}\r
+\r
+/* Get a C unsigned long int from a long int object, ignoring the high bits.\r
+ Returns -1 and sets an error condition if an error occurs. */\r
+\r
+unsigned PY_LONG_LONG\r
+PyLong_AsUnsignedLongLongMask(PyObject *vv)\r
+{\r
+ register PyLongObject *v;\r
+ unsigned PY_LONG_LONG x;\r
+ Py_ssize_t i;\r
+ int sign;\r
+\r
+ if (vv == NULL || !PyLong_Check(vv)) {\r
+ PyErr_BadInternalCall();\r
+ return (unsigned long) -1;\r
+ }\r
+ v = (PyLongObject *)vv;\r
+ i = v->ob_size;\r
+ sign = 1;\r
+ x = 0;\r
+ if (i < 0) {\r
+ sign = -1;\r
+ i = -i;\r
+ }\r
+ while (--i >= 0) {\r
+ x = (x << PyLong_SHIFT) | v->ob_digit[i];\r
+ }\r
+ return x * sign;\r
+}\r
+\r
+/* Get a C long long int from a Python long or Python int object.\r
+ On overflow, returns -1 and sets *overflow to 1 or -1 depending\r
+ on the sign of the result. Otherwise *overflow is 0.\r
+\r
+ For other errors (e.g., type error), returns -1 and sets an error\r
+ condition.\r
+*/\r
+\r
+PY_LONG_LONG\r
+PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow)\r
+{\r
+ /* This version by Tim Peters */\r
+ register PyLongObject *v;\r
+ unsigned PY_LONG_LONG x, prev;\r
+ PY_LONG_LONG res;\r
+ Py_ssize_t i;\r
+ int sign;\r
+ int do_decref = 0; /* if nb_int was called */\r
+\r
+ *overflow = 0;\r
+ if (vv == NULL) {\r
+ PyErr_BadInternalCall();\r
+ return -1;\r
+ }\r
+\r
+ if (PyInt_Check(vv))\r
+ return PyInt_AsLong(vv);\r
+\r
+ if (!PyLong_Check(vv)) {\r
+ PyNumberMethods *nb;\r
+ nb = vv->ob_type->tp_as_number;\r
+ if (nb == NULL || nb->nb_int == NULL) {\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "an integer is required");\r
+ return -1;\r
+ }\r
+ vv = (*nb->nb_int) (vv);\r
+ if (vv == NULL)\r
+ return -1;\r
+ do_decref = 1;\r
+ if(PyInt_Check(vv)) {\r
+ res = PyInt_AsLong(vv);\r
+ goto exit;\r
+ }\r
+ if (!PyLong_Check(vv)) {\r
+ Py_DECREF(vv);\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "nb_int should return int object");\r
+ return -1;\r
+ }\r
+ }\r
+\r
+ res = -1;\r
+ v = (PyLongObject *)vv;\r
+ i = Py_SIZE(v);\r
+\r
+ switch (i) {\r
+ case -1:\r
+ res = -(sdigit)v->ob_digit[0];\r
+ break;\r
+ case 0:\r
+ res = 0;\r
+ break;\r
+ case 1:\r
+ res = v->ob_digit[0];\r
+ break;\r
+ default:\r
+ sign = 1;\r
+ x = 0;\r
+ if (i < 0) {\r
+ sign = -1;\r
+ i = -(i);\r
+ }\r
+ while (--i >= 0) {\r
+ prev = x;\r
+ x = (x << PyLong_SHIFT) + v->ob_digit[i];\r
+ if ((x >> PyLong_SHIFT) != prev) {\r
+ *overflow = sign;\r
+ goto exit;\r
+ }\r
+ }\r
+ /* Haven't lost any bits, but casting to long requires extra\r
+ * care (see comment above).\r
+ */\r
+ if (x <= (unsigned PY_LONG_LONG)PY_LLONG_MAX) {\r
+ res = (PY_LONG_LONG)x * sign;\r
+ }\r
+ else if (sign < 0 && x == PY_ABS_LLONG_MIN) {\r
+ res = PY_LLONG_MIN;\r
+ }\r
+ else {\r
+ *overflow = sign;\r
+ /* res is already set to -1 */\r
+ }\r
+ }\r
+ exit:\r
+ if (do_decref) {\r
+ Py_DECREF(vv);\r
+ }\r
+ return res;\r
+}\r
+\r
+#undef IS_LITTLE_ENDIAN\r
+\r
+#endif /* HAVE_LONG_LONG */\r
+\r
+\r
+static int\r
+convert_binop(PyObject *v, PyObject *w, PyLongObject **a, PyLongObject **b) {\r
+ if (PyLong_Check(v)) {\r
+ *a = (PyLongObject *) v;\r
+ Py_INCREF(v);\r
+ }\r
+ else if (PyInt_Check(v)) {\r
+ *a = (PyLongObject *) PyLong_FromLong(PyInt_AS_LONG(v));\r
+ }\r
+ else {\r
+ return 0;\r
+ }\r
+ if (PyLong_Check(w)) {\r
+ *b = (PyLongObject *) w;\r
+ Py_INCREF(w);\r
+ }\r
+ else if (PyInt_Check(w)) {\r
+ *b = (PyLongObject *) PyLong_FromLong(PyInt_AS_LONG(w));\r
+ }\r
+ else {\r
+ Py_DECREF(*a);\r
+ return 0;\r
+ }\r
+ return 1;\r
+}\r
+\r
+#define CONVERT_BINOP(v, w, a, b) \\r
+ do { \\r
+ if (!convert_binop(v, w, a, b)) { \\r
+ Py_INCREF(Py_NotImplemented); \\r
+ return Py_NotImplemented; \\r
+ } \\r
+ } while(0) \\r
+\r
+/* bits_in_digit(d) returns the unique integer k such that 2**(k-1) <= d <\r
+ 2**k if d is nonzero, else 0. */\r
+\r
+static const unsigned char BitLengthTable[32] = {\r
+ 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,\r
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5\r
+};\r
+\r
+static int\r
+bits_in_digit(digit d)\r
+{\r
+ int d_bits = 0;\r
+ while (d >= 32) {\r
+ d_bits += 6;\r
+ d >>= 6;\r
+ }\r
+ d_bits += (int)BitLengthTable[d];\r
+ return d_bits;\r
+}\r
+\r
+/* x[0:m] and y[0:n] are digit vectors, LSD first, m >= n required. x[0:n]\r
+ * is modified in place, by adding y to it. Carries are propagated as far as\r
+ * x[m-1], and the remaining carry (0 or 1) is returned.\r
+ */\r
+static digit\r
+v_iadd(digit *x, Py_ssize_t m, digit *y, Py_ssize_t n)\r
+{\r
+ Py_ssize_t i;\r
+ digit carry = 0;\r
+\r
+ assert(m >= n);\r
+ for (i = 0; i < n; ++i) {\r
+ carry += x[i] + y[i];\r
+ x[i] = carry & PyLong_MASK;\r
+ carry >>= PyLong_SHIFT;\r
+ assert((carry & 1) == carry);\r
+ }\r
+ for (; carry && i < m; ++i) {\r
+ carry += x[i];\r
+ x[i] = carry & PyLong_MASK;\r
+ carry >>= PyLong_SHIFT;\r
+ assert((carry & 1) == carry);\r
+ }\r
+ return carry;\r
+}\r
+\r
+/* x[0:m] and y[0:n] are digit vectors, LSD first, m >= n required. x[0:n]\r
+ * is modified in place, by subtracting y from it. Borrows are propagated as\r
+ * far as x[m-1], and the remaining borrow (0 or 1) is returned.\r
+ */\r
+static digit\r
+v_isub(digit *x, Py_ssize_t m, digit *y, Py_ssize_t n)\r
+{\r
+ Py_ssize_t i;\r
+ digit borrow = 0;\r
+\r
+ assert(m >= n);\r
+ for (i = 0; i < n; ++i) {\r
+ borrow = x[i] - y[i] - borrow;\r
+ x[i] = borrow & PyLong_MASK;\r
+ borrow >>= PyLong_SHIFT;\r
+ borrow &= 1; /* keep only 1 sign bit */\r
+ }\r
+ for (; borrow && i < m; ++i) {\r
+ borrow = x[i] - borrow;\r
+ x[i] = borrow & PyLong_MASK;\r
+ borrow >>= PyLong_SHIFT;\r
+ borrow &= 1;\r
+ }\r
+ return borrow;\r
+}\r
+\r
+/* Shift digit vector a[0:m] d bits left, with 0 <= d < PyLong_SHIFT. Put\r
+ * result in z[0:m], and return the d bits shifted out of the top.\r
+ */\r
+static digit\r
+v_lshift(digit *z, digit *a, Py_ssize_t m, int d)\r
+{\r
+ Py_ssize_t i;\r
+ digit carry = 0;\r
+\r
+ assert(0 <= d && d < PyLong_SHIFT);\r
+ for (i=0; i < m; i++) {\r
+ twodigits acc = (twodigits)a[i] << d | carry;\r
+ z[i] = (digit)acc & PyLong_MASK;\r
+ carry = (digit)(acc >> PyLong_SHIFT);\r
+ }\r
+ return carry;\r
+}\r
+\r
+/* Shift digit vector a[0:m] d bits right, with 0 <= d < PyLong_SHIFT. Put\r
+ * result in z[0:m], and return the d bits shifted out of the bottom.\r
+ */\r
+static digit\r
+v_rshift(digit *z, digit *a, Py_ssize_t m, int d)\r
+{\r
+ Py_ssize_t i;\r
+ digit carry = 0;\r
+ digit mask = ((digit)1 << d) - 1U;\r
+\r
+ assert(0 <= d && d < PyLong_SHIFT);\r
+ for (i=m; i-- > 0;) {\r
+ twodigits acc = (twodigits)carry << PyLong_SHIFT | a[i];\r
+ carry = (digit)acc & mask;\r
+ z[i] = (digit)(acc >> d);\r
+ }\r
+ return carry;\r
+}\r
+\r
+/* Divide long pin, w/ size digits, by non-zero digit n, storing quotient\r
+ in pout, and returning the remainder. pin and pout point at the LSD.\r
+ It's OK for pin == pout on entry, which saves oodles of mallocs/frees in\r
+ _PyLong_Format, but that should be done with great care since longs are\r
+ immutable. */\r
+\r
+static digit\r
+inplace_divrem1(digit *pout, digit *pin, Py_ssize_t size, digit n)\r
+{\r
+ twodigits rem = 0;\r
+\r
+ assert(n > 0 && n <= PyLong_MASK);\r
+ pin += size;\r
+ pout += size;\r
+ while (--size >= 0) {\r
+ digit hi;\r
+ rem = (rem << PyLong_SHIFT) | *--pin;\r
+ *--pout = hi = (digit)(rem / n);\r
+ rem -= (twodigits)hi * n;\r
+ }\r
+ return (digit)rem;\r
+}\r
+\r
+/* Divide a long integer by a digit, returning both the quotient\r
+ (as function result) and the remainder (through *prem).\r
+ The sign of a is ignored; n should not be zero. */\r
+\r
+static PyLongObject *\r
+divrem1(PyLongObject *a, digit n, digit *prem)\r
+{\r
+ const Py_ssize_t size = ABS(Py_SIZE(a));\r
+ PyLongObject *z;\r
+\r
+ assert(n > 0 && n <= PyLong_MASK);\r
+ z = _PyLong_New(size);\r
+ if (z == NULL)\r
+ return NULL;\r
+ *prem = inplace_divrem1(z->ob_digit, a->ob_digit, size, n);\r
+ return long_normalize(z);\r
+}\r
+\r
+/* Convert a long integer to a base 10 string. Returns a new non-shared\r
+ string. (Return value is non-shared so that callers can modify the\r
+ returned value if necessary.) */\r
+\r
+static PyObject *\r
+long_to_decimal_string(PyObject *aa, int addL)\r
+{\r
+ PyLongObject *scratch, *a;\r
+ PyObject *str;\r
+ Py_ssize_t size, strlen, size_a, i, j;\r
+ digit *pout, *pin, rem, tenpow;\r
+ char *p;\r
+ int negative;\r
+\r
+ a = (PyLongObject *)aa;\r
+ if (a == NULL || !PyLong_Check(a)) {\r
+ PyErr_BadInternalCall();\r
+ return NULL;\r
+ }\r
+ size_a = ABS(Py_SIZE(a));\r
+ negative = Py_SIZE(a) < 0;\r
+\r
+ /* quick and dirty upper bound for the number of digits\r
+ required to express a in base _PyLong_DECIMAL_BASE:\r
+\r
+ #digits = 1 + floor(log2(a) / log2(_PyLong_DECIMAL_BASE))\r
+\r
+ But log2(a) < size_a * PyLong_SHIFT, and\r
+ log2(_PyLong_DECIMAL_BASE) = log2(10) * _PyLong_DECIMAL_SHIFT\r
+ > 3 * _PyLong_DECIMAL_SHIFT\r
+ */\r
+ if (size_a > PY_SSIZE_T_MAX / PyLong_SHIFT) {\r
+ PyErr_SetString(PyExc_OverflowError,\r
+ "long is too large to format");\r
+ return NULL;\r
+ }\r
+ /* the expression size_a * PyLong_SHIFT is now safe from overflow */\r
+ size = 1 + size_a * PyLong_SHIFT / (3 * _PyLong_DECIMAL_SHIFT);\r
+ scratch = _PyLong_New(size);\r
+ if (scratch == NULL)\r
+ return NULL;\r
+\r
+ /* convert array of base _PyLong_BASE digits in pin to an array of\r
+ base _PyLong_DECIMAL_BASE digits in pout, following Knuth (TAOCP,\r
+ Volume 2 (3rd edn), section 4.4, Method 1b). */\r
+ pin = a->ob_digit;\r
+ pout = scratch->ob_digit;\r
+ size = 0;\r
+ for (i = size_a; --i >= 0; ) {\r
+ digit hi = pin[i];\r
+ for (j = 0; j < size; j++) {\r
+ twodigits z = (twodigits)pout[j] << PyLong_SHIFT | hi;\r
+ hi = (digit)(z / _PyLong_DECIMAL_BASE);\r
+ pout[j] = (digit)(z - (twodigits)hi *\r
+ _PyLong_DECIMAL_BASE);\r
+ }\r
+ while (hi) {\r
+ pout[size++] = hi % _PyLong_DECIMAL_BASE;\r
+ hi /= _PyLong_DECIMAL_BASE;\r
+ }\r
+ /* check for keyboard interrupt */\r
+ SIGCHECK({\r
+ Py_DECREF(scratch);\r
+ return NULL;\r
+ });\r
+ }\r
+ /* pout should have at least one digit, so that the case when a = 0\r
+ works correctly */\r
+ if (size == 0)\r
+ pout[size++] = 0;\r
+\r
+ /* calculate exact length of output string, and allocate */\r
+ strlen = (addL != 0) + negative +\r
+ 1 + (size - 1) * _PyLong_DECIMAL_SHIFT;\r
+ tenpow = 10;\r
+ rem = pout[size-1];\r
+ while (rem >= tenpow) {\r
+ tenpow *= 10;\r
+ strlen++;\r
+ }\r
+ str = PyString_FromStringAndSize(NULL, strlen);\r
+ if (str == NULL) {\r
+ Py_DECREF(scratch);\r
+ return NULL;\r
+ }\r
+\r
+ /* fill the string right-to-left */\r
+ p = PyString_AS_STRING(str) + strlen;\r
+ *p = '\0';\r
+ if (addL)\r
+ *--p = 'L';\r
+ /* pout[0] through pout[size-2] contribute exactly\r
+ _PyLong_DECIMAL_SHIFT digits each */\r
+ for (i=0; i < size - 1; i++) {\r
+ rem = pout[i];\r
+ for (j = 0; j < _PyLong_DECIMAL_SHIFT; j++) {\r
+ *--p = '0' + rem % 10;\r
+ rem /= 10;\r
+ }\r
+ }\r
+ /* pout[size-1]: always produce at least one decimal digit */\r
+ rem = pout[i];\r
+ do {\r
+ *--p = '0' + rem % 10;\r
+ rem /= 10;\r
+ } while (rem != 0);\r
+\r
+ /* and sign */\r
+ if (negative)\r
+ *--p = '-';\r
+\r
+ /* check we've counted correctly */\r
+ assert(p == PyString_AS_STRING(str));\r
+ Py_DECREF(scratch);\r
+ return (PyObject *)str;\r
+}\r
+\r
+/* Convert the long to a string object with given base,\r
+ appending a base prefix of 0[box] if base is 2, 8 or 16.\r
+ Add a trailing "L" if addL is non-zero.\r
+ If newstyle is zero, then use the pre-2.6 behavior of octal having\r
+ a leading "0", instead of the prefix "0o" */\r
+PyAPI_FUNC(PyObject *)\r
+_PyLong_Format(PyObject *aa, int base, int addL, int newstyle)\r
+{\r
+ register PyLongObject *a = (PyLongObject *)aa;\r
+ PyStringObject *str;\r
+ Py_ssize_t i, sz;\r
+ Py_ssize_t size_a;\r
+ char *p;\r
+ int bits;\r
+ char sign = '\0';\r
+\r
+ if (base == 10)\r
+ return long_to_decimal_string((PyObject *)a, addL);\r
+\r
+ if (a == NULL || !PyLong_Check(a)) {\r
+ PyErr_BadInternalCall();\r
+ return NULL;\r
+ }\r
+ assert(base >= 2 && base <= 36);\r
+ size_a = ABS(Py_SIZE(a));\r
+\r
+ /* Compute a rough upper bound for the length of the string */\r
+ i = base;\r
+ bits = 0;\r
+ while (i > 1) {\r
+ ++bits;\r
+ i >>= 1;\r
+ }\r
+ i = 5 + (addL ? 1 : 0);\r
+ /* ensure we don't get signed overflow in sz calculation */\r
+ if (size_a > (PY_SSIZE_T_MAX - i) / PyLong_SHIFT) {\r
+ PyErr_SetString(PyExc_OverflowError,\r
+ "long is too large to format");\r
+ return NULL;\r
+ }\r
+ sz = i + 1 + (size_a * PyLong_SHIFT - 1) / bits;\r
+ assert(sz >= 0);\r
+ str = (PyStringObject *) PyString_FromStringAndSize((char *)0, sz);\r
+ if (str == NULL)\r
+ return NULL;\r
+ p = PyString_AS_STRING(str) + sz;\r
+ *p = '\0';\r
+ if (addL)\r
+ *--p = 'L';\r
+ if (a->ob_size < 0)\r
+ sign = '-';\r
+\r
+ if (a->ob_size == 0) {\r
+ *--p = '0';\r
+ }\r
+ else if ((base & (base - 1)) == 0) {\r
+ /* JRH: special case for power-of-2 bases */\r
+ twodigits accum = 0;\r
+ int accumbits = 0; /* # of bits in accum */\r
+ int basebits = 1; /* # of bits in base-1 */\r
+ i = base;\r
+ while ((i >>= 1) > 1)\r
+ ++basebits;\r
+\r
+ for (i = 0; i < size_a; ++i) {\r
+ accum |= (twodigits)a->ob_digit[i] << accumbits;\r
+ accumbits += PyLong_SHIFT;\r
+ assert(accumbits >= basebits);\r
+ do {\r
+ char cdigit = (char)(accum & (base - 1));\r
+ cdigit += (cdigit < 10) ? '0' : 'a'-10;\r
+ assert(p > PyString_AS_STRING(str));\r
+ *--p = cdigit;\r
+ accumbits -= basebits;\r
+ accum >>= basebits;\r
+ } while (i < size_a-1 ? accumbits >= basebits : accum > 0);\r
+ }\r
+ }\r
+ else {\r
+ /* Not 0, and base not a power of 2. Divide repeatedly by\r
+ base, but for speed use the highest power of base that\r
+ fits in a digit. */\r
+ Py_ssize_t size = size_a;\r
+ digit *pin = a->ob_digit;\r
+ PyLongObject *scratch;\r
+ /* powbasw <- largest power of base that fits in a digit. */\r
+ digit powbase = base; /* powbase == base ** power */\r
+ int power = 1;\r
+ for (;;) {\r
+ twodigits newpow = powbase * (twodigits)base;\r
+ if (newpow >> PyLong_SHIFT)\r
+ /* doesn't fit in a digit */\r
+ break;\r
+ powbase = (digit)newpow;\r
+ ++power;\r
+ }\r
+\r
+ /* Get a scratch area for repeated division. */\r
+ scratch = _PyLong_New(size);\r
+ if (scratch == NULL) {\r
+ Py_DECREF(str);\r
+ return NULL;\r
+ }\r
+\r
+ /* Repeatedly divide by powbase. */\r
+ do {\r
+ int ntostore = power;\r
+ digit rem = inplace_divrem1(scratch->ob_digit,\r
+ pin, size, powbase);\r
+ pin = scratch->ob_digit; /* no need to use a again */\r
+ if (pin[size - 1] == 0)\r
+ --size;\r
+ SIGCHECK({\r
+ Py_DECREF(scratch);\r
+ Py_DECREF(str);\r
+ return NULL;\r
+ });\r
+\r
+ /* Break rem into digits. */\r
+ assert(ntostore > 0);\r
+ do {\r
+ digit nextrem = (digit)(rem / base);\r
+ char c = (char)(rem - nextrem * base);\r
+ assert(p > PyString_AS_STRING(str));\r
+ c += (c < 10) ? '0' : 'a'-10;\r
+ *--p = c;\r
+ rem = nextrem;\r
+ --ntostore;\r
+ /* Termination is a bit delicate: must not\r
+ store leading zeroes, so must get out if\r
+ remaining quotient and rem are both 0. */\r
+ } while (ntostore && (size || rem));\r
+ } while (size != 0);\r
+ Py_DECREF(scratch);\r
+ }\r
+\r
+ if (base == 2) {\r
+ *--p = 'b';\r
+ *--p = '0';\r
+ }\r
+ else if (base == 8) {\r
+ if (newstyle) {\r
+ *--p = 'o';\r
+ *--p = '0';\r
+ }\r
+ else\r
+ if (size_a != 0)\r
+ *--p = '0';\r
+ }\r
+ else if (base == 16) {\r
+ *--p = 'x';\r
+ *--p = '0';\r
+ }\r
+ else if (base != 10) {\r
+ *--p = '#';\r
+ *--p = '0' + base%10;\r
+ if (base > 10)\r
+ *--p = '0' + base/10;\r
+ }\r
+ if (sign)\r
+ *--p = sign;\r
+ if (p != PyString_AS_STRING(str)) {\r
+ char *q = PyString_AS_STRING(str);\r
+ assert(p > q);\r
+ do {\r
+ } while ((*q++ = *p++) != '\0');\r
+ q--;\r
+ _PyString_Resize((PyObject **)&str,\r
+ (Py_ssize_t) (q - PyString_AS_STRING(str)));\r
+ }\r
+ return (PyObject *)str;\r
+}\r
+\r
+/* Table of digit values for 8-bit string -> integer conversion.\r
+ * '0' maps to 0, ..., '9' maps to 9.\r
+ * 'a' and 'A' map to 10, ..., 'z' and 'Z' map to 35.\r
+ * All other indices map to 37.\r
+ * Note that when converting a base B string, a char c is a legitimate\r
+ * base B digit iff _PyLong_DigitValue[Py_CHARMASK(c)] < B.\r
+ */\r
+int _PyLong_DigitValue[256] = {\r
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,\r
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,\r
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,\r
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 37, 37, 37, 37, 37, 37,\r
+ 37, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,\r
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 37, 37, 37, 37, 37,\r
+ 37, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,\r
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 37, 37, 37, 37, 37,\r
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,\r
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,\r
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,\r
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,\r
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,\r
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,\r
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,\r
+ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,\r
+};\r
+\r
+/* *str points to the first digit in a string of base `base` digits. base\r
+ * is a power of 2 (2, 4, 8, 16, or 32). *str is set to point to the first\r
+ * non-digit (which may be *str!). A normalized long is returned.\r
+ * The point to this routine is that it takes time linear in the number of\r
+ * string characters.\r
+ */\r
+static PyLongObject *\r
+long_from_binary_base(char **str, int base)\r
+{\r
+ char *p = *str;\r
+ char *start = p;\r
+ int bits_per_char;\r
+ Py_ssize_t n;\r
+ PyLongObject *z;\r
+ twodigits accum;\r
+ int bits_in_accum;\r
+ digit *pdigit;\r
+\r
+ assert(base >= 2 && base <= 32 && (base & (base - 1)) == 0);\r
+ n = base;\r
+ for (bits_per_char = -1; n; ++bits_per_char)\r
+ n >>= 1;\r
+ /* n <- total # of bits needed, while setting p to end-of-string */\r
+ while (_PyLong_DigitValue[Py_CHARMASK(*p)] < base)\r
+ ++p;\r
+ *str = p;\r
+ /* n <- # of Python digits needed, = ceiling(n/PyLong_SHIFT). */\r
+ n = (p - start) * bits_per_char + PyLong_SHIFT - 1;\r
+ if (n / bits_per_char < p - start) {\r
+ PyErr_SetString(PyExc_ValueError,\r
+ "long string too large to convert");\r
+ return NULL;\r
+ }\r
+ n = n / PyLong_SHIFT;\r
+ z = _PyLong_New(n);\r
+ if (z == NULL)\r
+ return NULL;\r
+ /* Read string from right, and fill in long from left; i.e.,\r
+ * from least to most significant in both.\r
+ */\r
+ accum = 0;\r
+ bits_in_accum = 0;\r
+ pdigit = z->ob_digit;\r
+ while (--p >= start) {\r
+ int k = _PyLong_DigitValue[Py_CHARMASK(*p)];\r
+ assert(k >= 0 && k < base);\r
+ accum |= (twodigits)k << bits_in_accum;\r
+ bits_in_accum += bits_per_char;\r
+ if (bits_in_accum >= PyLong_SHIFT) {\r
+ *pdigit++ = (digit)(accum & PyLong_MASK);\r
+ assert(pdigit - z->ob_digit <= n);\r
+ accum >>= PyLong_SHIFT;\r
+ bits_in_accum -= PyLong_SHIFT;\r
+ assert(bits_in_accum < PyLong_SHIFT);\r
+ }\r
+ }\r
+ if (bits_in_accum) {\r
+ assert(bits_in_accum <= PyLong_SHIFT);\r
+ *pdigit++ = (digit)accum;\r
+ assert(pdigit - z->ob_digit <= n);\r
+ }\r
+ while (pdigit - z->ob_digit < n)\r
+ *pdigit++ = 0;\r
+ return long_normalize(z);\r
+}\r
+\r
+PyObject *\r
+PyLong_FromString(char *str, char **pend, int base)\r
+{\r
+ int sign = 1;\r
+ char *start, *orig_str = str;\r
+ PyLongObject *z;\r
+ PyObject *strobj, *strrepr;\r
+ Py_ssize_t slen;\r
+\r
+ if ((base != 0 && base < 2) || base > 36) {\r
+ PyErr_SetString(PyExc_ValueError,\r
+ "long() arg 2 must be >= 2 and <= 36");\r
+ return NULL;\r
+ }\r
+ while (*str != '\0' && isspace(Py_CHARMASK(*str)))\r
+ str++;\r
+ if (*str == '+')\r
+ ++str;\r
+ else if (*str == '-') {\r
+ ++str;\r
+ sign = -1;\r
+ }\r
+ while (*str != '\0' && isspace(Py_CHARMASK(*str)))\r
+ str++;\r
+ if (base == 0) {\r
+ /* No base given. Deduce the base from the contents\r
+ of the string */\r
+ if (str[0] != '0')\r
+ base = 10;\r
+ else if (str[1] == 'x' || str[1] == 'X')\r
+ base = 16;\r
+ else if (str[1] == 'o' || str[1] == 'O')\r
+ base = 8;\r
+ else if (str[1] == 'b' || str[1] == 'B')\r
+ base = 2;\r
+ else\r
+ /* "old" (C-style) octal literal, still valid in\r
+ 2.x, although illegal in 3.x */\r
+ base = 8;\r
+ }\r
+ /* Whether or not we were deducing the base, skip leading chars\r
+ as needed */\r
+ if (str[0] == '0' &&\r
+ ((base == 16 && (str[1] == 'x' || str[1] == 'X')) ||\r
+ (base == 8 && (str[1] == 'o' || str[1] == 'O')) ||\r
+ (base == 2 && (str[1] == 'b' || str[1] == 'B'))))\r
+ str += 2;\r
+\r
+ start = str;\r
+ if ((base & (base - 1)) == 0)\r
+ z = long_from_binary_base(&str, base);\r
+ else {\r
+/***\r
+Binary bases can be converted in time linear in the number of digits, because\r
+Python's representation base is binary. Other bases (including decimal!) use\r
+the simple quadratic-time algorithm below, complicated by some speed tricks.\r
+\r
+First some math: the largest integer that can be expressed in N base-B digits\r
+is B**N-1. Consequently, if we have an N-digit input in base B, the worst-\r
+case number of Python digits needed to hold it is the smallest integer n s.t.\r
+\r
+ PyLong_BASE**n-1 >= B**N-1 [or, adding 1 to both sides]\r
+ PyLong_BASE**n >= B**N [taking logs to base PyLong_BASE]\r
+ n >= log(B**N)/log(PyLong_BASE) = N * log(B)/log(PyLong_BASE)\r
+\r
+The static array log_base_PyLong_BASE[base] == log(base)/log(PyLong_BASE) so\r
+we can compute this quickly. A Python long with that much space is reserved\r
+near the start, and the result is computed into it.\r
+\r
+The input string is actually treated as being in base base**i (i.e., i digits\r
+are processed at a time), where two more static arrays hold:\r
+\r
+ convwidth_base[base] = the largest integer i such that\r
+ base**i <= PyLong_BASE\r
+ convmultmax_base[base] = base ** convwidth_base[base]\r
+\r
+The first of these is the largest i such that i consecutive input digits\r
+must fit in a single Python digit. The second is effectively the input\r
+base we're really using.\r
+\r
+Viewing the input as a sequence <c0, c1, ..., c_n-1> of digits in base\r
+convmultmax_base[base], the result is "simply"\r
+\r
+ (((c0*B + c1)*B + c2)*B + c3)*B + ... ))) + c_n-1\r
+\r
+where B = convmultmax_base[base].\r
+\r
+Error analysis: as above, the number of Python digits `n` needed is worst-\r
+case\r
+\r
+ n >= N * log(B)/log(PyLong_BASE)\r
+\r
+where `N` is the number of input digits in base `B`. This is computed via\r
+\r
+ size_z = (Py_ssize_t)((scan - str) * log_base_PyLong_BASE[base]) + 1;\r
+\r
+below. Two numeric concerns are how much space this can waste, and whether\r
+the computed result can be too small. To be concrete, assume PyLong_BASE =\r
+2**15, which is the default (and it's unlikely anyone changes that).\r
+\r
+Waste isn't a problem: provided the first input digit isn't 0, the difference\r
+between the worst-case input with N digits and the smallest input with N\r
+digits is about a factor of B, but B is small compared to PyLong_BASE so at\r
+most one allocated Python digit can remain unused on that count. If\r
+N*log(B)/log(PyLong_BASE) is mathematically an exact integer, then truncating\r
+that and adding 1 returns a result 1 larger than necessary. However, that\r
+can't happen: whenever B is a power of 2, long_from_binary_base() is called\r
+instead, and it's impossible for B**i to be an integer power of 2**15 when B\r
+is not a power of 2 (i.e., it's impossible for N*log(B)/log(PyLong_BASE) to be\r
+an exact integer when B is not a power of 2, since B**i has a prime factor\r
+other than 2 in that case, but (2**15)**j's only prime factor is 2).\r
+\r
+The computed result can be too small if the true value of\r
+N*log(B)/log(PyLong_BASE) is a little bit larger than an exact integer, but\r
+due to roundoff errors (in computing log(B), log(PyLong_BASE), their quotient,\r
+and/or multiplying that by N) yields a numeric result a little less than that\r
+integer. Unfortunately, "how close can a transcendental function get to an\r
+integer over some range?" questions are generally theoretically intractable.\r
+Computer analysis via continued fractions is practical: expand\r
+log(B)/log(PyLong_BASE) via continued fractions, giving a sequence i/j of "the\r
+best" rational approximations. Then j*log(B)/log(PyLong_BASE) is\r
+approximately equal to (the integer) i. This shows that we can get very close\r
+to being in trouble, but very rarely. For example, 76573 is a denominator in\r
+one of the continued-fraction approximations to log(10)/log(2**15), and\r
+indeed:\r
+\r
+ >>> log(10)/log(2**15)*76573\r
+ 16958.000000654003\r
+\r
+is very close to an integer. If we were working with IEEE single-precision,\r
+rounding errors could kill us. Finding worst cases in IEEE double-precision\r
+requires better-than-double-precision log() functions, and Tim didn't bother.\r
+Instead the code checks to see whether the allocated space is enough as each\r
+new Python digit is added, and copies the whole thing to a larger long if not.\r
+This should happen extremely rarely, and in fact I don't have a test case\r
+that triggers it(!). Instead the code was tested by artificially allocating\r
+just 1 digit at the start, so that the copying code was exercised for every\r
+digit beyond the first.\r
+***/\r
+ register twodigits c; /* current input character */\r
+ Py_ssize_t size_z;\r
+ int i;\r
+ int convwidth;\r
+ twodigits convmultmax, convmult;\r
+ digit *pz, *pzstop;\r
+ char* scan;\r
+\r
+ static double log_base_PyLong_BASE[37] = {0.0e0,};\r
+ static int convwidth_base[37] = {0,};\r
+ static twodigits convmultmax_base[37] = {0,};\r
+\r
+ if (log_base_PyLong_BASE[base] == 0.0) {\r
+ twodigits convmax = base;\r
+ int i = 1;\r
+\r
+ log_base_PyLong_BASE[base] = (log((double)base) /\r
+ log((double)PyLong_BASE));\r
+ for (;;) {\r
+ twodigits next = convmax * base;\r
+ if (next > PyLong_BASE)\r
+ break;\r
+ convmax = next;\r
+ ++i;\r
+ }\r
+ convmultmax_base[base] = convmax;\r
+ assert(i > 0);\r
+ convwidth_base[base] = i;\r
+ }\r
+\r
+ /* Find length of the string of numeric characters. */\r
+ scan = str;\r
+ while (_PyLong_DigitValue[Py_CHARMASK(*scan)] < base)\r
+ ++scan;\r
+\r
+ /* Create a long object that can contain the largest possible\r
+ * integer with this base and length. Note that there's no\r
+ * need to initialize z->ob_digit -- no slot is read up before\r
+ * being stored into.\r
+ */\r
+ size_z = (Py_ssize_t)((scan - str) * log_base_PyLong_BASE[base]) + 1;\r
+ /* Uncomment next line to test exceedingly rare copy code */\r
+ /* size_z = 1; */\r
+ assert(size_z > 0);\r
+ z = _PyLong_New(size_z);\r
+ if (z == NULL)\r
+ return NULL;\r
+ Py_SIZE(z) = 0;\r
+\r
+ /* `convwidth` consecutive input digits are treated as a single\r
+ * digit in base `convmultmax`.\r
+ */\r
+ convwidth = convwidth_base[base];\r
+ convmultmax = convmultmax_base[base];\r
+\r
+ /* Work ;-) */\r
+ while (str < scan) {\r
+ /* grab up to convwidth digits from the input string */\r
+ c = (digit)_PyLong_DigitValue[Py_CHARMASK(*str++)];\r
+ for (i = 1; i < convwidth && str != scan; ++i, ++str) {\r
+ c = (twodigits)(c * base +\r
+ _PyLong_DigitValue[Py_CHARMASK(*str)]);\r
+ assert(c < PyLong_BASE);\r
+ }\r
+\r
+ convmult = convmultmax;\r
+ /* Calculate the shift only if we couldn't get\r
+ * convwidth digits.\r
+ */\r
+ if (i != convwidth) {\r
+ convmult = base;\r
+ for ( ; i > 1; --i)\r
+ convmult *= base;\r
+ }\r
+\r
+ /* Multiply z by convmult, and add c. */\r
+ pz = z->ob_digit;\r
+ pzstop = pz + Py_SIZE(z);\r
+ for (; pz < pzstop; ++pz) {\r
+ c += (twodigits)*pz * convmult;\r
+ *pz = (digit)(c & PyLong_MASK);\r
+ c >>= PyLong_SHIFT;\r
+ }\r
+ /* carry off the current end? */\r
+ if (c) {\r
+ assert(c < PyLong_BASE);\r
+ if (Py_SIZE(z) < size_z) {\r
+ *pz = (digit)c;\r
+ ++Py_SIZE(z);\r
+ }\r
+ else {\r
+ PyLongObject *tmp;\r
+ /* Extremely rare. Get more space. */\r
+ assert(Py_SIZE(z) == size_z);\r
+ tmp = _PyLong_New(size_z + 1);\r
+ if (tmp == NULL) {\r
+ Py_DECREF(z);\r
+ return NULL;\r
+ }\r
+ memcpy(tmp->ob_digit,\r
+ z->ob_digit,\r
+ sizeof(digit) * size_z);\r
+ Py_DECREF(z);\r
+ z = tmp;\r
+ z->ob_digit[size_z] = (digit)c;\r
+ ++size_z;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ if (z == NULL)\r
+ return NULL;\r
+ if (str == start)\r
+ goto onError;\r
+ if (sign < 0)\r
+ Py_SIZE(z) = -(Py_SIZE(z));\r
+ if (*str == 'L' || *str == 'l')\r
+ str++;\r
+ while (*str && isspace(Py_CHARMASK(*str)))\r
+ str++;\r
+ if (*str != '\0')\r
+ goto onError;\r
+ if (pend)\r
+ *pend = str;\r
+ return (PyObject *) z;\r
+\r
+ onError:\r
+ Py_XDECREF(z);\r
+ slen = strlen(orig_str) < 200 ? strlen(orig_str) : 200;\r
+ strobj = PyString_FromStringAndSize(orig_str, slen);\r
+ if (strobj == NULL)\r
+ return NULL;\r
+ strrepr = PyObject_Repr(strobj);\r
+ Py_DECREF(strobj);\r
+ if (strrepr == NULL)\r
+ return NULL;\r
+ PyErr_Format(PyExc_ValueError,\r
+ "invalid literal for long() with base %d: %s",\r
+ base, PyString_AS_STRING(strrepr));\r
+ Py_DECREF(strrepr);\r
+ return NULL;\r
+}\r
+\r
+#ifdef Py_USING_UNICODE\r
+PyObject *\r
+PyLong_FromUnicode(Py_UNICODE *u, Py_ssize_t length, int base)\r
+{\r
+ PyObject *result;\r
+ char *buffer = (char *)PyMem_MALLOC(length+1);\r
+\r
+ if (buffer == NULL)\r
+ return NULL;\r
+\r
+ if (PyUnicode_EncodeDecimal(u, length, buffer, NULL)) {\r
+ PyMem_FREE(buffer);\r
+ return NULL;\r
+ }\r
+ result = PyLong_FromString(buffer, NULL, base);\r
+ PyMem_FREE(buffer);\r
+ return result;\r
+}\r
+#endif\r
+\r
+/* forward */\r
+static PyLongObject *x_divrem\r
+ (PyLongObject *, PyLongObject *, PyLongObject **);\r
+static PyObject *long_long(PyObject *v);\r
+\r
+/* Long division with remainder, top-level routine */\r
+\r
+static int\r
+long_divrem(PyLongObject *a, PyLongObject *b,\r
+ PyLongObject **pdiv, PyLongObject **prem)\r
+{\r
+ Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b));\r
+ PyLongObject *z;\r
+\r
+ if (size_b == 0) {\r
+ PyErr_SetString(PyExc_ZeroDivisionError,\r
+ "long division or modulo by zero");\r
+ return -1;\r
+ }\r
+ if (size_a < size_b ||\r
+ (size_a == size_b &&\r
+ a->ob_digit[size_a-1] < b->ob_digit[size_b-1])) {\r
+ /* |a| < |b|. */\r
+ *pdiv = _PyLong_New(0);\r
+ if (*pdiv == NULL)\r
+ return -1;\r
+ Py_INCREF(a);\r
+ *prem = (PyLongObject *) a;\r
+ return 0;\r
+ }\r
+ if (size_b == 1) {\r
+ digit rem = 0;\r
+ z = divrem1(a, b->ob_digit[0], &rem);\r
+ if (z == NULL)\r
+ return -1;\r
+ *prem = (PyLongObject *) PyLong_FromLong((long)rem);\r
+ if (*prem == NULL) {\r
+ Py_DECREF(z);\r
+ return -1;\r
+ }\r
+ }\r
+ else {\r
+ z = x_divrem(a, b, prem);\r
+ if (z == NULL)\r
+ return -1;\r
+ }\r
+ /* Set the signs.\r
+ The quotient z has the sign of a*b;\r
+ the remainder r has the sign of a,\r
+ so a = b*z + r. */\r
+ if ((a->ob_size < 0) != (b->ob_size < 0))\r
+ z->ob_size = -(z->ob_size);\r
+ if (a->ob_size < 0 && (*prem)->ob_size != 0)\r
+ (*prem)->ob_size = -((*prem)->ob_size);\r
+ *pdiv = z;\r
+ return 0;\r
+}\r
+\r
+/* Unsigned long division with remainder -- the algorithm. The arguments v1\r
+ and w1 should satisfy 2 <= ABS(Py_SIZE(w1)) <= ABS(Py_SIZE(v1)). */\r
+\r
+static PyLongObject *\r
+x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem)\r
+{\r
+ PyLongObject *v, *w, *a;\r
+ Py_ssize_t i, k, size_v, size_w;\r
+ int d;\r
+ digit wm1, wm2, carry, q, r, vtop, *v0, *vk, *w0, *ak;\r
+ twodigits vv;\r
+ sdigit zhi;\r
+ stwodigits z;\r
+\r
+ /* We follow Knuth [The Art of Computer Programming, Vol. 2 (3rd\r
+ edn.), section 4.3.1, Algorithm D], except that we don't explicitly\r
+ handle the special case when the initial estimate q for a quotient\r
+ digit is >= PyLong_BASE: the max value for q is PyLong_BASE+1, and\r
+ that won't overflow a digit. */\r
+\r
+ /* allocate space; w will also be used to hold the final remainder */\r
+ size_v = ABS(Py_SIZE(v1));\r
+ size_w = ABS(Py_SIZE(w1));\r
+ assert(size_v >= size_w && size_w >= 2); /* Assert checks by div() */\r
+ v = _PyLong_New(size_v+1);\r
+ if (v == NULL) {\r
+ *prem = NULL;\r
+ return NULL;\r
+ }\r
+ w = _PyLong_New(size_w);\r
+ if (w == NULL) {\r
+ Py_DECREF(v);\r
+ *prem = NULL;\r
+ return NULL;\r
+ }\r
+\r
+ /* normalize: shift w1 left so that its top digit is >= PyLong_BASE/2.\r
+ shift v1 left by the same amount. Results go into w and v. */\r
+ d = PyLong_SHIFT - bits_in_digit(w1->ob_digit[size_w-1]);\r
+ carry = v_lshift(w->ob_digit, w1->ob_digit, size_w, d);\r
+ assert(carry == 0);\r
+ carry = v_lshift(v->ob_digit, v1->ob_digit, size_v, d);\r
+ if (carry != 0 || v->ob_digit[size_v-1] >= w->ob_digit[size_w-1]) {\r
+ v->ob_digit[size_v] = carry;\r
+ size_v++;\r
+ }\r
+\r
+ /* Now v->ob_digit[size_v-1] < w->ob_digit[size_w-1], so quotient has\r
+ at most (and usually exactly) k = size_v - size_w digits. */\r
+ k = size_v - size_w;\r
+ assert(k >= 0);\r
+ a = _PyLong_New(k);\r
+ if (a == NULL) {\r
+ Py_DECREF(w);\r
+ Py_DECREF(v);\r
+ *prem = NULL;\r
+ return NULL;\r
+ }\r
+ v0 = v->ob_digit;\r
+ w0 = w->ob_digit;\r
+ wm1 = w0[size_w-1];\r
+ wm2 = w0[size_w-2];\r
+ for (vk = v0+k, ak = a->ob_digit + k; vk-- > v0;) {\r
+ /* inner loop: divide vk[0:size_w+1] by w0[0:size_w], giving\r
+ single-digit quotient q, remainder in vk[0:size_w]. */\r
+\r
+ SIGCHECK({\r
+ Py_DECREF(a);\r
+ Py_DECREF(w);\r
+ Py_DECREF(v);\r
+ *prem = NULL;\r
+ return NULL;\r
+ });\r
+\r
+ /* estimate quotient digit q; may overestimate by 1 (rare) */\r
+ vtop = vk[size_w];\r
+ assert(vtop <= wm1);\r
+ vv = ((twodigits)vtop << PyLong_SHIFT) | vk[size_w-1];\r
+ q = (digit)(vv / wm1);\r
+ r = (digit)(vv - (twodigits)wm1 * q); /* r = vv % wm1 */\r
+ while ((twodigits)wm2 * q > (((twodigits)r << PyLong_SHIFT)\r
+ | vk[size_w-2])) {\r
+ --q;\r
+ r += wm1;\r
+ if (r >= PyLong_BASE)\r
+ break;\r
+ }\r
+ assert(q <= PyLong_BASE);\r
+\r
+ /* subtract q*w0[0:size_w] from vk[0:size_w+1] */\r
+ zhi = 0;\r
+ for (i = 0; i < size_w; ++i) {\r
+ /* invariants: -PyLong_BASE <= -q <= zhi <= 0;\r
+ -PyLong_BASE * q <= z < PyLong_BASE */\r
+ z = (sdigit)vk[i] + zhi -\r
+ (stwodigits)q * (stwodigits)w0[i];\r
+ vk[i] = (digit)z & PyLong_MASK;\r
+ zhi = (sdigit)Py_ARITHMETIC_RIGHT_SHIFT(stwodigits,\r
+ z, PyLong_SHIFT);\r
+ }\r
+\r
+ /* add w back if q was too large (this branch taken rarely) */\r
+ assert((sdigit)vtop + zhi == -1 || (sdigit)vtop + zhi == 0);\r
+ if ((sdigit)vtop + zhi < 0) {\r
+ carry = 0;\r
+ for (i = 0; i < size_w; ++i) {\r
+ carry += vk[i] + w0[i];\r
+ vk[i] = carry & PyLong_MASK;\r
+ carry >>= PyLong_SHIFT;\r
+ }\r
+ --q;\r
+ }\r
+\r
+ /* store quotient digit */\r
+ assert(q < PyLong_BASE);\r
+ *--ak = q;\r
+ }\r
+\r
+ /* unshift remainder; we reuse w to store the result */\r
+ carry = v_rshift(w0, v0, size_w, d);\r
+ assert(carry==0);\r
+ Py_DECREF(v);\r
+\r
+ *prem = long_normalize(w);\r
+ return long_normalize(a);\r
+}\r
+\r
+/* For a nonzero PyLong a, express a in the form x * 2**e, with 0.5 <=\r
+ abs(x) < 1.0 and e >= 0; return x and put e in *e. Here x is\r
+ rounded to DBL_MANT_DIG significant bits using round-half-to-even.\r
+ If a == 0, return 0.0 and set *e = 0. If the resulting exponent\r
+ e is larger than PY_SSIZE_T_MAX, raise OverflowError and return\r
+ -1.0. */\r
+\r
+/* attempt to define 2.0**DBL_MANT_DIG as a compile-time constant */\r
+#if DBL_MANT_DIG == 53\r
+#define EXP2_DBL_MANT_DIG 9007199254740992.0\r
+#else\r
+#define EXP2_DBL_MANT_DIG (ldexp(1.0, DBL_MANT_DIG))\r
+#endif\r
+\r
+double\r
+_PyLong_Frexp(PyLongObject *a, Py_ssize_t *e)\r
+{\r
+ Py_ssize_t a_size, a_bits, shift_digits, shift_bits, x_size;\r
+ /* See below for why x_digits is always large enough. */\r
+ digit rem, x_digits[2 + (DBL_MANT_DIG + 1) / PyLong_SHIFT];\r
+ double dx;\r
+ /* Correction term for round-half-to-even rounding. For a digit x,\r
+ "x + half_even_correction[x & 7]" gives x rounded to the nearest\r
+ multiple of 4, rounding ties to a multiple of 8. */\r
+ static const int half_even_correction[8] = {0, -1, -2, 1, 0, -1, 2, 1};\r
+\r
+ a_size = ABS(Py_SIZE(a));\r
+ if (a_size == 0) {\r
+ /* Special case for 0: significand 0.0, exponent 0. */\r
+ *e = 0;\r
+ return 0.0;\r
+ }\r
+ a_bits = bits_in_digit(a->ob_digit[a_size-1]);\r
+ /* The following is an overflow-free version of the check\r
+ "if ((a_size - 1) * PyLong_SHIFT + a_bits > PY_SSIZE_T_MAX) ..." */\r
+ if (a_size >= (PY_SSIZE_T_MAX - 1) / PyLong_SHIFT + 1 &&\r
+ (a_size > (PY_SSIZE_T_MAX - 1) / PyLong_SHIFT + 1 ||\r
+ a_bits > (PY_SSIZE_T_MAX - 1) % PyLong_SHIFT + 1))\r
+ goto overflow;\r
+ a_bits = (a_size - 1) * PyLong_SHIFT + a_bits;\r
+\r
+ /* Shift the first DBL_MANT_DIG + 2 bits of a into x_digits[0:x_size]\r
+ (shifting left if a_bits <= DBL_MANT_DIG + 2).\r
+\r
+ Number of digits needed for result: write // for floor division.\r
+ Then if shifting left, we end up using\r
+\r
+ 1 + a_size + (DBL_MANT_DIG + 2 - a_bits) // PyLong_SHIFT\r
+\r
+ digits. If shifting right, we use\r
+\r
+ a_size - (a_bits - DBL_MANT_DIG - 2) // PyLong_SHIFT\r
+\r
+ digits. Using a_size = 1 + (a_bits - 1) // PyLong_SHIFT along with\r
+ the inequalities\r
+\r
+ m // PyLong_SHIFT + n // PyLong_SHIFT <= (m + n) // PyLong_SHIFT\r
+ m // PyLong_SHIFT - n // PyLong_SHIFT <=\r
+ 1 + (m - n - 1) // PyLong_SHIFT,\r
+\r
+ valid for any integers m and n, we find that x_size satisfies\r
+\r
+ x_size <= 2 + (DBL_MANT_DIG + 1) // PyLong_SHIFT\r
+\r
+ in both cases.\r
+ */\r
+ if (a_bits <= DBL_MANT_DIG + 2) {\r
+ shift_digits = (DBL_MANT_DIG + 2 - a_bits) / PyLong_SHIFT;\r
+ shift_bits = (DBL_MANT_DIG + 2 - a_bits) % PyLong_SHIFT;\r
+ x_size = 0;\r
+ while (x_size < shift_digits)\r
+ x_digits[x_size++] = 0;\r
+ rem = v_lshift(x_digits + x_size, a->ob_digit, a_size,\r
+ (int)shift_bits);\r
+ x_size += a_size;\r
+ x_digits[x_size++] = rem;\r
+ }\r
+ else {\r
+ shift_digits = (a_bits - DBL_MANT_DIG - 2) / PyLong_SHIFT;\r
+ shift_bits = (a_bits - DBL_MANT_DIG - 2) % PyLong_SHIFT;\r
+ rem = v_rshift(x_digits, a->ob_digit + shift_digits,\r
+ a_size - shift_digits, (int)shift_bits);\r
+ x_size = a_size - shift_digits;\r
+ /* For correct rounding below, we need the least significant\r
+ bit of x to be 'sticky' for this shift: if any of the bits\r
+ shifted out was nonzero, we set the least significant bit\r
+ of x. */\r
+ if (rem)\r
+ x_digits[0] |= 1;\r
+ else\r
+ while (shift_digits > 0)\r
+ if (a->ob_digit[--shift_digits]) {\r
+ x_digits[0] |= 1;\r
+ break;\r
+ }\r
+ }\r
+ assert(1 <= x_size &&\r
+ x_size <= (Py_ssize_t)(sizeof(x_digits)/sizeof(digit)));\r
+\r
+ /* Round, and convert to double. */\r
+ x_digits[0] += half_even_correction[x_digits[0] & 7];\r
+ dx = x_digits[--x_size];\r
+ while (x_size > 0)\r
+ dx = dx * PyLong_BASE + x_digits[--x_size];\r
+\r
+ /* Rescale; make correction if result is 1.0. */\r
+ dx /= 4.0 * EXP2_DBL_MANT_DIG;\r
+ if (dx == 1.0) {\r
+ if (a_bits == PY_SSIZE_T_MAX)\r
+ goto overflow;\r
+ dx = 0.5;\r
+ a_bits += 1;\r
+ }\r
+\r
+ *e = a_bits;\r
+ return Py_SIZE(a) < 0 ? -dx : dx;\r
+\r
+ overflow:\r
+ /* exponent > PY_SSIZE_T_MAX */\r
+ PyErr_SetString(PyExc_OverflowError,\r
+ "huge integer: number of bits overflows a Py_ssize_t");\r
+ *e = 0;\r
+ return -1.0;\r
+}\r
+\r
+/* Get a C double from a long int object. Rounds to the nearest double,\r
+ using the round-half-to-even rule in the case of a tie. */\r
+\r
+double\r
+PyLong_AsDouble(PyObject *v)\r
+{\r
+ Py_ssize_t exponent;\r
+ double x;\r
+\r
+ if (v == NULL || !PyLong_Check(v)) {\r
+ PyErr_BadInternalCall();\r
+ return -1.0;\r
+ }\r
+ x = _PyLong_Frexp((PyLongObject *)v, &exponent);\r
+ if ((x == -1.0 && PyErr_Occurred()) || exponent > DBL_MAX_EXP) {\r
+ PyErr_SetString(PyExc_OverflowError,\r
+ "long int too large to convert to float");\r
+ return -1.0;\r
+ }\r
+ return ldexp(x, (int)exponent);\r
+}\r
+\r
+/* Methods */\r
+\r
+static void\r
+long_dealloc(PyObject *v)\r
+{\r
+ Py_TYPE(v)->tp_free(v);\r
+}\r
+\r
+static PyObject *\r
+long_repr(PyObject *v)\r
+{\r
+ return _PyLong_Format(v, 10, 1, 0);\r
+}\r
+\r
+static PyObject *\r
+long_str(PyObject *v)\r
+{\r
+ return _PyLong_Format(v, 10, 0, 0);\r
+}\r
+\r
+static int\r
+long_compare(PyLongObject *a, PyLongObject *b)\r
+{\r
+ Py_ssize_t sign;\r
+\r
+ if (Py_SIZE(a) != Py_SIZE(b)) {\r
+ sign = Py_SIZE(a) - Py_SIZE(b);\r
+ }\r
+ else {\r
+ Py_ssize_t i = ABS(Py_SIZE(a));\r
+ while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])\r
+ ;\r
+ if (i < 0)\r
+ sign = 0;\r
+ else {\r
+ sign = (sdigit)a->ob_digit[i] - (sdigit)b->ob_digit[i];\r
+ if (Py_SIZE(a) < 0)\r
+ sign = -sign;\r
+ }\r
+ }\r
+ return sign < 0 ? -1 : sign > 0 ? 1 : 0;\r
+}\r
+\r
+static long\r
+long_hash(PyLongObject *v)\r
+{\r
+ unsigned long x;\r
+ Py_ssize_t i;\r
+ int sign;\r
+\r
+ /* This is designed so that Python ints and longs with the\r
+ same value hash to the same value, otherwise comparisons\r
+ of mapping keys will turn out weird */\r
+ i = v->ob_size;\r
+ sign = 1;\r
+ x = 0;\r
+ if (i < 0) {\r
+ sign = -1;\r
+ i = -(i);\r
+ }\r
+ /* The following loop produces a C unsigned long x such that x is\r
+ congruent to the absolute value of v modulo ULONG_MAX. The\r
+ resulting x is nonzero if and only if v is. */\r
+ while (--i >= 0) {\r
+ /* Force a native long #-bits (32 or 64) circular shift */\r
+ x = (x >> (8*SIZEOF_LONG-PyLong_SHIFT)) | (x << PyLong_SHIFT);\r
+ x += v->ob_digit[i];\r
+ /* If the addition above overflowed we compensate by\r
+ incrementing. This preserves the value modulo\r
+ ULONG_MAX. */\r
+ if (x < v->ob_digit[i])\r
+ x++;\r
+ }\r
+ x = x * sign;\r
+ if (x == (unsigned long)-1)\r
+ x = (unsigned long)-2;\r
+ return (long)x;\r
+}\r
+\r
+\r
+/* Add the absolute values of two long integers. */\r
+\r
+static PyLongObject *\r
+x_add(PyLongObject *a, PyLongObject *b)\r
+{\r
+ Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b));\r
+ PyLongObject *z;\r
+ Py_ssize_t i;\r
+ digit carry = 0;\r
+\r
+ /* Ensure a is the larger of the two: */\r
+ if (size_a < size_b) {\r
+ { PyLongObject *temp = a; a = b; b = temp; }\r
+ { Py_ssize_t size_temp = size_a;\r
+ size_a = size_b;\r
+ size_b = size_temp; }\r
+ }\r
+ z = _PyLong_New(size_a+1);\r
+ if (z == NULL)\r
+ return NULL;\r
+ for (i = 0; i < size_b; ++i) {\r
+ carry += a->ob_digit[i] + b->ob_digit[i];\r
+ z->ob_digit[i] = carry & PyLong_MASK;\r
+ carry >>= PyLong_SHIFT;\r
+ }\r
+ for (; i < size_a; ++i) {\r
+ carry += a->ob_digit[i];\r
+ z->ob_digit[i] = carry & PyLong_MASK;\r
+ carry >>= PyLong_SHIFT;\r
+ }\r
+ z->ob_digit[i] = carry;\r
+ return long_normalize(z);\r
+}\r
+\r
+/* Subtract the absolute values of two integers. */\r
+\r
+static PyLongObject *\r
+x_sub(PyLongObject *a, PyLongObject *b)\r
+{\r
+ Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b));\r
+ PyLongObject *z;\r
+ Py_ssize_t i;\r
+ int sign = 1;\r
+ digit borrow = 0;\r
+\r
+ /* Ensure a is the larger of the two: */\r
+ if (size_a < size_b) {\r
+ sign = -1;\r
+ { PyLongObject *temp = a; a = b; b = temp; }\r
+ { Py_ssize_t size_temp = size_a;\r
+ size_a = size_b;\r
+ size_b = size_temp; }\r
+ }\r
+ else if (size_a == size_b) {\r
+ /* Find highest digit where a and b differ: */\r
+ i = size_a;\r
+ while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])\r
+ ;\r
+ if (i < 0)\r
+ return _PyLong_New(0);\r
+ if (a->ob_digit[i] < b->ob_digit[i]) {\r
+ sign = -1;\r
+ { PyLongObject *temp = a; a = b; b = temp; }\r
+ }\r
+ size_a = size_b = i+1;\r
+ }\r
+ z = _PyLong_New(size_a);\r
+ if (z == NULL)\r
+ return NULL;\r
+ for (i = 0; i < size_b; ++i) {\r
+ /* The following assumes unsigned arithmetic\r
+ works module 2**N for some N>PyLong_SHIFT. */\r
+ borrow = a->ob_digit[i] - b->ob_digit[i] - borrow;\r
+ z->ob_digit[i] = borrow & PyLong_MASK;\r
+ borrow >>= PyLong_SHIFT;\r
+ borrow &= 1; /* Keep only one sign bit */\r
+ }\r
+ for (; i < size_a; ++i) {\r
+ borrow = a->ob_digit[i] - borrow;\r
+ z->ob_digit[i] = borrow & PyLong_MASK;\r
+ borrow >>= PyLong_SHIFT;\r
+ borrow &= 1; /* Keep only one sign bit */\r
+ }\r
+ assert(borrow == 0);\r
+ if (sign < 0)\r
+ z->ob_size = -(z->ob_size);\r
+ return long_normalize(z);\r
+}\r
+\r
+static PyObject *\r
+long_add(PyLongObject *v, PyLongObject *w)\r
+{\r
+ PyLongObject *a, *b, *z;\r
+\r
+ CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);\r
+\r
+ if (a->ob_size < 0) {\r
+ if (b->ob_size < 0) {\r
+ z = x_add(a, b);\r
+ if (z != NULL && z->ob_size != 0)\r
+ z->ob_size = -(z->ob_size);\r
+ }\r
+ else\r
+ z = x_sub(b, a);\r
+ }\r
+ else {\r
+ if (b->ob_size < 0)\r
+ z = x_sub(a, b);\r
+ else\r
+ z = x_add(a, b);\r
+ }\r
+ Py_DECREF(a);\r
+ Py_DECREF(b);\r
+ return (PyObject *)z;\r
+}\r
+\r
+static PyObject *\r
+long_sub(PyLongObject *v, PyLongObject *w)\r
+{\r
+ PyLongObject *a, *b, *z;\r
+\r
+ CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);\r
+\r
+ if (a->ob_size < 0) {\r
+ if (b->ob_size < 0)\r
+ z = x_sub(a, b);\r
+ else\r
+ z = x_add(a, b);\r
+ if (z != NULL && z->ob_size != 0)\r
+ z->ob_size = -(z->ob_size);\r
+ }\r
+ else {\r
+ if (b->ob_size < 0)\r
+ z = x_add(a, b);\r
+ else\r
+ z = x_sub(a, b);\r
+ }\r
+ Py_DECREF(a);\r
+ Py_DECREF(b);\r
+ return (PyObject *)z;\r
+}\r
+\r
+/* Grade school multiplication, ignoring the signs.\r
+ * Returns the absolute value of the product, or NULL if error.\r
+ */\r
+static PyLongObject *\r
+x_mul(PyLongObject *a, PyLongObject *b)\r
+{\r
+ PyLongObject *z;\r
+ Py_ssize_t size_a = ABS(Py_SIZE(a));\r
+ Py_ssize_t size_b = ABS(Py_SIZE(b));\r
+ Py_ssize_t i;\r
+\r
+ z = _PyLong_New(size_a + size_b);\r
+ if (z == NULL)\r
+ return NULL;\r
+\r
+ memset(z->ob_digit, 0, Py_SIZE(z) * sizeof(digit));\r
+ if (a == b) {\r
+ /* Efficient squaring per HAC, Algorithm 14.16:\r
+ * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf\r
+ * Gives slightly less than a 2x speedup when a == b,\r
+ * via exploiting that each entry in the multiplication\r
+ * pyramid appears twice (except for the size_a squares).\r
+ */\r
+ for (i = 0; i < size_a; ++i) {\r
+ twodigits carry;\r
+ twodigits f = a->ob_digit[i];\r
+ digit *pz = z->ob_digit + (i << 1);\r
+ digit *pa = a->ob_digit + i + 1;\r
+ digit *paend = a->ob_digit + size_a;\r
+\r
+ SIGCHECK({\r
+ Py_DECREF(z);\r
+ return NULL;\r
+ });\r
+\r
+ carry = *pz + f * f;\r
+ *pz++ = (digit)(carry & PyLong_MASK);\r
+ carry >>= PyLong_SHIFT;\r
+ assert(carry <= PyLong_MASK);\r
+\r
+ /* Now f is added in twice in each column of the\r
+ * pyramid it appears. Same as adding f<<1 once.\r
+ */\r
+ f <<= 1;\r
+ while (pa < paend) {\r
+ carry += *pz + *pa++ * f;\r
+ *pz++ = (digit)(carry & PyLong_MASK);\r
+ carry >>= PyLong_SHIFT;\r
+ assert(carry <= (PyLong_MASK << 1));\r
+ }\r
+ if (carry) {\r
+ carry += *pz;\r
+ *pz++ = (digit)(carry & PyLong_MASK);\r
+ carry >>= PyLong_SHIFT;\r
+ }\r
+ if (carry)\r
+ *pz += (digit)(carry & PyLong_MASK);\r
+ assert((carry >> PyLong_SHIFT) == 0);\r
+ }\r
+ }\r
+ else { /* a is not the same as b -- gradeschool long mult */\r
+ for (i = 0; i < size_a; ++i) {\r
+ twodigits carry = 0;\r
+ twodigits f = a->ob_digit[i];\r
+ digit *pz = z->ob_digit + i;\r
+ digit *pb = b->ob_digit;\r
+ digit *pbend = b->ob_digit + size_b;\r
+\r
+ SIGCHECK({\r
+ Py_DECREF(z);\r
+ return NULL;\r
+ });\r
+\r
+ while (pb < pbend) {\r
+ carry += *pz + *pb++ * f;\r
+ *pz++ = (digit)(carry & PyLong_MASK);\r
+ carry >>= PyLong_SHIFT;\r
+ assert(carry <= PyLong_MASK);\r
+ }\r
+ if (carry)\r
+ *pz += (digit)(carry & PyLong_MASK);\r
+ assert((carry >> PyLong_SHIFT) == 0);\r
+ }\r
+ }\r
+ return long_normalize(z);\r
+}\r
+\r
+/* A helper for Karatsuba multiplication (k_mul).\r
+ Takes a long "n" and an integer "size" representing the place to\r
+ split, and sets low and high such that abs(n) == (high << size) + low,\r
+ viewing the shift as being by digits. The sign bit is ignored, and\r
+ the return values are >= 0.\r
+ Returns 0 on success, -1 on failure.\r
+*/\r
+static int\r
+kmul_split(PyLongObject *n,\r
+ Py_ssize_t size,\r
+ PyLongObject **high,\r
+ PyLongObject **low)\r
+{\r
+ PyLongObject *hi, *lo;\r
+ Py_ssize_t size_lo, size_hi;\r
+ const Py_ssize_t size_n = ABS(Py_SIZE(n));\r
+\r
+ size_lo = MIN(size_n, size);\r
+ size_hi = size_n - size_lo;\r
+\r
+ if ((hi = _PyLong_New(size_hi)) == NULL)\r
+ return -1;\r
+ if ((lo = _PyLong_New(size_lo)) == NULL) {\r
+ Py_DECREF(hi);\r
+ return -1;\r
+ }\r
+\r
+ memcpy(lo->ob_digit, n->ob_digit, size_lo * sizeof(digit));\r
+ memcpy(hi->ob_digit, n->ob_digit + size_lo, size_hi * sizeof(digit));\r
+\r
+ *high = long_normalize(hi);\r
+ *low = long_normalize(lo);\r
+ return 0;\r
+}\r
+\r
+static PyLongObject *k_lopsided_mul(PyLongObject *a, PyLongObject *b);\r
+\r
+/* Karatsuba multiplication. Ignores the input signs, and returns the\r
+ * absolute value of the product (or NULL if error).\r
+ * See Knuth Vol. 2 Chapter 4.3.3 (Pp. 294-295).\r
+ */\r
+static PyLongObject *\r
+k_mul(PyLongObject *a, PyLongObject *b)\r
+{\r
+ Py_ssize_t asize = ABS(Py_SIZE(a));\r
+ Py_ssize_t bsize = ABS(Py_SIZE(b));\r
+ PyLongObject *ah = NULL;\r
+ PyLongObject *al = NULL;\r
+ PyLongObject *bh = NULL;\r
+ PyLongObject *bl = NULL;\r
+ PyLongObject *ret = NULL;\r
+ PyLongObject *t1, *t2, *t3;\r
+ Py_ssize_t shift; /* the number of digits we split off */\r
+ Py_ssize_t i;\r
+\r
+ /* (ah*X+al)(bh*X+bl) = ah*bh*X*X + (ah*bl + al*bh)*X + al*bl\r
+ * Let k = (ah+al)*(bh+bl) = ah*bl + al*bh + ah*bh + al*bl\r
+ * Then the original product is\r
+ * ah*bh*X*X + (k - ah*bh - al*bl)*X + al*bl\r
+ * By picking X to be a power of 2, "*X" is just shifting, and it's\r
+ * been reduced to 3 multiplies on numbers half the size.\r
+ */\r
+\r
+ /* We want to split based on the larger number; fiddle so that b\r
+ * is largest.\r
+ */\r
+ if (asize > bsize) {\r
+ t1 = a;\r
+ a = b;\r
+ b = t1;\r
+\r
+ i = asize;\r
+ asize = bsize;\r
+ bsize = i;\r
+ }\r
+\r
+ /* Use gradeschool math when either number is too small. */\r
+ i = a == b ? KARATSUBA_SQUARE_CUTOFF : KARATSUBA_CUTOFF;\r
+ if (asize <= i) {\r
+ if (asize == 0)\r
+ return _PyLong_New(0);\r
+ else\r
+ return x_mul(a, b);\r
+ }\r
+\r
+ /* If a is small compared to b, splitting on b gives a degenerate\r
+ * case with ah==0, and Karatsuba may be (even much) less efficient\r
+ * than "grade school" then. However, we can still win, by viewing\r
+ * b as a string of "big digits", each of width a->ob_size. That\r
+ * leads to a sequence of balanced calls to k_mul.\r
+ */\r
+ if (2 * asize <= bsize)\r
+ return k_lopsided_mul(a, b);\r
+\r
+ /* Split a & b into hi & lo pieces. */\r
+ shift = bsize >> 1;\r
+ if (kmul_split(a, shift, &ah, &al) < 0) goto fail;\r
+ assert(Py_SIZE(ah) > 0); /* the split isn't degenerate */\r
+\r
+ if (a == b) {\r
+ bh = ah;\r
+ bl = al;\r
+ Py_INCREF(bh);\r
+ Py_INCREF(bl);\r
+ }\r
+ else if (kmul_split(b, shift, &bh, &bl) < 0) goto fail;\r
+\r
+ /* The plan:\r
+ * 1. Allocate result space (asize + bsize digits: that's always\r
+ * enough).\r
+ * 2. Compute ah*bh, and copy into result at 2*shift.\r
+ * 3. Compute al*bl, and copy into result at 0. Note that this\r
+ * can't overlap with #2.\r
+ * 4. Subtract al*bl from the result, starting at shift. This may\r
+ * underflow (borrow out of the high digit), but we don't care:\r
+ * we're effectively doing unsigned arithmetic mod\r
+ * PyLong_BASE**(sizea + sizeb), and so long as the *final* result fits,\r
+ * borrows and carries out of the high digit can be ignored.\r
+ * 5. Subtract ah*bh from the result, starting at shift.\r
+ * 6. Compute (ah+al)*(bh+bl), and add it into the result starting\r
+ * at shift.\r
+ */\r
+\r
+ /* 1. Allocate result space. */\r
+ ret = _PyLong_New(asize + bsize);\r
+ if (ret == NULL) goto fail;\r
+#ifdef Py_DEBUG\r
+ /* Fill with trash, to catch reference to uninitialized digits. */\r
+ memset(ret->ob_digit, 0xDF, Py_SIZE(ret) * sizeof(digit));\r
+#endif\r
+\r
+ /* 2. t1 <- ah*bh, and copy into high digits of result. */\r
+ if ((t1 = k_mul(ah, bh)) == NULL) goto fail;\r
+ assert(Py_SIZE(t1) >= 0);\r
+ assert(2*shift + Py_SIZE(t1) <= Py_SIZE(ret));\r
+ memcpy(ret->ob_digit + 2*shift, t1->ob_digit,\r
+ Py_SIZE(t1) * sizeof(digit));\r
+\r
+ /* Zero-out the digits higher than the ah*bh copy. */\r
+ i = Py_SIZE(ret) - 2*shift - Py_SIZE(t1);\r
+ if (i)\r
+ memset(ret->ob_digit + 2*shift + Py_SIZE(t1), 0,\r
+ i * sizeof(digit));\r
+\r
+ /* 3. t2 <- al*bl, and copy into the low digits. */\r
+ if ((t2 = k_mul(al, bl)) == NULL) {\r
+ Py_DECREF(t1);\r
+ goto fail;\r
+ }\r
+ assert(Py_SIZE(t2) >= 0);\r
+ assert(Py_SIZE(t2) <= 2*shift); /* no overlap with high digits */\r
+ memcpy(ret->ob_digit, t2->ob_digit, Py_SIZE(t2) * sizeof(digit));\r
+\r
+ /* Zero out remaining digits. */\r
+ i = 2*shift - Py_SIZE(t2); /* number of uninitialized digits */\r
+ if (i)\r
+ memset(ret->ob_digit + Py_SIZE(t2), 0, i * sizeof(digit));\r
+\r
+ /* 4 & 5. Subtract ah*bh (t1) and al*bl (t2). We do al*bl first\r
+ * because it's fresher in cache.\r
+ */\r
+ i = Py_SIZE(ret) - shift; /* # digits after shift */\r
+ (void)v_isub(ret->ob_digit + shift, i, t2->ob_digit, Py_SIZE(t2));\r
+ Py_DECREF(t2);\r
+\r
+ (void)v_isub(ret->ob_digit + shift, i, t1->ob_digit, Py_SIZE(t1));\r
+ Py_DECREF(t1);\r
+\r
+ /* 6. t3 <- (ah+al)(bh+bl), and add into result. */\r
+ if ((t1 = x_add(ah, al)) == NULL) goto fail;\r
+ Py_DECREF(ah);\r
+ Py_DECREF(al);\r
+ ah = al = NULL;\r
+\r
+ if (a == b) {\r
+ t2 = t1;\r
+ Py_INCREF(t2);\r
+ }\r
+ else if ((t2 = x_add(bh, bl)) == NULL) {\r
+ Py_DECREF(t1);\r
+ goto fail;\r
+ }\r
+ Py_DECREF(bh);\r
+ Py_DECREF(bl);\r
+ bh = bl = NULL;\r
+\r
+ t3 = k_mul(t1, t2);\r
+ Py_DECREF(t1);\r
+ Py_DECREF(t2);\r
+ if (t3 == NULL) goto fail;\r
+ assert(Py_SIZE(t3) >= 0);\r
+\r
+ /* Add t3. It's not obvious why we can't run out of room here.\r
+ * See the (*) comment after this function.\r
+ */\r
+ (void)v_iadd(ret->ob_digit + shift, i, t3->ob_digit, Py_SIZE(t3));\r
+ Py_DECREF(t3);\r
+\r
+ return long_normalize(ret);\r
+\r
+ fail:\r
+ Py_XDECREF(ret);\r
+ Py_XDECREF(ah);\r
+ Py_XDECREF(al);\r
+ Py_XDECREF(bh);\r
+ Py_XDECREF(bl);\r
+ return NULL;\r
+}\r
+\r
+/* (*) Why adding t3 can't "run out of room" above.\r
+\r
+Let f(x) mean the floor of x and c(x) mean the ceiling of x. Some facts\r
+to start with:\r
+\r
+1. For any integer i, i = c(i/2) + f(i/2). In particular,\r
+ bsize = c(bsize/2) + f(bsize/2).\r
+2. shift = f(bsize/2)\r
+3. asize <= bsize\r
+4. Since we call k_lopsided_mul if asize*2 <= bsize, asize*2 > bsize in this\r
+ routine, so asize > bsize/2 >= f(bsize/2) in this routine.\r
+\r
+We allocated asize + bsize result digits, and add t3 into them at an offset\r
+of shift. This leaves asize+bsize-shift allocated digit positions for t3\r
+to fit into, = (by #1 and #2) asize + f(bsize/2) + c(bsize/2) - f(bsize/2) =\r
+asize + c(bsize/2) available digit positions.\r
+\r
+bh has c(bsize/2) digits, and bl at most f(size/2) digits. So bh+hl has\r
+at most c(bsize/2) digits + 1 bit.\r
+\r
+If asize == bsize, ah has c(bsize/2) digits, else ah has at most f(bsize/2)\r
+digits, and al has at most f(bsize/2) digits in any case. So ah+al has at\r
+most (asize == bsize ? c(bsize/2) : f(bsize/2)) digits + 1 bit.\r
+\r
+The product (ah+al)*(bh+bl) therefore has at most\r
+\r
+ c(bsize/2) + (asize == bsize ? c(bsize/2) : f(bsize/2)) digits + 2 bits\r
+\r
+and we have asize + c(bsize/2) available digit positions. We need to show\r
+this is always enough. An instance of c(bsize/2) cancels out in both, so\r
+the question reduces to whether asize digits is enough to hold\r
+(asize == bsize ? c(bsize/2) : f(bsize/2)) digits + 2 bits. If asize < bsize,\r
+then we're asking whether asize digits >= f(bsize/2) digits + 2 bits. By #4,\r
+asize is at least f(bsize/2)+1 digits, so this in turn reduces to whether 1\r
+digit is enough to hold 2 bits. This is so since PyLong_SHIFT=15 >= 2. If\r
+asize == bsize, then we're asking whether bsize digits is enough to hold\r
+c(bsize/2) digits + 2 bits, or equivalently (by #1) whether f(bsize/2) digits\r
+is enough to hold 2 bits. This is so if bsize >= 2, which holds because\r
+bsize >= KARATSUBA_CUTOFF >= 2.\r
+\r
+Note that since there's always enough room for (ah+al)*(bh+bl), and that's\r
+clearly >= each of ah*bh and al*bl, there's always enough room to subtract\r
+ah*bh and al*bl too.\r
+*/\r
+\r
+/* b has at least twice the digits of a, and a is big enough that Karatsuba\r
+ * would pay off *if* the inputs had balanced sizes. View b as a sequence\r
+ * of slices, each with a->ob_size digits, and multiply the slices by a,\r
+ * one at a time. This gives k_mul balanced inputs to work with, and is\r
+ * also cache-friendly (we compute one double-width slice of the result\r
+ * at a time, then move on, never backtracking except for the helpful\r
+ * single-width slice overlap between successive partial sums).\r
+ */\r
+static PyLongObject *\r
+k_lopsided_mul(PyLongObject *a, PyLongObject *b)\r
+{\r
+ const Py_ssize_t asize = ABS(Py_SIZE(a));\r
+ Py_ssize_t bsize = ABS(Py_SIZE(b));\r
+ Py_ssize_t nbdone; /* # of b digits already multiplied */\r
+ PyLongObject *ret;\r
+ PyLongObject *bslice = NULL;\r
+\r
+ assert(asize > KARATSUBA_CUTOFF);\r
+ assert(2 * asize <= bsize);\r
+\r
+ /* Allocate result space, and zero it out. */\r
+ ret = _PyLong_New(asize + bsize);\r
+ if (ret == NULL)\r
+ return NULL;\r
+ memset(ret->ob_digit, 0, Py_SIZE(ret) * sizeof(digit));\r
+\r
+ /* Successive slices of b are copied into bslice. */\r
+ bslice = _PyLong_New(asize);\r
+ if (bslice == NULL)\r
+ goto fail;\r
+\r
+ nbdone = 0;\r
+ while (bsize > 0) {\r
+ PyLongObject *product;\r
+ const Py_ssize_t nbtouse = MIN(bsize, asize);\r
+\r
+ /* Multiply the next slice of b by a. */\r
+ memcpy(bslice->ob_digit, b->ob_digit + nbdone,\r
+ nbtouse * sizeof(digit));\r
+ Py_SIZE(bslice) = nbtouse;\r
+ product = k_mul(a, bslice);\r
+ if (product == NULL)\r
+ goto fail;\r
+\r
+ /* Add into result. */\r
+ (void)v_iadd(ret->ob_digit + nbdone, Py_SIZE(ret) - nbdone,\r
+ product->ob_digit, Py_SIZE(product));\r
+ Py_DECREF(product);\r
+\r
+ bsize -= nbtouse;\r
+ nbdone += nbtouse;\r
+ }\r
+\r
+ Py_DECREF(bslice);\r
+ return long_normalize(ret);\r
+\r
+ fail:\r
+ Py_DECREF(ret);\r
+ Py_XDECREF(bslice);\r
+ return NULL;\r
+}\r
+\r
+static PyObject *\r
+long_mul(PyLongObject *v, PyLongObject *w)\r
+{\r
+ PyLongObject *a, *b, *z;\r
+\r
+ if (!convert_binop((PyObject *)v, (PyObject *)w, &a, &b)) {\r
+ Py_INCREF(Py_NotImplemented);\r
+ return Py_NotImplemented;\r
+ }\r
+\r
+ z = k_mul(a, b);\r
+ /* Negate if exactly one of the inputs is negative. */\r
+ if (((a->ob_size ^ b->ob_size) < 0) && z)\r
+ z->ob_size = -(z->ob_size);\r
+ Py_DECREF(a);\r
+ Py_DECREF(b);\r
+ return (PyObject *)z;\r
+}\r
+\r
+/* The / and % operators are now defined in terms of divmod().\r
+ The expression a mod b has the value a - b*floor(a/b).\r
+ The long_divrem function gives the remainder after division of\r
+ |a| by |b|, with the sign of a. This is also expressed\r
+ as a - b*trunc(a/b), if trunc truncates towards zero.\r
+ Some examples:\r
+ a b a rem b a mod b\r
+ 13 10 3 3\r
+ -13 10 -3 7\r
+ 13 -10 3 -7\r
+ -13 -10 -3 -3\r
+ So, to get from rem to mod, we have to add b if a and b\r
+ have different signs. We then subtract one from the 'div'\r
+ part of the outcome to keep the invariant intact. */\r
+\r
+/* Compute\r
+ * *pdiv, *pmod = divmod(v, w)\r
+ * NULL can be passed for pdiv or pmod, in which case that part of\r
+ * the result is simply thrown away. The caller owns a reference to\r
+ * each of these it requests (does not pass NULL for).\r
+ */\r
+static int\r
+l_divmod(PyLongObject *v, PyLongObject *w,\r
+ PyLongObject **pdiv, PyLongObject **pmod)\r
+{\r
+ PyLongObject *div, *mod;\r
+\r
+ if (long_divrem(v, w, &div, &mod) < 0)\r
+ return -1;\r
+ if ((Py_SIZE(mod) < 0 && Py_SIZE(w) > 0) ||\r
+ (Py_SIZE(mod) > 0 && Py_SIZE(w) < 0)) {\r
+ PyLongObject *temp;\r
+ PyLongObject *one;\r
+ temp = (PyLongObject *) long_add(mod, w);\r
+ Py_DECREF(mod);\r
+ mod = temp;\r
+ if (mod == NULL) {\r
+ Py_DECREF(div);\r
+ return -1;\r
+ }\r
+ one = (PyLongObject *) PyLong_FromLong(1L);\r
+ if (one == NULL ||\r
+ (temp = (PyLongObject *) long_sub(div, one)) == NULL) {\r
+ Py_DECREF(mod);\r
+ Py_DECREF(div);\r
+ Py_XDECREF(one);\r
+ return -1;\r
+ }\r
+ Py_DECREF(one);\r
+ Py_DECREF(div);\r
+ div = temp;\r
+ }\r
+ if (pdiv != NULL)\r
+ *pdiv = div;\r
+ else\r
+ Py_DECREF(div);\r
+\r
+ if (pmod != NULL)\r
+ *pmod = mod;\r
+ else\r
+ Py_DECREF(mod);\r
+\r
+ return 0;\r
+}\r
+\r
+static PyObject *\r
+long_div(PyObject *v, PyObject *w)\r
+{\r
+ PyLongObject *a, *b, *div;\r
+\r
+ CONVERT_BINOP(v, w, &a, &b);\r
+ if (l_divmod(a, b, &div, NULL) < 0)\r
+ div = NULL;\r
+ Py_DECREF(a);\r
+ Py_DECREF(b);\r
+ return (PyObject *)div;\r
+}\r
+\r
+static PyObject *\r
+long_classic_div(PyObject *v, PyObject *w)\r
+{\r
+ PyLongObject *a, *b, *div;\r
+\r
+ CONVERT_BINOP(v, w, &a, &b);\r
+ if (Py_DivisionWarningFlag &&\r
+ PyErr_Warn(PyExc_DeprecationWarning, "classic long division") < 0)\r
+ div = NULL;\r
+ else if (l_divmod(a, b, &div, NULL) < 0)\r
+ div = NULL;\r
+ Py_DECREF(a);\r
+ Py_DECREF(b);\r
+ return (PyObject *)div;\r
+}\r
+\r
+/* PyLong/PyLong -> float, with correctly rounded result. */\r
+\r
+#define MANT_DIG_DIGITS (DBL_MANT_DIG / PyLong_SHIFT)\r
+#define MANT_DIG_BITS (DBL_MANT_DIG % PyLong_SHIFT)\r
+\r
+static PyObject *\r
+long_true_divide(PyObject *v, PyObject *w)\r
+{\r
+ PyLongObject *a, *b, *x;\r
+ Py_ssize_t a_size, b_size, shift, extra_bits, diff, x_size, x_bits;\r
+ digit mask, low;\r
+ int inexact, negate, a_is_small, b_is_small;\r
+ double dx, result;\r
+\r
+ CONVERT_BINOP(v, w, &a, &b);\r
+\r
+ /*\r
+ Method in a nutshell:\r
+\r
+ 0. reduce to case a, b > 0; filter out obvious underflow/overflow\r
+ 1. choose a suitable integer 'shift'\r
+ 2. use integer arithmetic to compute x = floor(2**-shift*a/b)\r
+ 3. adjust x for correct rounding\r
+ 4. convert x to a double dx with the same value\r
+ 5. return ldexp(dx, shift).\r
+\r
+ In more detail:\r
+\r
+ 0. For any a, a/0 raises ZeroDivisionError; for nonzero b, 0/b\r
+ returns either 0.0 or -0.0, depending on the sign of b. For a and\r
+ b both nonzero, ignore signs of a and b, and add the sign back in\r
+ at the end. Now write a_bits and b_bits for the bit lengths of a\r
+ and b respectively (that is, a_bits = 1 + floor(log_2(a)); likewise\r
+ for b). Then\r
+\r
+ 2**(a_bits - b_bits - 1) < a/b < 2**(a_bits - b_bits + 1).\r
+\r
+ So if a_bits - b_bits > DBL_MAX_EXP then a/b > 2**DBL_MAX_EXP and\r
+ so overflows. Similarly, if a_bits - b_bits < DBL_MIN_EXP -\r
+ DBL_MANT_DIG - 1 then a/b underflows to 0. With these cases out of\r
+ the way, we can assume that\r
+\r
+ DBL_MIN_EXP - DBL_MANT_DIG - 1 <= a_bits - b_bits <= DBL_MAX_EXP.\r
+\r
+ 1. The integer 'shift' is chosen so that x has the right number of\r
+ bits for a double, plus two or three extra bits that will be used\r
+ in the rounding decisions. Writing a_bits and b_bits for the\r
+ number of significant bits in a and b respectively, a\r
+ straightforward formula for shift is:\r
+\r
+ shift = a_bits - b_bits - DBL_MANT_DIG - 2\r
+\r
+ This is fine in the usual case, but if a/b is smaller than the\r
+ smallest normal float then it can lead to double rounding on an\r
+ IEEE 754 platform, giving incorrectly rounded results. So we\r
+ adjust the formula slightly. The actual formula used is:\r
+\r
+ shift = MAX(a_bits - b_bits, DBL_MIN_EXP) - DBL_MANT_DIG - 2\r
+\r
+ 2. The quantity x is computed by first shifting a (left -shift bits\r
+ if shift <= 0, right shift bits if shift > 0) and then dividing by\r
+ b. For both the shift and the division, we keep track of whether\r
+ the result is inexact, in a flag 'inexact'; this information is\r
+ needed at the rounding stage.\r
+\r
+ With the choice of shift above, together with our assumption that\r
+ a_bits - b_bits >= DBL_MIN_EXP - DBL_MANT_DIG - 1, it follows\r
+ that x >= 1.\r
+\r
+ 3. Now x * 2**shift <= a/b < (x+1) * 2**shift. We want to replace\r
+ this with an exactly representable float of the form\r
+\r
+ round(x/2**extra_bits) * 2**(extra_bits+shift).\r
+\r
+ For float representability, we need x/2**extra_bits <\r
+ 2**DBL_MANT_DIG and extra_bits + shift >= DBL_MIN_EXP -\r
+ DBL_MANT_DIG. This translates to the condition:\r
+\r
+ extra_bits >= MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG\r
+\r
+ To round, we just modify the bottom digit of x in-place; this can\r
+ end up giving a digit with value > PyLONG_MASK, but that's not a\r
+ problem since digits can hold values up to 2*PyLONG_MASK+1.\r
+\r
+ With the original choices for shift above, extra_bits will always\r
+ be 2 or 3. Then rounding under the round-half-to-even rule, we\r
+ round up iff the most significant of the extra bits is 1, and\r
+ either: (a) the computation of x in step 2 had an inexact result,\r
+ or (b) at least one other of the extra bits is 1, or (c) the least\r
+ significant bit of x (above those to be rounded) is 1.\r
+\r
+ 4. Conversion to a double is straightforward; all floating-point\r
+ operations involved in the conversion are exact, so there's no\r
+ danger of rounding errors.\r
+\r
+ 5. Use ldexp(x, shift) to compute x*2**shift, the final result.\r
+ The result will always be exactly representable as a double, except\r
+ in the case that it overflows. To avoid dependence on the exact\r
+ behaviour of ldexp on overflow, we check for overflow before\r
+ applying ldexp. The result of ldexp is adjusted for sign before\r
+ returning.\r
+ */\r
+\r
+ /* Reduce to case where a and b are both positive. */\r
+ a_size = ABS(Py_SIZE(a));\r
+ b_size = ABS(Py_SIZE(b));\r
+ negate = (Py_SIZE(a) < 0) ^ (Py_SIZE(b) < 0);\r
+ if (b_size == 0) {\r
+ PyErr_SetString(PyExc_ZeroDivisionError,\r
+ "division by zero");\r
+ goto error;\r
+ }\r
+ if (a_size == 0)\r
+ goto underflow_or_zero;\r
+\r
+ /* Fast path for a and b small (exactly representable in a double).\r
+ Relies on floating-point division being correctly rounded; results\r
+ may be subject to double rounding on x86 machines that operate with\r
+ the x87 FPU set to 64-bit precision. */\r
+ a_is_small = a_size <= MANT_DIG_DIGITS ||\r
+ (a_size == MANT_DIG_DIGITS+1 &&\r
+ a->ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0);\r
+ b_is_small = b_size <= MANT_DIG_DIGITS ||\r
+ (b_size == MANT_DIG_DIGITS+1 &&\r
+ b->ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0);\r
+ if (a_is_small && b_is_small) {\r
+ double da, db;\r
+ da = a->ob_digit[--a_size];\r
+ while (a_size > 0)\r
+ da = da * PyLong_BASE + a->ob_digit[--a_size];\r
+ db = b->ob_digit[--b_size];\r
+ while (b_size > 0)\r
+ db = db * PyLong_BASE + b->ob_digit[--b_size];\r
+ result = da / db;\r
+ goto success;\r
+ }\r
+\r
+ /* Catch obvious cases of underflow and overflow */\r
+ diff = a_size - b_size;\r
+ if (diff > PY_SSIZE_T_MAX/PyLong_SHIFT - 1)\r
+ /* Extreme overflow */\r
+ goto overflow;\r
+ else if (diff < 1 - PY_SSIZE_T_MAX/PyLong_SHIFT)\r
+ /* Extreme underflow */\r
+ goto underflow_or_zero;\r
+ /* Next line is now safe from overflowing a Py_ssize_t */\r
+ diff = diff * PyLong_SHIFT + bits_in_digit(a->ob_digit[a_size - 1]) -\r
+ bits_in_digit(b->ob_digit[b_size - 1]);\r
+ /* Now diff = a_bits - b_bits. */\r
+ if (diff > DBL_MAX_EXP)\r
+ goto overflow;\r
+ else if (diff < DBL_MIN_EXP - DBL_MANT_DIG - 1)\r
+ goto underflow_or_zero;\r
+\r
+ /* Choose value for shift; see comments for step 1 above. */\r
+ shift = MAX(diff, DBL_MIN_EXP) - DBL_MANT_DIG - 2;\r
+\r
+ inexact = 0;\r
+\r
+ /* x = abs(a * 2**-shift) */\r
+ if (shift <= 0) {\r
+ Py_ssize_t i, shift_digits = -shift / PyLong_SHIFT;\r
+ digit rem;\r
+ /* x = a << -shift */\r
+ if (a_size >= PY_SSIZE_T_MAX - 1 - shift_digits) {\r
+ /* In practice, it's probably impossible to end up\r
+ here. Both a and b would have to be enormous,\r
+ using close to SIZE_T_MAX bytes of memory each. */\r
+ PyErr_SetString(PyExc_OverflowError,\r
+ "intermediate overflow during division");\r
+ goto error;\r
+ }\r
+ x = _PyLong_New(a_size + shift_digits + 1);\r
+ if (x == NULL)\r
+ goto error;\r
+ for (i = 0; i < shift_digits; i++)\r
+ x->ob_digit[i] = 0;\r
+ rem = v_lshift(x->ob_digit + shift_digits, a->ob_digit,\r
+ a_size, -shift % PyLong_SHIFT);\r
+ x->ob_digit[a_size + shift_digits] = rem;\r
+ }\r
+ else {\r
+ Py_ssize_t shift_digits = shift / PyLong_SHIFT;\r
+ digit rem;\r
+ /* x = a >> shift */\r
+ assert(a_size >= shift_digits);\r
+ x = _PyLong_New(a_size - shift_digits);\r
+ if (x == NULL)\r
+ goto error;\r
+ rem = v_rshift(x->ob_digit, a->ob_digit + shift_digits,\r
+ a_size - shift_digits, shift % PyLong_SHIFT);\r
+ /* set inexact if any of the bits shifted out is nonzero */\r
+ if (rem)\r
+ inexact = 1;\r
+ while (!inexact && shift_digits > 0)\r
+ if (a->ob_digit[--shift_digits])\r
+ inexact = 1;\r
+ }\r
+ long_normalize(x);\r
+ x_size = Py_SIZE(x);\r
+\r
+ /* x //= b. If the remainder is nonzero, set inexact. We own the only\r
+ reference to x, so it's safe to modify it in-place. */\r
+ if (b_size == 1) {\r
+ digit rem = inplace_divrem1(x->ob_digit, x->ob_digit, x_size,\r
+ b->ob_digit[0]);\r
+ long_normalize(x);\r
+ if (rem)\r
+ inexact = 1;\r
+ }\r
+ else {\r
+ PyLongObject *div, *rem;\r
+ div = x_divrem(x, b, &rem);\r
+ Py_DECREF(x);\r
+ x = div;\r
+ if (x == NULL)\r
+ goto error;\r
+ if (Py_SIZE(rem))\r
+ inexact = 1;\r
+ Py_DECREF(rem);\r
+ }\r
+ x_size = ABS(Py_SIZE(x));\r
+ assert(x_size > 0); /* result of division is never zero */\r
+ x_bits = (x_size-1)*PyLong_SHIFT+bits_in_digit(x->ob_digit[x_size-1]);\r
+\r
+ /* The number of extra bits that have to be rounded away. */\r
+ extra_bits = MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG;\r
+ assert(extra_bits == 2 || extra_bits == 3);\r
+\r
+ /* Round by directly modifying the low digit of x. */\r
+ mask = (digit)1 << (extra_bits - 1);\r
+ low = x->ob_digit[0] | inexact;\r
+ if (low & mask && low & (3*mask-1))\r
+ low += mask;\r
+ x->ob_digit[0] = low & ~(mask-1U);\r
+\r
+ /* Convert x to a double dx; the conversion is exact. */\r
+ dx = x->ob_digit[--x_size];\r
+ while (x_size > 0)\r
+ dx = dx * PyLong_BASE + x->ob_digit[--x_size];\r
+ Py_DECREF(x);\r
+\r
+ /* Check whether ldexp result will overflow a double. */\r
+ if (shift + x_bits >= DBL_MAX_EXP &&\r
+ (shift + x_bits > DBL_MAX_EXP || dx == ldexp(1.0, (int)x_bits)))\r
+ goto overflow;\r
+ result = ldexp(dx, (int)shift);\r
+\r
+ success:\r
+ Py_DECREF(a);\r
+ Py_DECREF(b);\r
+ return PyFloat_FromDouble(negate ? -result : result);\r
+\r
+ underflow_or_zero:\r
+ Py_DECREF(a);\r
+ Py_DECREF(b);\r
+ return PyFloat_FromDouble(negate ? -0.0 : 0.0);\r
+\r
+ overflow:\r
+ PyErr_SetString(PyExc_OverflowError,\r
+ "integer division result too large for a float");\r
+ error:\r
+ Py_DECREF(a);\r
+ Py_DECREF(b);\r
+ return NULL;\r
+}\r
+\r
+static PyObject *\r
+long_mod(PyObject *v, PyObject *w)\r
+{\r
+ PyLongObject *a, *b, *mod;\r
+\r
+ CONVERT_BINOP(v, w, &a, &b);\r
+\r
+ if (l_divmod(a, b, NULL, &mod) < 0)\r
+ mod = NULL;\r
+ Py_DECREF(a);\r
+ Py_DECREF(b);\r
+ return (PyObject *)mod;\r
+}\r
+\r
+static PyObject *\r
+long_divmod(PyObject *v, PyObject *w)\r
+{\r
+ PyLongObject *a, *b, *div, *mod;\r
+ PyObject *z;\r
+\r
+ CONVERT_BINOP(v, w, &a, &b);\r
+\r
+ if (l_divmod(a, b, &div, &mod) < 0) {\r
+ Py_DECREF(a);\r
+ Py_DECREF(b);\r
+ return NULL;\r
+ }\r
+ z = PyTuple_New(2);\r
+ if (z != NULL) {\r
+ PyTuple_SetItem(z, 0, (PyObject *) div);\r
+ PyTuple_SetItem(z, 1, (PyObject *) mod);\r
+ }\r
+ else {\r
+ Py_DECREF(div);\r
+ Py_DECREF(mod);\r
+ }\r
+ Py_DECREF(a);\r
+ Py_DECREF(b);\r
+ return z;\r
+}\r
+\r
+/* pow(v, w, x) */\r
+static PyObject *\r
+long_pow(PyObject *v, PyObject *w, PyObject *x)\r
+{\r
+ PyLongObject *a, *b, *c; /* a,b,c = v,w,x */\r
+ int negativeOutput = 0; /* if x<0 return negative output */\r
+\r
+ PyLongObject *z = NULL; /* accumulated result */\r
+ Py_ssize_t i, j, k; /* counters */\r
+ PyLongObject *temp = NULL;\r
+\r
+ /* 5-ary values. If the exponent is large enough, table is\r
+ * precomputed so that table[i] == a**i % c for i in range(32).\r
+ */\r
+ PyLongObject *table[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\r
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};\r
+\r
+ /* a, b, c = v, w, x */\r
+ CONVERT_BINOP(v, w, &a, &b);\r
+ if (PyLong_Check(x)) {\r
+ c = (PyLongObject *)x;\r
+ Py_INCREF(x);\r
+ }\r
+ else if (PyInt_Check(x)) {\r
+ c = (PyLongObject *)PyLong_FromLong(PyInt_AS_LONG(x));\r
+ if (c == NULL)\r
+ goto Error;\r
+ }\r
+ else if (x == Py_None)\r
+ c = NULL;\r
+ else {\r
+ Py_DECREF(a);\r
+ Py_DECREF(b);\r
+ Py_INCREF(Py_NotImplemented);\r
+ return Py_NotImplemented;\r
+ }\r
+\r
+ if (Py_SIZE(b) < 0) { /* if exponent is negative */\r
+ if (c) {\r
+ PyErr_SetString(PyExc_TypeError, "pow() 2nd argument "\r
+ "cannot be negative when 3rd argument specified");\r
+ goto Error;\r
+ }\r
+ else {\r
+ /* else return a float. This works because we know\r
+ that this calls float_pow() which converts its\r
+ arguments to double. */\r
+ Py_DECREF(a);\r
+ Py_DECREF(b);\r
+ return PyFloat_Type.tp_as_number->nb_power(v, w, x);\r
+ }\r
+ }\r
+\r
+ if (c) {\r
+ /* if modulus == 0:\r
+ raise ValueError() */\r
+ if (Py_SIZE(c) == 0) {\r
+ PyErr_SetString(PyExc_ValueError,\r
+ "pow() 3rd argument cannot be 0");\r
+ goto Error;\r
+ }\r
+\r
+ /* if modulus < 0:\r
+ negativeOutput = True\r
+ modulus = -modulus */\r
+ if (Py_SIZE(c) < 0) {\r
+ negativeOutput = 1;\r
+ temp = (PyLongObject *)_PyLong_Copy(c);\r
+ if (temp == NULL)\r
+ goto Error;\r
+ Py_DECREF(c);\r
+ c = temp;\r
+ temp = NULL;\r
+ c->ob_size = - c->ob_size;\r
+ }\r
+\r
+ /* if modulus == 1:\r
+ return 0 */\r
+ if ((Py_SIZE(c) == 1) && (c->ob_digit[0] == 1)) {\r
+ z = (PyLongObject *)PyLong_FromLong(0L);\r
+ goto Done;\r
+ }\r
+\r
+ /* Reduce base by modulus in some cases:\r
+ 1. If base < 0. Forcing the base non-negative makes things easier.\r
+ 2. If base is obviously larger than the modulus. The "small\r
+ exponent" case later can multiply directly by base repeatedly,\r
+ while the "large exponent" case multiplies directly by base 31\r
+ times. It can be unboundedly faster to multiply by\r
+ base % modulus instead.\r
+ We could _always_ do this reduction, but l_divmod() isn't cheap,\r
+ so we only do it when it buys something. */\r
+ if (Py_SIZE(a) < 0 || Py_SIZE(a) > Py_SIZE(c)) {\r
+ if (l_divmod(a, c, NULL, &temp) < 0)\r
+ goto Error;\r
+ Py_DECREF(a);\r
+ a = temp;\r
+ temp = NULL;\r
+ }\r
+ }\r
+\r
+ /* At this point a, b, and c are guaranteed non-negative UNLESS\r
+ c is NULL, in which case a may be negative. */\r
+\r
+ z = (PyLongObject *)PyLong_FromLong(1L);\r
+ if (z == NULL)\r
+ goto Error;\r
+\r
+ /* Perform a modular reduction, X = X % c, but leave X alone if c\r
+ * is NULL.\r
+ */\r
+#define REDUCE(X) \\r
+ do { \\r
+ if (c != NULL) { \\r
+ if (l_divmod(X, c, NULL, &temp) < 0) \\r
+ goto Error; \\r
+ Py_XDECREF(X); \\r
+ X = temp; \\r
+ temp = NULL; \\r
+ } \\r
+ } while(0)\r
+\r
+ /* Multiply two values, then reduce the result:\r
+ result = X*Y % c. If c is NULL, skip the mod. */\r
+#define MULT(X, Y, result) \\r
+ do { \\r
+ temp = (PyLongObject *)long_mul(X, Y); \\r
+ if (temp == NULL) \\r
+ goto Error; \\r
+ Py_XDECREF(result); \\r
+ result = temp; \\r
+ temp = NULL; \\r
+ REDUCE(result); \\r
+ } while(0)\r
+\r
+ if (Py_SIZE(b) <= FIVEARY_CUTOFF) {\r
+ /* Left-to-right binary exponentiation (HAC Algorithm 14.79) */\r
+ /* http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf */\r
+ for (i = Py_SIZE(b) - 1; i >= 0; --i) {\r
+ digit bi = b->ob_digit[i];\r
+\r
+ for (j = (digit)1 << (PyLong_SHIFT-1); j != 0; j >>= 1) {\r
+ MULT(z, z, z);\r
+ if (bi & j)\r
+ MULT(z, a, z);\r
+ }\r
+ }\r
+ }\r
+ else {\r
+ /* Left-to-right 5-ary exponentiation (HAC Algorithm 14.82) */\r
+ Py_INCREF(z); /* still holds 1L */\r
+ table[0] = z;\r
+ for (i = 1; i < 32; ++i)\r
+ MULT(table[i-1], a, table[i]);\r
+\r
+ for (i = Py_SIZE(b) - 1; i >= 0; --i) {\r
+ const digit bi = b->ob_digit[i];\r
+\r
+ for (j = PyLong_SHIFT - 5; j >= 0; j -= 5) {\r
+ const int index = (bi >> j) & 0x1f;\r
+ for (k = 0; k < 5; ++k)\r
+ MULT(z, z, z);\r
+ if (index)\r
+ MULT(z, table[index], z);\r
+ }\r
+ }\r
+ }\r
+\r
+ if (negativeOutput && (Py_SIZE(z) != 0)) {\r
+ temp = (PyLongObject *)long_sub(z, c);\r
+ if (temp == NULL)\r
+ goto Error;\r
+ Py_DECREF(z);\r
+ z = temp;\r
+ temp = NULL;\r
+ }\r
+ goto Done;\r
+\r
+ Error:\r
+ if (z != NULL) {\r
+ Py_DECREF(z);\r
+ z = NULL;\r
+ }\r
+ /* fall through */\r
+ Done:\r
+ if (Py_SIZE(b) > FIVEARY_CUTOFF) {\r
+ for (i = 0; i < 32; ++i)\r
+ Py_XDECREF(table[i]);\r
+ }\r
+ Py_DECREF(a);\r
+ Py_DECREF(b);\r
+ Py_XDECREF(c);\r
+ Py_XDECREF(temp);\r
+ return (PyObject *)z;\r
+}\r
+\r
+static PyObject *\r
+long_invert(PyLongObject *v)\r
+{\r
+ /* Implement ~x as -(x+1) */\r
+ PyLongObject *x;\r
+ PyLongObject *w;\r
+ w = (PyLongObject *)PyLong_FromLong(1L);\r
+ if (w == NULL)\r
+ return NULL;\r
+ x = (PyLongObject *) long_add(v, w);\r
+ Py_DECREF(w);\r
+ if (x == NULL)\r
+ return NULL;\r
+ Py_SIZE(x) = -(Py_SIZE(x));\r
+ return (PyObject *)x;\r
+}\r
+\r
+static PyObject *\r
+long_neg(PyLongObject *v)\r
+{\r
+ PyLongObject *z;\r
+ if (v->ob_size == 0 && PyLong_CheckExact(v)) {\r
+ /* -0 == 0 */\r
+ Py_INCREF(v);\r
+ return (PyObject *) v;\r
+ }\r
+ z = (PyLongObject *)_PyLong_Copy(v);\r
+ if (z != NULL)\r
+ z->ob_size = -(v->ob_size);\r
+ return (PyObject *)z;\r
+}\r
+\r
+static PyObject *\r
+long_abs(PyLongObject *v)\r
+{\r
+ if (v->ob_size < 0)\r
+ return long_neg(v);\r
+ else\r
+ return long_long((PyObject *)v);\r
+}\r
+\r
+static int\r
+long_nonzero(PyLongObject *v)\r
+{\r
+ return Py_SIZE(v) != 0;\r
+}\r
+\r
+static PyObject *\r
+long_rshift(PyLongObject *v, PyLongObject *w)\r
+{\r
+ PyLongObject *a, *b;\r
+ PyLongObject *z = NULL;\r
+ Py_ssize_t shiftby, newsize, wordshift, loshift, hishift, i, j;\r
+ digit lomask, himask;\r
+\r
+ CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b);\r
+\r
+ if (Py_SIZE(a) < 0) {\r
+ /* Right shifting negative numbers is harder */\r
+ PyLongObject *a1, *a2;\r
+ a1 = (PyLongObject *) long_invert(a);\r
+ if (a1 == NULL)\r
+ goto rshift_error;\r
+ a2 = (PyLongObject *) long_rshift(a1, b);\r
+ Py_DECREF(a1);\r
+ if (a2 == NULL)\r
+ goto rshift_error;\r
+ z = (PyLongObject *) long_invert(a2);\r
+ Py_DECREF(a2);\r
+ }\r
+ else {\r
+ shiftby = PyLong_AsSsize_t((PyObject *)b);\r
+ if (shiftby == -1L && PyErr_Occurred())\r
+ goto rshift_error;\r
+ if (shiftby < 0) {\r
+ PyErr_SetString(PyExc_ValueError,\r
+ "negative shift count");\r
+ goto rshift_error;\r
+ }\r
+ wordshift = shiftby / PyLong_SHIFT;\r
+ newsize = ABS(Py_SIZE(a)) - wordshift;\r
+ if (newsize <= 0) {\r
+ z = _PyLong_New(0);\r
+ Py_DECREF(a);\r
+ Py_DECREF(b);\r
+ return (PyObject *)z;\r
+ }\r
+ loshift = shiftby % PyLong_SHIFT;\r
+ hishift = PyLong_SHIFT - loshift;\r
+ lomask = ((digit)1 << hishift) - 1;\r
+ himask = PyLong_MASK ^ lomask;\r
+ z = _PyLong_New(newsize);\r
+ if (z == NULL)\r
+ goto rshift_error;\r
+ if (Py_SIZE(a) < 0)\r
+ Py_SIZE(z) = -(Py_SIZE(z));\r
+ for (i = 0, j = wordshift; i < newsize; i++, j++) {\r
+ z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask;\r
+ if (i+1 < newsize)\r
+ z->ob_digit[i] |= (a->ob_digit[j+1] << hishift) & himask;\r
+ }\r
+ z = long_normalize(z);\r
+ }\r
+ rshift_error:\r
+ Py_DECREF(a);\r
+ Py_DECREF(b);\r
+ return (PyObject *) z;\r
+\r
+}\r
+\r
+static PyObject *\r
+long_lshift(PyObject *v, PyObject *w)\r
+{\r
+ /* This version due to Tim Peters */\r
+ PyLongObject *a, *b;\r
+ PyLongObject *z = NULL;\r
+ Py_ssize_t shiftby, oldsize, newsize, wordshift, remshift, i, j;\r
+ twodigits accum;\r
+\r
+ CONVERT_BINOP(v, w, &a, &b);\r
+\r
+ shiftby = PyLong_AsSsize_t((PyObject *)b);\r
+ if (shiftby == -1L && PyErr_Occurred())\r
+ goto lshift_error;\r
+ if (shiftby < 0) {\r
+ PyErr_SetString(PyExc_ValueError, "negative shift count");\r
+ goto lshift_error;\r
+ }\r
+ /* wordshift, remshift = divmod(shiftby, PyLong_SHIFT) */\r
+ wordshift = shiftby / PyLong_SHIFT;\r
+ remshift = shiftby - wordshift * PyLong_SHIFT;\r
+\r
+ oldsize = ABS(a->ob_size);\r
+ newsize = oldsize + wordshift;\r
+ if (remshift)\r
+ ++newsize;\r
+ z = _PyLong_New(newsize);\r
+ if (z == NULL)\r
+ goto lshift_error;\r
+ if (a->ob_size < 0)\r
+ z->ob_size = -(z->ob_size);\r
+ for (i = 0; i < wordshift; i++)\r
+ z->ob_digit[i] = 0;\r
+ accum = 0;\r
+ for (i = wordshift, j = 0; j < oldsize; i++, j++) {\r
+ accum |= (twodigits)a->ob_digit[j] << remshift;\r
+ z->ob_digit[i] = (digit)(accum & PyLong_MASK);\r
+ accum >>= PyLong_SHIFT;\r
+ }\r
+ if (remshift)\r
+ z->ob_digit[newsize-1] = (digit)accum;\r
+ else\r
+ assert(!accum);\r
+ z = long_normalize(z);\r
+ lshift_error:\r
+ Py_DECREF(a);\r
+ Py_DECREF(b);\r
+ return (PyObject *) z;\r
+}\r
+\r
+/* Compute two's complement of digit vector a[0:m], writing result to\r
+ z[0:m]. The digit vector a need not be normalized, but should not\r
+ be entirely zero. a and z may point to the same digit vector. */\r
+\r
+static void\r
+v_complement(digit *z, digit *a, Py_ssize_t m)\r
+{\r
+ Py_ssize_t i;\r
+ digit carry = 1;\r
+ for (i = 0; i < m; ++i) {\r
+ carry += a[i] ^ PyLong_MASK;\r
+ z[i] = carry & PyLong_MASK;\r
+ carry >>= PyLong_SHIFT;\r
+ }\r
+ assert(carry == 0);\r
+}\r
+\r
+/* Bitwise and/xor/or operations */\r
+\r
+static PyObject *\r
+long_bitwise(PyLongObject *a,\r
+ int op, /* '&', '|', '^' */\r
+ PyLongObject *b)\r
+{\r
+ int nega, negb, negz;\r
+ Py_ssize_t size_a, size_b, size_z, i;\r
+ PyLongObject *z;\r
+\r
+ /* Bitwise operations for negative numbers operate as though\r
+ on a two's complement representation. So convert arguments\r
+ from sign-magnitude to two's complement, and convert the\r
+ result back to sign-magnitude at the end. */\r
+\r
+ /* If a is negative, replace it by its two's complement. */\r
+ size_a = ABS(Py_SIZE(a));\r
+ nega = Py_SIZE(a) < 0;\r
+ if (nega) {\r
+ z = _PyLong_New(size_a);\r
+ if (z == NULL)\r
+ return NULL;\r
+ v_complement(z->ob_digit, a->ob_digit, size_a);\r
+ a = z;\r
+ }\r
+ else\r
+ /* Keep reference count consistent. */\r
+ Py_INCREF(a);\r
+\r
+ /* Same for b. */\r
+ size_b = ABS(Py_SIZE(b));\r
+ negb = Py_SIZE(b) < 0;\r
+ if (negb) {\r
+ z = _PyLong_New(size_b);\r
+ if (z == NULL) {\r
+ Py_DECREF(a);\r
+ return NULL;\r
+ }\r
+ v_complement(z->ob_digit, b->ob_digit, size_b);\r
+ b = z;\r
+ }\r
+ else\r
+ Py_INCREF(b);\r
+\r
+ /* Swap a and b if necessary to ensure size_a >= size_b. */\r
+ if (size_a < size_b) {\r
+ z = a; a = b; b = z;\r
+ size_z = size_a; size_a = size_b; size_b = size_z;\r
+ negz = nega; nega = negb; negb = negz;\r
+ }\r
+\r
+ /* JRH: The original logic here was to allocate the result value (z)\r
+ as the longer of the two operands. However, there are some cases\r
+ where the result is guaranteed to be shorter than that: AND of two\r
+ positives, OR of two negatives: use the shorter number. AND with\r
+ mixed signs: use the positive number. OR with mixed signs: use the\r
+ negative number.\r
+ */\r
+ switch (op) {\r
+ case '^':\r
+ negz = nega ^ negb;\r
+ size_z = size_a;\r
+ break;\r
+ case '&':\r
+ negz = nega & negb;\r
+ size_z = negb ? size_a : size_b;\r
+ break;\r
+ case '|':\r
+ negz = nega | negb;\r
+ size_z = negb ? size_b : size_a;\r
+ break;\r
+ default:\r
+ PyErr_BadArgument();\r
+ return NULL;\r
+ }\r
+\r
+ /* We allow an extra digit if z is negative, to make sure that\r
+ the final two's complement of z doesn't overflow. */\r
+ z = _PyLong_New(size_z + negz);\r
+ if (z == NULL) {\r
+ Py_DECREF(a);\r
+ Py_DECREF(b);\r
+ return NULL;\r
+ }\r
+\r
+ /* Compute digits for overlap of a and b. */\r
+ switch(op) {\r
+ case '&':\r
+ for (i = 0; i < size_b; ++i)\r
+ z->ob_digit[i] = a->ob_digit[i] & b->ob_digit[i];\r
+ break;\r
+ case '|':\r
+ for (i = 0; i < size_b; ++i)\r
+ z->ob_digit[i] = a->ob_digit[i] | b->ob_digit[i];\r
+ break;\r
+ case '^':\r
+ for (i = 0; i < size_b; ++i)\r
+ z->ob_digit[i] = a->ob_digit[i] ^ b->ob_digit[i];\r
+ break;\r
+ default:\r
+ PyErr_BadArgument();\r
+ return NULL;\r
+ }\r
+\r
+ /* Copy any remaining digits of a, inverting if necessary. */\r
+ if (op == '^' && negb)\r
+ for (; i < size_z; ++i)\r
+ z->ob_digit[i] = a->ob_digit[i] ^ PyLong_MASK;\r
+ else if (i < size_z)\r
+ memcpy(&z->ob_digit[i], &a->ob_digit[i],\r
+ (size_z-i)*sizeof(digit));\r
+\r
+ /* Complement result if negative. */\r
+ if (negz) {\r
+ Py_SIZE(z) = -(Py_SIZE(z));\r
+ z->ob_digit[size_z] = PyLong_MASK;\r
+ v_complement(z->ob_digit, z->ob_digit, size_z+1);\r
+ }\r
+\r
+ Py_DECREF(a);\r
+ Py_DECREF(b);\r
+ return (PyObject *)long_normalize(z);\r
+}\r
+\r
+static PyObject *\r
+long_and(PyObject *v, PyObject *w)\r
+{\r
+ PyLongObject *a, *b;\r
+ PyObject *c;\r
+ CONVERT_BINOP(v, w, &a, &b);\r
+ c = long_bitwise(a, '&', b);\r
+ Py_DECREF(a);\r
+ Py_DECREF(b);\r
+ return c;\r
+}\r
+\r
+static PyObject *\r
+long_xor(PyObject *v, PyObject *w)\r
+{\r
+ PyLongObject *a, *b;\r
+ PyObject *c;\r
+ CONVERT_BINOP(v, w, &a, &b);\r
+ c = long_bitwise(a, '^', b);\r
+ Py_DECREF(a);\r
+ Py_DECREF(b);\r
+ return c;\r
+}\r
+\r
+static PyObject *\r
+long_or(PyObject *v, PyObject *w)\r
+{\r
+ PyLongObject *a, *b;\r
+ PyObject *c;\r
+ CONVERT_BINOP(v, w, &a, &b);\r
+ c = long_bitwise(a, '|', b);\r
+ Py_DECREF(a);\r
+ Py_DECREF(b);\r
+ return c;\r
+}\r
+\r
+static int\r
+long_coerce(PyObject **pv, PyObject **pw)\r
+{\r
+ if (PyInt_Check(*pw)) {\r
+ *pw = PyLong_FromLong(PyInt_AS_LONG(*pw));\r
+ if (*pw == NULL)\r
+ return -1;\r
+ Py_INCREF(*pv);\r
+ return 0;\r
+ }\r
+ else if (PyLong_Check(*pw)) {\r
+ Py_INCREF(*pv);\r
+ Py_INCREF(*pw);\r
+ return 0;\r
+ }\r
+ return 1; /* Can't do it */\r
+}\r
+\r
+static PyObject *\r
+long_long(PyObject *v)\r
+{\r
+ if (PyLong_CheckExact(v))\r
+ Py_INCREF(v);\r
+ else\r
+ v = _PyLong_Copy((PyLongObject *)v);\r
+ return v;\r
+}\r
+\r
+static PyObject *\r
+long_int(PyObject *v)\r
+{\r
+ long x;\r
+ x = PyLong_AsLong(v);\r
+ if (PyErr_Occurred()) {\r
+ if (PyErr_ExceptionMatches(PyExc_OverflowError)) {\r
+ PyErr_Clear();\r
+ if (PyLong_CheckExact(v)) {\r
+ Py_INCREF(v);\r
+ return v;\r
+ }\r
+ else\r
+ return _PyLong_Copy((PyLongObject *)v);\r
+ }\r
+ else\r
+ return NULL;\r
+ }\r
+ return PyInt_FromLong(x);\r
+}\r
+\r
+static PyObject *\r
+long_float(PyObject *v)\r
+{\r
+ double result;\r
+ result = PyLong_AsDouble(v);\r
+ if (result == -1.0 && PyErr_Occurred())\r
+ return NULL;\r
+ return PyFloat_FromDouble(result);\r
+}\r
+\r
+static PyObject *\r
+long_oct(PyObject *v)\r
+{\r
+ return _PyLong_Format(v, 8, 1, 0);\r
+}\r
+\r
+static PyObject *\r
+long_hex(PyObject *v)\r
+{\r
+ return _PyLong_Format(v, 16, 1, 0);\r
+}\r
+\r
+static PyObject *\r
+long_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);\r
+\r
+static PyObject *\r
+long_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
+{\r
+ PyObject *x = NULL;\r
+ int base = -909; /* unlikely! */\r
+ static char *kwlist[] = {"x", "base", 0};\r
+\r
+ if (type != &PyLong_Type)\r
+ return long_subtype_new(type, args, kwds); /* Wimp out */\r
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:long", kwlist,\r
+ &x, &base))\r
+ return NULL;\r
+ if (x == NULL) {\r
+ if (base != -909) {\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "long() missing string argument");\r
+ return NULL;\r
+ }\r
+ return PyLong_FromLong(0L);\r
+ }\r
+ if (base == -909)\r
+ return PyNumber_Long(x);\r
+ else if (PyString_Check(x)) {\r
+ /* Since PyLong_FromString doesn't have a length parameter,\r
+ * check here for possible NULs in the string. */\r
+ char *string = PyString_AS_STRING(x);\r
+ if (strlen(string) != (size_t)PyString_Size(x)) {\r
+ /* create a repr() of the input string,\r
+ * just like PyLong_FromString does. */\r
+ PyObject *srepr;\r
+ srepr = PyObject_Repr(x);\r
+ if (srepr == NULL)\r
+ return NULL;\r
+ PyErr_Format(PyExc_ValueError,\r
+ "invalid literal for long() with base %d: %s",\r
+ base, PyString_AS_STRING(srepr));\r
+ Py_DECREF(srepr);\r
+ return NULL;\r
+ }\r
+ return PyLong_FromString(PyString_AS_STRING(x), NULL, base);\r
+ }\r
+#ifdef Py_USING_UNICODE\r
+ else if (PyUnicode_Check(x))\r
+ return PyLong_FromUnicode(PyUnicode_AS_UNICODE(x),\r
+ PyUnicode_GET_SIZE(x),\r
+ base);\r
+#endif\r
+ else {\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "long() can't convert non-string with explicit base");\r
+ return NULL;\r
+ }\r
+}\r
+\r
+/* Wimpy, slow approach to tp_new calls for subtypes of long:\r
+ first create a regular long from whatever arguments we got,\r
+ then allocate a subtype instance and initialize it from\r
+ the regular long. The regular long is then thrown away.\r
+*/\r
+static PyObject *\r
+long_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
+{\r
+ PyLongObject *tmp, *newobj;\r
+ Py_ssize_t i, n;\r
+\r
+ assert(PyType_IsSubtype(type, &PyLong_Type));\r
+ tmp = (PyLongObject *)long_new(&PyLong_Type, args, kwds);\r
+ if (tmp == NULL)\r
+ return NULL;\r
+ assert(PyLong_CheckExact(tmp));\r
+ n = Py_SIZE(tmp);\r
+ if (n < 0)\r
+ n = -n;\r
+ newobj = (PyLongObject *)type->tp_alloc(type, n);\r
+ if (newobj == NULL) {\r
+ Py_DECREF(tmp);\r
+ return NULL;\r
+ }\r
+ assert(PyLong_Check(newobj));\r
+ Py_SIZE(newobj) = Py_SIZE(tmp);\r
+ for (i = 0; i < n; i++)\r
+ newobj->ob_digit[i] = tmp->ob_digit[i];\r
+ Py_DECREF(tmp);\r
+ return (PyObject *)newobj;\r
+}\r
+\r
+static PyObject *\r
+long_getnewargs(PyLongObject *v)\r
+{\r
+ return Py_BuildValue("(N)", _PyLong_Copy(v));\r
+}\r
+\r
+static PyObject *\r
+long_get0(PyLongObject *v, void *context) {\r
+ return PyLong_FromLong(0L);\r
+}\r
+\r
+static PyObject *\r
+long_get1(PyLongObject *v, void *context) {\r
+ return PyLong_FromLong(1L);\r
+}\r
+\r
+static PyObject *\r
+long__format__(PyObject *self, PyObject *args)\r
+{\r
+ PyObject *format_spec;\r
+\r
+ if (!PyArg_ParseTuple(args, "O:__format__", &format_spec))\r
+ return NULL;\r
+ if (PyBytes_Check(format_spec))\r
+ return _PyLong_FormatAdvanced(self,\r
+ PyBytes_AS_STRING(format_spec),\r
+ PyBytes_GET_SIZE(format_spec));\r
+ if (PyUnicode_Check(format_spec)) {\r
+ /* Convert format_spec to a str */\r
+ PyObject *result;\r
+ PyObject *str_spec = PyObject_Str(format_spec);\r
+\r
+ if (str_spec == NULL)\r
+ return NULL;\r
+\r
+ result = _PyLong_FormatAdvanced(self,\r
+ PyBytes_AS_STRING(str_spec),\r
+ PyBytes_GET_SIZE(str_spec));\r
+\r
+ Py_DECREF(str_spec);\r
+ return result;\r
+ }\r
+ PyErr_SetString(PyExc_TypeError, "__format__ requires str or unicode");\r
+ return NULL;\r
+}\r
+\r
+static PyObject *\r
+long_sizeof(PyLongObject *v)\r
+{\r
+ Py_ssize_t res;\r
+\r
+ res = v->ob_type->tp_basicsize + ABS(Py_SIZE(v))*sizeof(digit);\r
+ return PyInt_FromSsize_t(res);\r
+}\r
+\r
+static PyObject *\r
+long_bit_length(PyLongObject *v)\r
+{\r
+ PyLongObject *result, *x, *y;\r
+ Py_ssize_t ndigits, msd_bits = 0;\r
+ digit msd;\r
+\r
+ assert(v != NULL);\r
+ assert(PyLong_Check(v));\r
+\r
+ ndigits = ABS(Py_SIZE(v));\r
+ if (ndigits == 0)\r
+ return PyInt_FromLong(0);\r
+\r
+ msd = v->ob_digit[ndigits-1];\r
+ while (msd >= 32) {\r
+ msd_bits += 6;\r
+ msd >>= 6;\r
+ }\r
+ msd_bits += (long)(BitLengthTable[msd]);\r
+\r
+ if (ndigits <= PY_SSIZE_T_MAX/PyLong_SHIFT)\r
+ return PyInt_FromSsize_t((ndigits-1)*PyLong_SHIFT + msd_bits);\r
+\r
+ /* expression above may overflow; use Python integers instead */\r
+ result = (PyLongObject *)PyLong_FromSsize_t(ndigits - 1);\r
+ if (result == NULL)\r
+ return NULL;\r
+ x = (PyLongObject *)PyLong_FromLong(PyLong_SHIFT);\r
+ if (x == NULL)\r
+ goto error;\r
+ y = (PyLongObject *)long_mul(result, x);\r
+ Py_DECREF(x);\r
+ if (y == NULL)\r
+ goto error;\r
+ Py_DECREF(result);\r
+ result = y;\r
+\r
+ x = (PyLongObject *)PyLong_FromLong((long)msd_bits);\r
+ if (x == NULL)\r
+ goto error;\r
+ y = (PyLongObject *)long_add(result, x);\r
+ Py_DECREF(x);\r
+ if (y == NULL)\r
+ goto error;\r
+ Py_DECREF(result);\r
+ result = y;\r
+\r
+ return (PyObject *)result;\r
+\r
+ error:\r
+ Py_DECREF(result);\r
+ return NULL;\r
+}\r
+\r
+PyDoc_STRVAR(long_bit_length_doc,\r
+"long.bit_length() -> int or long\n\\r
+\n\\r
+Number of bits necessary to represent self in binary.\n\\r
+>>> bin(37L)\n\\r
+'0b100101'\n\\r
+>>> (37L).bit_length()\n\\r
+6");\r
+\r
+#if 0\r
+static PyObject *\r
+long_is_finite(PyObject *v)\r
+{\r
+ Py_RETURN_TRUE;\r
+}\r
+#endif\r
+\r
+static PyMethodDef long_methods[] = {\r
+ {"conjugate", (PyCFunction)long_long, METH_NOARGS,\r
+ "Returns self, the complex conjugate of any long."},\r
+ {"bit_length", (PyCFunction)long_bit_length, METH_NOARGS,\r
+ long_bit_length_doc},\r
+#if 0\r
+ {"is_finite", (PyCFunction)long_is_finite, METH_NOARGS,\r
+ "Returns always True."},\r
+#endif\r
+ {"__trunc__", (PyCFunction)long_long, METH_NOARGS,\r
+ "Truncating an Integral returns itself."},\r
+ {"__getnewargs__", (PyCFunction)long_getnewargs, METH_NOARGS},\r
+ {"__format__", (PyCFunction)long__format__, METH_VARARGS},\r
+ {"__sizeof__", (PyCFunction)long_sizeof, METH_NOARGS,\r
+ "Returns size in memory, in bytes"},\r
+ {NULL, NULL} /* sentinel */\r
+};\r
+\r
+static PyGetSetDef long_getset[] = {\r
+ {"real",\r
+ (getter)long_long, (setter)NULL,\r
+ "the real part of a complex number",\r
+ NULL},\r
+ {"imag",\r
+ (getter)long_get0, (setter)NULL,\r
+ "the imaginary part of a complex number",\r
+ NULL},\r
+ {"numerator",\r
+ (getter)long_long, (setter)NULL,\r
+ "the numerator of a rational number in lowest terms",\r
+ NULL},\r
+ {"denominator",\r
+ (getter)long_get1, (setter)NULL,\r
+ "the denominator of a rational number in lowest terms",\r
+ NULL},\r
+ {NULL} /* Sentinel */\r
+};\r
+\r
+PyDoc_STRVAR(long_doc,\r
+"long(x=0) -> long\n\\r
+long(x, base=10) -> long\n\\r
+\n\\r
+Convert a number or string to a long integer, or return 0L if no arguments\n\\r
+are given. If x is floating point, the conversion truncates towards zero.\n\\r
+\n\\r
+If x is not a number or if base is given, then x must be a string or\n\\r
+Unicode object representing an integer literal in the given base. The\n\\r
+literal can be preceded by '+' or '-' and be surrounded by whitespace.\n\\r
+The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to\n\\r
+interpret the base from the string as an integer literal.\n\\r
+>>> int('0b100', base=0)\n\\r
+4L");\r
+\r
+static PyNumberMethods long_as_number = {\r
+ (binaryfunc)long_add, /*nb_add*/\r
+ (binaryfunc)long_sub, /*nb_subtract*/\r
+ (binaryfunc)long_mul, /*nb_multiply*/\r
+ long_classic_div, /*nb_divide*/\r
+ long_mod, /*nb_remainder*/\r
+ long_divmod, /*nb_divmod*/\r
+ long_pow, /*nb_power*/\r
+ (unaryfunc)long_neg, /*nb_negative*/\r
+ (unaryfunc)long_long, /*tp_positive*/\r
+ (unaryfunc)long_abs, /*tp_absolute*/\r
+ (inquiry)long_nonzero, /*tp_nonzero*/\r
+ (unaryfunc)long_invert, /*nb_invert*/\r
+ long_lshift, /*nb_lshift*/\r
+ (binaryfunc)long_rshift, /*nb_rshift*/\r
+ long_and, /*nb_and*/\r
+ long_xor, /*nb_xor*/\r
+ long_or, /*nb_or*/\r
+ long_coerce, /*nb_coerce*/\r
+ long_int, /*nb_int*/\r
+ long_long, /*nb_long*/\r
+ long_float, /*nb_float*/\r
+ long_oct, /*nb_oct*/\r
+ long_hex, /*nb_hex*/\r
+ 0, /* nb_inplace_add */\r
+ 0, /* nb_inplace_subtract */\r
+ 0, /* nb_inplace_multiply */\r
+ 0, /* nb_inplace_divide */\r
+ 0, /* nb_inplace_remainder */\r
+ 0, /* nb_inplace_power */\r
+ 0, /* nb_inplace_lshift */\r
+ 0, /* nb_inplace_rshift */\r
+ 0, /* nb_inplace_and */\r
+ 0, /* nb_inplace_xor */\r
+ 0, /* nb_inplace_or */\r
+ long_div, /* nb_floor_divide */\r
+ long_true_divide, /* nb_true_divide */\r
+ 0, /* nb_inplace_floor_divide */\r
+ 0, /* nb_inplace_true_divide */\r
+ long_long, /* nb_index */\r
+};\r
+\r
+PyTypeObject PyLong_Type = {\r
+ PyObject_HEAD_INIT(&PyType_Type)\r
+ 0, /* ob_size */\r
+ "long", /* tp_name */\r
+ offsetof(PyLongObject, ob_digit), /* tp_basicsize */\r
+ sizeof(digit), /* tp_itemsize */\r
+ long_dealloc, /* tp_dealloc */\r
+ 0, /* tp_print */\r
+ 0, /* tp_getattr */\r
+ 0, /* tp_setattr */\r
+ (cmpfunc)long_compare, /* tp_compare */\r
+ long_repr, /* tp_repr */\r
+ &long_as_number, /* tp_as_number */\r
+ 0, /* tp_as_sequence */\r
+ 0, /* tp_as_mapping */\r
+ (hashfunc)long_hash, /* tp_hash */\r
+ 0, /* tp_call */\r
+ long_str, /* tp_str */\r
+ PyObject_GenericGetAttr, /* tp_getattro */\r
+ 0, /* tp_setattro */\r
+ 0, /* tp_as_buffer */\r
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |\r
+ Py_TPFLAGS_BASETYPE | Py_TPFLAGS_LONG_SUBCLASS, /* tp_flags */\r
+ long_doc, /* tp_doc */\r
+ 0, /* tp_traverse */\r
+ 0, /* tp_clear */\r
+ 0, /* tp_richcompare */\r
+ 0, /* tp_weaklistoffset */\r
+ 0, /* tp_iter */\r
+ 0, /* tp_iternext */\r
+ long_methods, /* tp_methods */\r
+ 0, /* tp_members */\r
+ long_getset, /* tp_getset */\r
+ 0, /* tp_base */\r
+ 0, /* tp_dict */\r
+ 0, /* tp_descr_get */\r
+ 0, /* tp_descr_set */\r
+ 0, /* tp_dictoffset */\r
+ 0, /* tp_init */\r
+ 0, /* tp_alloc */\r
+ long_new, /* tp_new */\r
+ PyObject_Del, /* tp_free */\r
+};\r
+\r
+static PyTypeObject Long_InfoType;\r
+\r
+PyDoc_STRVAR(long_info__doc__,\r
+"sys.long_info\n\\r
+\n\\r
+A struct sequence that holds information about Python's\n\\r
+internal representation of integers. The attributes are read only.");\r
+\r
+static PyStructSequence_Field long_info_fields[] = {\r
+ {"bits_per_digit", "size of a digit in bits"},\r
+ {"sizeof_digit", "size in bytes of the C type used to represent a digit"},\r
+ {NULL, NULL}\r
+};\r
+\r
+static PyStructSequence_Desc long_info_desc = {\r
+ "sys.long_info", /* name */\r
+ long_info__doc__, /* doc */\r
+ long_info_fields, /* fields */\r
+ 2 /* number of fields */\r
+};\r
+\r
+PyObject *\r
+PyLong_GetInfo(void)\r
+{\r
+ PyObject* long_info;\r
+ int field = 0;\r
+ long_info = PyStructSequence_New(&Long_InfoType);\r
+ if (long_info == NULL)\r
+ return NULL;\r
+ PyStructSequence_SET_ITEM(long_info, field++,\r
+ PyInt_FromLong(PyLong_SHIFT));\r
+ PyStructSequence_SET_ITEM(long_info, field++,\r
+ PyInt_FromLong(sizeof(digit)));\r
+ if (PyErr_Occurred()) {\r
+ Py_CLEAR(long_info);\r
+ return NULL;\r
+ }\r
+ return long_info;\r
+}\r
+\r
+int\r
+_PyLong_Init(void)\r
+{\r
+ /* initialize long_info */\r
+ if (Long_InfoType.tp_name == 0)\r
+ PyStructSequence_InitType(&Long_InfoType, &long_info_desc);\r
+ return 1;\r
+}\r
--- /dev/null
+/* stringlib: locale related helpers implementation */\r
+\r
+#ifndef STRINGLIB_LOCALEUTIL_H\r
+#define STRINGLIB_LOCALEUTIL_H\r
+\r
+#include <locale.h>\r
+\r
+#define MAX(x, y) ((x) < (y) ? (y) : (x))\r
+#define MIN(x, y) ((x) < (y) ? (x) : (y))\r
+\r
+typedef struct {\r
+ const char *grouping;\r
+ char previous;\r
+ Py_ssize_t i; /* Where we're currently pointing in grouping. */\r
+} GroupGenerator;\r
+\r
+static void\r
+_GroupGenerator_init(GroupGenerator *self, const char *grouping)\r
+{\r
+ self->grouping = grouping;\r
+ self->i = 0;\r
+ self->previous = 0;\r
+}\r
+\r
+/* Returns the next grouping, or 0 to signify end. */\r
+static Py_ssize_t\r
+_GroupGenerator_next(GroupGenerator *self)\r
+{\r
+ /* Note that we don't really do much error checking here. If a\r
+ grouping string contains just CHAR_MAX, for example, then just\r
+ terminate the generator. That shouldn't happen, but at least we\r
+ fail gracefully. */\r
+ switch (self->grouping[self->i]) {\r
+ case 0:\r
+ return self->previous;\r
+ case CHAR_MAX:\r
+ /* Stop the generator. */\r
+ return 0;\r
+ default: {\r
+ char ch = self->grouping[self->i];\r
+ self->previous = ch;\r
+ self->i++;\r
+ return (Py_ssize_t)ch;\r
+ }\r
+ }\r
+}\r
+\r
+/* Fill in some digits, leading zeros, and thousands separator. All\r
+ are optional, depending on when we're called. */\r
+static void\r
+fill(STRINGLIB_CHAR **digits_end, STRINGLIB_CHAR **buffer_end,\r
+ Py_ssize_t n_chars, Py_ssize_t n_zeros, const char* thousands_sep,\r
+ Py_ssize_t thousands_sep_len)\r
+{\r
+#if STRINGLIB_IS_UNICODE\r
+ Py_ssize_t i;\r
+#endif\r
+\r
+ if (thousands_sep) {\r
+ *buffer_end -= thousands_sep_len;\r
+\r
+ /* Copy the thousands_sep chars into the buffer. */\r
+#if STRINGLIB_IS_UNICODE\r
+ /* Convert from the char's of the thousands_sep from\r
+ the locale into unicode. */\r
+ for (i = 0; i < thousands_sep_len; ++i)\r
+ (*buffer_end)[i] = thousands_sep[i];\r
+#else\r
+ /* No conversion, just memcpy the thousands_sep. */\r
+ memcpy(*buffer_end, thousands_sep, thousands_sep_len);\r
+#endif\r
+ }\r
+\r
+ *buffer_end -= n_chars;\r
+ *digits_end -= n_chars;\r
+ memcpy(*buffer_end, *digits_end, n_chars * sizeof(STRINGLIB_CHAR));\r
+\r
+ *buffer_end -= n_zeros;\r
+ STRINGLIB_FILL(*buffer_end, '0', n_zeros);\r
+}\r
+\r
+/**\r
+ * _Py_InsertThousandsGrouping:\r
+ * @buffer: A pointer to the start of a string.\r
+ * @n_buffer: Number of characters in @buffer.\r
+ * @digits: A pointer to the digits we're reading from. If count\r
+ * is non-NULL, this is unused.\r
+ * @n_digits: The number of digits in the string, in which we want\r
+ * to put the grouping chars.\r
+ * @min_width: The minimum width of the digits in the output string.\r
+ * Output will be zero-padded on the left to fill.\r
+ * @grouping: see definition in localeconv().\r
+ * @thousands_sep: see definition in localeconv().\r
+ *\r
+ * There are 2 modes: counting and filling. If @buffer is NULL,\r
+ * we are in counting mode, else filling mode.\r
+ * If counting, the required buffer size is returned.\r
+ * If filling, we know the buffer will be large enough, so we don't\r
+ * need to pass in the buffer size.\r
+ * Inserts thousand grouping characters (as defined by grouping and\r
+ * thousands_sep) into the string between buffer and buffer+n_digits.\r
+ *\r
+ * Return value: 0 on error, else 1. Note that no error can occur if\r
+ * count is non-NULL.\r
+ *\r
+ * This name won't be used, the includer of this file should define\r
+ * it to be the actual function name, based on unicode or string.\r
+ *\r
+ * As closely as possible, this code mimics the logic in decimal.py's\r
+ _insert_thousands_sep().\r
+ **/\r
+Py_ssize_t\r
+_Py_InsertThousandsGrouping(STRINGLIB_CHAR *buffer,\r
+ Py_ssize_t n_buffer,\r
+ STRINGLIB_CHAR *digits,\r
+ Py_ssize_t n_digits,\r
+ Py_ssize_t min_width,\r
+ const char *grouping,\r
+ const char *thousands_sep)\r
+{\r
+ Py_ssize_t count = 0;\r
+ Py_ssize_t n_zeros;\r
+ int loop_broken = 0;\r
+ int use_separator = 0; /* First time through, don't append the\r
+ separator. They only go between\r
+ groups. */\r
+ STRINGLIB_CHAR *buffer_end = NULL;\r
+ STRINGLIB_CHAR *digits_end = NULL;\r
+ Py_ssize_t l;\r
+ Py_ssize_t n_chars;\r
+ Py_ssize_t thousands_sep_len = strlen(thousands_sep);\r
+ Py_ssize_t remaining = n_digits; /* Number of chars remaining to\r
+ be looked at */\r
+ /* A generator that returns all of the grouping widths, until it\r
+ returns 0. */\r
+ GroupGenerator groupgen;\r
+ _GroupGenerator_init(&groupgen, grouping);\r
+\r
+ if (buffer) {\r
+ buffer_end = buffer + n_buffer;\r
+ digits_end = digits + n_digits;\r
+ }\r
+\r
+ while ((l = _GroupGenerator_next(&groupgen)) > 0) {\r
+ l = MIN(l, MAX(MAX(remaining, min_width), 1));\r
+ n_zeros = MAX(0, l - remaining);\r
+ n_chars = MAX(0, MIN(remaining, l));\r
+\r
+ /* Use n_zero zero's and n_chars chars */\r
+\r
+ /* Count only, don't do anything. */\r
+ count += (use_separator ? thousands_sep_len : 0) + n_zeros + n_chars;\r
+\r
+ if (buffer) {\r
+ /* Copy into the output buffer. */\r
+ fill(&digits_end, &buffer_end, n_chars, n_zeros,\r
+ use_separator ? thousands_sep : NULL, thousands_sep_len);\r
+ }\r
+\r
+ /* Use a separator next time. */\r
+ use_separator = 1;\r
+\r
+ remaining -= n_chars;\r
+ min_width -= l;\r
+\r
+ if (remaining <= 0 && min_width <= 0) {\r
+ loop_broken = 1;\r
+ break;\r
+ }\r
+ min_width -= thousands_sep_len;\r
+ }\r
+ if (!loop_broken) {\r
+ /* We left the loop without using a break statement. */\r
+\r
+ l = MAX(MAX(remaining, min_width), 1);\r
+ n_zeros = MAX(0, l - remaining);\r
+ n_chars = MAX(0, MIN(remaining, l));\r
+\r
+ /* Use n_zero zero's and n_chars chars */\r
+ count += (use_separator ? thousands_sep_len : 0) + n_zeros + n_chars;\r
+ if (buffer) {\r
+ /* Copy into the output buffer. */\r
+ fill(&digits_end, &buffer_end, n_chars, n_zeros,\r
+ use_separator ? thousands_sep : NULL, thousands_sep_len);\r
+ }\r
+ }\r
+ return count;\r
+}\r
+\r
+/**\r
+ * _Py_InsertThousandsGroupingLocale:\r
+ * @buffer: A pointer to the start of a string.\r
+ * @n_digits: The number of digits in the string, in which we want\r
+ * to put the grouping chars.\r
+ *\r
+ * Reads thee current locale and calls _Py_InsertThousandsGrouping().\r
+ **/\r
+Py_ssize_t\r
+_Py_InsertThousandsGroupingLocale(STRINGLIB_CHAR *buffer,\r
+ Py_ssize_t n_buffer,\r
+ STRINGLIB_CHAR *digits,\r
+ Py_ssize_t n_digits,\r
+ Py_ssize_t min_width)\r
+{\r
+ struct lconv *locale_data = localeconv();\r
+ const char *grouping = locale_data->grouping;\r
+ const char *thousands_sep = locale_data->thousands_sep;\r
+\r
+ return _Py_InsertThousandsGrouping(buffer, n_buffer, digits, n_digits,\r
+ min_width, grouping, thousands_sep);\r
+}\r
+#endif /* STRINGLIB_LOCALEUTIL_H */\r
--- /dev/null
+/* Return the copyright string. This is updated manually. */\r
+\r
+#include "Python.h"\r
+\r
+static char cprt[] = \r
+"\\r
+Copyright (c) 2001-2015 Python Software Foundation.\n\\r
+All Rights Reserved.\n\\r
+\n\\r
+Copyright (c) 2000 BeOpen.com.\n\\r
+All Rights Reserved.\n\\r
+\n\\r
+Copyright (c) 1995-2001 Corporation for National Research Initiatives.\n\\r
+All Rights Reserved.\n\\r
+\n\\r
+Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam.\n\\r
+All Rights Reserved.";\r
+\r
+const char *\r
+Py_GetCopyright(void)\r
+{\r
+ return cprt;\r
+}\r
--- /dev/null
+\r
+/* Write Python objects to files and read them back.\r
+ This is intended for writing and reading compiled Python code only;\r
+ a true persistent storage facility would be much harder, since\r
+ it would have to take circular links and sharing into account. */\r
+\r
+#define PY_SSIZE_T_CLEAN\r
+\r
+#include "Python.h"\r
+#include "longintrepr.h"\r
+#include "code.h"\r
+#include "marshal.h"\r
+\r
+#define ABS(x) ((x) < 0 ? -(x) : (x))\r
+\r
+/* High water mark to determine when the marshalled object is dangerously deep\r
+ * and risks coring the interpreter. When the object stack gets this deep,\r
+ * raise an exception instead of continuing.\r
+ */\r
+#define MAX_MARSHAL_STACK_DEPTH 2000\r
+\r
+#define TYPE_NULL '0'\r
+#define TYPE_NONE 'N'\r
+#define TYPE_FALSE 'F'\r
+#define TYPE_TRUE 'T'\r
+#define TYPE_STOPITER 'S'\r
+#define TYPE_ELLIPSIS '.'\r
+#define TYPE_INT 'i'\r
+#define TYPE_INT64 'I'\r
+#define TYPE_FLOAT 'f'\r
+#define TYPE_BINARY_FLOAT 'g'\r
+#define TYPE_COMPLEX 'x'\r
+#define TYPE_BINARY_COMPLEX 'y'\r
+#define TYPE_LONG 'l'\r
+#define TYPE_STRING 's'\r
+#define TYPE_INTERNED 't'\r
+#define TYPE_STRINGREF 'R'\r
+#define TYPE_TUPLE '('\r
+#define TYPE_LIST '['\r
+#define TYPE_DICT '{'\r
+#define TYPE_CODE 'c'\r
+#define TYPE_UNICODE 'u'\r
+#define TYPE_UNKNOWN '?'\r
+#define TYPE_SET '<'\r
+#define TYPE_FROZENSET '>'\r
+\r
+#define WFERR_OK 0\r
+#define WFERR_UNMARSHALLABLE 1\r
+#define WFERR_NESTEDTOODEEP 2\r
+#define WFERR_NOMEMORY 3\r
+\r
+typedef struct {\r
+ FILE *fp;\r
+ int error; /* see WFERR_* values */\r
+ int depth;\r
+ /* If fp == NULL, the following are valid: */\r
+ PyObject *str;\r
+ char *ptr;\r
+ char *end;\r
+ PyObject *strings; /* dict on marshal, list on unmarshal */\r
+ int version;\r
+} WFILE;\r
+\r
+#define w_byte(c, p) if (((p)->fp)) putc((c), (p)->fp); \\r
+ else if ((p)->ptr != (p)->end) *(p)->ptr++ = (c); \\r
+ else w_more(c, p)\r
+\r
+static void\r
+w_more(int c, WFILE *p)\r
+{\r
+ Py_ssize_t size, newsize;\r
+ if (p->str == NULL)\r
+ return; /* An error already occurred */\r
+ size = PyString_Size(p->str);\r
+ newsize = size + size + 1024;\r
+ if (newsize > 32*1024*1024) {\r
+ newsize = size + (size >> 3); /* 12.5% overallocation */\r
+ }\r
+ if (_PyString_Resize(&p->str, newsize) != 0) {\r
+ p->ptr = p->end = NULL;\r
+ }\r
+ else {\r
+ p->ptr = PyString_AS_STRING((PyStringObject *)p->str) + size;\r
+ p->end =\r
+ PyString_AS_STRING((PyStringObject *)p->str) + newsize;\r
+ *p->ptr++ = Py_SAFE_DOWNCAST(c, int, char);\r
+ }\r
+}\r
+\r
+static void\r
+w_string(const char *s, Py_ssize_t n, WFILE *p)\r
+{\r
+ if (p->fp != NULL) {\r
+ fwrite(s, 1, n, p->fp);\r
+ }\r
+ else {\r
+ while (--n >= 0) {\r
+ w_byte(*s, p);\r
+ s++;\r
+ }\r
+ }\r
+}\r
+\r
+static void\r
+w_short(int x, WFILE *p)\r
+{\r
+ w_byte((char)( x & 0xff), p);\r
+ w_byte((char)((x>> 8) & 0xff), p);\r
+}\r
+\r
+static void\r
+w_long(long x, WFILE *p)\r
+{\r
+ w_byte((char)( x & 0xff), p);\r
+ w_byte((char)((x>> 8) & 0xff), p);\r
+ w_byte((char)((x>>16) & 0xff), p);\r
+ w_byte((char)((x>>24) & 0xff), p);\r
+}\r
+\r
+#if SIZEOF_LONG > 4\r
+static void\r
+w_long64(long x, WFILE *p)\r
+{\r
+ w_long(x, p);\r
+ w_long(x>>32, p);\r
+}\r
+#endif\r
+\r
+#define SIZE32_MAX 0x7FFFFFFF\r
+\r
+#if SIZEOF_SIZE_T > 4\r
+# define W_SIZE(n, p) do { \\r
+ if ((n) > SIZE32_MAX) { \\r
+ (p)->depth--; \\r
+ (p)->error = WFERR_UNMARSHALLABLE; \\r
+ return; \\r
+ } \\r
+ w_long((long)(n), p); \\r
+ } while(0)\r
+#else\r
+# define W_SIZE w_long\r
+#endif\r
+\r
+static void\r
+w_pstring(const char *s, Py_ssize_t n, WFILE *p)\r
+{\r
+ W_SIZE(n, p);\r
+ w_string(s, n, p);\r
+}\r
+\r
+/* We assume that Python longs are stored internally in base some power of\r
+ 2**15; for the sake of portability we'll always read and write them in base\r
+ exactly 2**15. */\r
+\r
+#define PyLong_MARSHAL_SHIFT 15\r
+#define PyLong_MARSHAL_BASE ((short)1 << PyLong_MARSHAL_SHIFT)\r
+#define PyLong_MARSHAL_MASK (PyLong_MARSHAL_BASE - 1)\r
+#if PyLong_SHIFT % PyLong_MARSHAL_SHIFT != 0\r
+#error "PyLong_SHIFT must be a multiple of PyLong_MARSHAL_SHIFT"\r
+#endif\r
+#define PyLong_MARSHAL_RATIO (PyLong_SHIFT / PyLong_MARSHAL_SHIFT)\r
+\r
+static void\r
+w_PyLong(const PyLongObject *ob, WFILE *p)\r
+{\r
+ Py_ssize_t i, j, n, l;\r
+ digit d;\r
+\r
+ w_byte(TYPE_LONG, p);\r
+ if (Py_SIZE(ob) == 0) {\r
+ w_long((long)0, p);\r
+ return;\r
+ }\r
+\r
+ /* set l to number of base PyLong_MARSHAL_BASE digits */\r
+ n = ABS(Py_SIZE(ob));\r
+ l = (n-1) * PyLong_MARSHAL_RATIO;\r
+ d = ob->ob_digit[n-1];\r
+ assert(d != 0); /* a PyLong is always normalized */\r
+ do {\r
+ d >>= PyLong_MARSHAL_SHIFT;\r
+ l++;\r
+ } while (d != 0);\r
+ if (l > SIZE32_MAX) {\r
+ p->depth--;\r
+ p->error = WFERR_UNMARSHALLABLE;\r
+ return;\r
+ }\r
+ w_long((long)(Py_SIZE(ob) > 0 ? l : -l), p);\r
+\r
+ for (i=0; i < n-1; i++) {\r
+ d = ob->ob_digit[i];\r
+ for (j=0; j < PyLong_MARSHAL_RATIO; j++) {\r
+ w_short(d & PyLong_MARSHAL_MASK, p);\r
+ d >>= PyLong_MARSHAL_SHIFT;\r
+ }\r
+ assert (d == 0);\r
+ }\r
+ d = ob->ob_digit[n-1];\r
+ do {\r
+ w_short(d & PyLong_MARSHAL_MASK, p);\r
+ d >>= PyLong_MARSHAL_SHIFT;\r
+ } while (d != 0);\r
+}\r
+\r
+static void\r
+w_object(PyObject *v, WFILE *p)\r
+{\r
+ Py_ssize_t i, n;\r
+\r
+ p->depth++;\r
+\r
+ if (p->depth > MAX_MARSHAL_STACK_DEPTH) {\r
+ p->error = WFERR_NESTEDTOODEEP;\r
+ }\r
+ else if (v == NULL) {\r
+ w_byte(TYPE_NULL, p);\r
+ }\r
+ else if (v == Py_None) {\r
+ w_byte(TYPE_NONE, p);\r
+ }\r
+ else if (v == PyExc_StopIteration) {\r
+ w_byte(TYPE_STOPITER, p);\r
+ }\r
+ else if (v == Py_Ellipsis) {\r
+ w_byte(TYPE_ELLIPSIS, p);\r
+ }\r
+ else if (v == Py_False) {\r
+ w_byte(TYPE_FALSE, p);\r
+ }\r
+ else if (v == Py_True) {\r
+ w_byte(TYPE_TRUE, p);\r
+ }\r
+ else if (PyInt_CheckExact(v)) {\r
+ long x = PyInt_AS_LONG((PyIntObject *)v);\r
+#if SIZEOF_LONG > 4\r
+ long y = Py_ARITHMETIC_RIGHT_SHIFT(long, x, 31);\r
+ if (y && y != -1) {\r
+ w_byte(TYPE_INT64, p);\r
+ w_long64(x, p);\r
+ }\r
+ else\r
+#endif\r
+ {\r
+ w_byte(TYPE_INT, p);\r
+ w_long(x, p);\r
+ }\r
+ }\r
+ else if (PyLong_CheckExact(v)) {\r
+ PyLongObject *ob = (PyLongObject *)v;\r
+ w_PyLong(ob, p);\r
+ }\r
+ else if (PyFloat_CheckExact(v)) {\r
+ if (p->version > 1) {\r
+ unsigned char buf[8];\r
+ if (_PyFloat_Pack8(PyFloat_AsDouble(v),\r
+ buf, 1) < 0) {\r
+ p->error = WFERR_UNMARSHALLABLE;\r
+ return;\r
+ }\r
+ w_byte(TYPE_BINARY_FLOAT, p);\r
+ w_string((char*)buf, 8, p);\r
+ }\r
+ else {\r
+ char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v),\r
+ 'g', 17, 0, NULL);\r
+ if (!buf) {\r
+ p->error = WFERR_NOMEMORY;\r
+ return;\r
+ }\r
+ n = strlen(buf);\r
+ w_byte(TYPE_FLOAT, p);\r
+ w_byte((int)n, p);\r
+ w_string(buf, n, p);\r
+ PyMem_Free(buf);\r
+ }\r
+ }\r
+#ifndef WITHOUT_COMPLEX\r
+ else if (PyComplex_CheckExact(v)) {\r
+ if (p->version > 1) {\r
+ unsigned char buf[8];\r
+ if (_PyFloat_Pack8(PyComplex_RealAsDouble(v),\r
+ buf, 1) < 0) {\r
+ p->error = WFERR_UNMARSHALLABLE;\r
+ return;\r
+ }\r
+ w_byte(TYPE_BINARY_COMPLEX, p);\r
+ w_string((char*)buf, 8, p);\r
+ if (_PyFloat_Pack8(PyComplex_ImagAsDouble(v),\r
+ buf, 1) < 0) {\r
+ p->error = WFERR_UNMARSHALLABLE;\r
+ return;\r
+ }\r
+ w_string((char*)buf, 8, p);\r
+ }\r
+ else {\r
+ char *buf;\r
+ w_byte(TYPE_COMPLEX, p);\r
+ buf = PyOS_double_to_string(PyComplex_RealAsDouble(v),\r
+ 'g', 17, 0, NULL);\r
+ if (!buf) {\r
+ p->error = WFERR_NOMEMORY;\r
+ return;\r
+ }\r
+ n = strlen(buf);\r
+ w_byte((int)n, p);\r
+ w_string(buf, n, p);\r
+ PyMem_Free(buf);\r
+ buf = PyOS_double_to_string(PyComplex_ImagAsDouble(v),\r
+ 'g', 17, 0, NULL);\r
+ if (!buf) {\r
+ p->error = WFERR_NOMEMORY;\r
+ return;\r
+ }\r
+ n = strlen(buf);\r
+ w_byte((int)n, p);\r
+ w_string(buf, n, p);\r
+ PyMem_Free(buf);\r
+ }\r
+ }\r
+#endif\r
+ else if (PyString_CheckExact(v)) {\r
+ if (p->strings && PyString_CHECK_INTERNED(v)) {\r
+ PyObject *o = PyDict_GetItem(p->strings, v);\r
+ if (o) {\r
+ long w = PyInt_AsLong(o);\r
+ w_byte(TYPE_STRINGREF, p);\r
+ w_long(w, p);\r
+ goto exit;\r
+ }\r
+ else {\r
+ int ok;\r
+ o = PyInt_FromSsize_t(PyDict_Size(p->strings));\r
+ ok = o &&\r
+ PyDict_SetItem(p->strings, v, o) >= 0;\r
+ Py_XDECREF(o);\r
+ if (!ok) {\r
+ p->depth--;\r
+ p->error = WFERR_UNMARSHALLABLE;\r
+ return;\r
+ }\r
+ w_byte(TYPE_INTERNED, p);\r
+ }\r
+ }\r
+ else {\r
+ w_byte(TYPE_STRING, p);\r
+ }\r
+ w_pstring(PyBytes_AS_STRING(v), PyString_GET_SIZE(v), p);\r
+ }\r
+#ifdef Py_USING_UNICODE\r
+ else if (PyUnicode_CheckExact(v)) {\r
+ PyObject *utf8;\r
+ utf8 = PyUnicode_AsUTF8String(v);\r
+ if (utf8 == NULL) {\r
+ p->depth--;\r
+ p->error = WFERR_UNMARSHALLABLE;\r
+ return;\r
+ }\r
+ w_byte(TYPE_UNICODE, p);\r
+ w_pstring(PyString_AS_STRING(utf8), PyString_GET_SIZE(utf8), p);\r
+ Py_DECREF(utf8);\r
+ }\r
+#endif\r
+ else if (PyTuple_CheckExact(v)) {\r
+ w_byte(TYPE_TUPLE, p);\r
+ n = PyTuple_Size(v);\r
+ W_SIZE(n, p);\r
+ for (i = 0; i < n; i++) {\r
+ w_object(PyTuple_GET_ITEM(v, i), p);\r
+ }\r
+ }\r
+ else if (PyList_CheckExact(v)) {\r
+ w_byte(TYPE_LIST, p);\r
+ n = PyList_GET_SIZE(v);\r
+ W_SIZE(n, p);\r
+ for (i = 0; i < n; i++) {\r
+ w_object(PyList_GET_ITEM(v, i), p);\r
+ }\r
+ }\r
+ else if (PyDict_CheckExact(v)) {\r
+ Py_ssize_t pos;\r
+ PyObject *key, *value;\r
+ w_byte(TYPE_DICT, p);\r
+ /* This one is NULL object terminated! */\r
+ pos = 0;\r
+ while (PyDict_Next(v, &pos, &key, &value)) {\r
+ w_object(key, p);\r
+ w_object(value, p);\r
+ }\r
+ w_object((PyObject *)NULL, p);\r
+ }\r
+ else if (PyAnySet_CheckExact(v)) {\r
+ PyObject *value, *it;\r
+\r
+ if (PyObject_TypeCheck(v, &PySet_Type))\r
+ w_byte(TYPE_SET, p);\r
+ else\r
+ w_byte(TYPE_FROZENSET, p);\r
+ n = PyObject_Size(v);\r
+ if (n == -1) {\r
+ p->depth--;\r
+ p->error = WFERR_UNMARSHALLABLE;\r
+ return;\r
+ }\r
+ W_SIZE(n, p);\r
+ it = PyObject_GetIter(v);\r
+ if (it == NULL) {\r
+ p->depth--;\r
+ p->error = WFERR_UNMARSHALLABLE;\r
+ return;\r
+ }\r
+ while ((value = PyIter_Next(it)) != NULL) {\r
+ w_object(value, p);\r
+ Py_DECREF(value);\r
+ }\r
+ Py_DECREF(it);\r
+ if (PyErr_Occurred()) {\r
+ p->depth--;\r
+ p->error = WFERR_UNMARSHALLABLE;\r
+ return;\r
+ }\r
+ }\r
+ else if (PyCode_Check(v)) {\r
+ PyCodeObject *co = (PyCodeObject *)v;\r
+ w_byte(TYPE_CODE, p);\r
+ w_long(co->co_argcount, p);\r
+ w_long(co->co_nlocals, p);\r
+ w_long(co->co_stacksize, p);\r
+ w_long(co->co_flags, p);\r
+ w_object(co->co_code, p);\r
+ w_object(co->co_consts, p);\r
+ w_object(co->co_names, p);\r
+ w_object(co->co_varnames, p);\r
+ w_object(co->co_freevars, p);\r
+ w_object(co->co_cellvars, p);\r
+ w_object(co->co_filename, p);\r
+ w_object(co->co_name, p);\r
+ w_long(co->co_firstlineno, p);\r
+ w_object(co->co_lnotab, p);\r
+ }\r
+ else if (PyObject_CheckReadBuffer(v)) {\r
+ /* Write unknown buffer-style objects as a string */\r
+ char *s;\r
+ PyBufferProcs *pb = v->ob_type->tp_as_buffer;\r
+ w_byte(TYPE_STRING, p);\r
+ n = (*pb->bf_getreadbuffer)(v, 0, (void **)&s);\r
+ w_pstring(s, n, p);\r
+ }\r
+ else {\r
+ w_byte(TYPE_UNKNOWN, p);\r
+ p->error = WFERR_UNMARSHALLABLE;\r
+ }\r
+ exit:\r
+ p->depth--;\r
+}\r
+\r
+/* version currently has no effect for writing longs. */\r
+void\r
+PyMarshal_WriteLongToFile(long x, FILE *fp, int version)\r
+{\r
+ WFILE wf;\r
+ wf.fp = fp;\r
+ wf.error = WFERR_OK;\r
+ wf.depth = 0;\r
+ wf.strings = NULL;\r
+ wf.version = version;\r
+ w_long(x, &wf);\r
+}\r
+\r
+void\r
+PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version)\r
+{\r
+ WFILE wf;\r
+ wf.fp = fp;\r
+ wf.error = WFERR_OK;\r
+ wf.depth = 0;\r
+ wf.strings = (version > 0) ? PyDict_New() : NULL;\r
+ wf.version = version;\r
+ w_object(x, &wf);\r
+ Py_XDECREF(wf.strings);\r
+}\r
+\r
+typedef WFILE RFILE; /* Same struct with different invariants */\r
+\r
+#define rs_byte(p) (((p)->ptr < (p)->end) ? (unsigned char)*(p)->ptr++ : EOF)\r
+\r
+#define r_byte(p) ((p)->fp ? getc((p)->fp) : rs_byte(p))\r
+\r
+static Py_ssize_t\r
+r_string(char *s, Py_ssize_t n, RFILE *p)\r
+{\r
+ if (p->fp != NULL)\r
+ /* The result fits into int because it must be <=n. */\r
+ return fread(s, 1, n, p->fp);\r
+ if (p->end - p->ptr < n)\r
+ n = p->end - p->ptr;\r
+ memcpy(s, p->ptr, n);\r
+ p->ptr += n;\r
+ return n;\r
+}\r
+\r
+static int\r
+r_short(RFILE *p)\r
+{\r
+ register short x;\r
+ x = r_byte(p);\r
+ x |= r_byte(p) << 8;\r
+ /* Sign-extension, in case short greater than 16 bits */\r
+ x |= -(x & 0x8000);\r
+ return x;\r
+}\r
+\r
+static long\r
+r_long(RFILE *p)\r
+{\r
+ register long x;\r
+ register FILE *fp = p->fp;\r
+ if (fp) {\r
+ x = getc(fp);\r
+ x |= (long)getc(fp) << 8;\r
+ x |= (long)getc(fp) << 16;\r
+ x |= (long)getc(fp) << 24;\r
+ }\r
+ else {\r
+ x = rs_byte(p);\r
+ x |= (long)rs_byte(p) << 8;\r
+ x |= (long)rs_byte(p) << 16;\r
+ x |= (long)rs_byte(p) << 24;\r
+ }\r
+#if SIZEOF_LONG > 4\r
+ /* Sign extension for 64-bit machines */\r
+ x |= -(x & 0x80000000L);\r
+#endif\r
+ return x;\r
+}\r
+\r
+/* r_long64 deals with the TYPE_INT64 code. On a machine with\r
+ sizeof(long) > 4, it returns a Python int object, else a Python long\r
+ object. Note that w_long64 writes out TYPE_INT if 32 bits is enough,\r
+ so there's no inefficiency here in returning a PyLong on 32-bit boxes\r
+ for everything written via TYPE_INT64 (i.e., if an int is written via\r
+ TYPE_INT64, it *needs* more than 32 bits).\r
+*/\r
+static PyObject *\r
+r_long64(RFILE *p)\r
+{\r
+ long lo4 = r_long(p);\r
+ long hi4 = r_long(p);\r
+#if SIZEOF_LONG > 4\r
+ long x = (hi4 << 32) | (lo4 & 0xFFFFFFFFL);\r
+ return PyInt_FromLong(x);\r
+#else\r
+ unsigned char buf[8];\r
+ int one = 1;\r
+ int is_little_endian = (int)*(char*)&one;\r
+ if (is_little_endian) {\r
+ memcpy(buf, &lo4, 4);\r
+ memcpy(buf+4, &hi4, 4);\r
+ }\r
+ else {\r
+ memcpy(buf, &hi4, 4);\r
+ memcpy(buf+4, &lo4, 4);\r
+ }\r
+ return _PyLong_FromByteArray(buf, 8, is_little_endian, 1);\r
+#endif\r
+}\r
+\r
+static PyObject *\r
+r_PyLong(RFILE *p)\r
+{\r
+ PyLongObject *ob;\r
+ long n, size, i;\r
+ int j, md, shorts_in_top_digit;\r
+ digit d;\r
+\r
+ n = r_long(p);\r
+ if (n == 0)\r
+ return (PyObject *)_PyLong_New(0);\r
+ if (n < -SIZE32_MAX || n > SIZE32_MAX) {\r
+ PyErr_SetString(PyExc_ValueError,\r
+ "bad marshal data (long size out of range)");\r
+ return NULL;\r
+ }\r
+\r
+ size = 1 + (ABS(n) - 1) / PyLong_MARSHAL_RATIO;\r
+ shorts_in_top_digit = 1 + (ABS(n) - 1) % PyLong_MARSHAL_RATIO;\r
+ ob = _PyLong_New(size);\r
+ if (ob == NULL)\r
+ return NULL;\r
+ Py_SIZE(ob) = n > 0 ? size : -size;\r
+\r
+ for (i = 0; i < size-1; i++) {\r
+ d = 0;\r
+ for (j=0; j < PyLong_MARSHAL_RATIO; j++) {\r
+ md = r_short(p);\r
+ if (md < 0 || md > PyLong_MARSHAL_BASE)\r
+ goto bad_digit;\r
+ d += (digit)md << j*PyLong_MARSHAL_SHIFT;\r
+ }\r
+ ob->ob_digit[i] = d;\r
+ }\r
+ d = 0;\r
+ for (j=0; j < shorts_in_top_digit; j++) {\r
+ md = r_short(p);\r
+ if (md < 0 || md > PyLong_MARSHAL_BASE)\r
+ goto bad_digit;\r
+ /* topmost marshal digit should be nonzero */\r
+ if (md == 0 && j == shorts_in_top_digit - 1) {\r
+ Py_DECREF(ob);\r
+ PyErr_SetString(PyExc_ValueError,\r
+ "bad marshal data (unnormalized long data)");\r
+ return NULL;\r
+ }\r
+ d += (digit)md << j*PyLong_MARSHAL_SHIFT;\r
+ }\r
+ /* top digit should be nonzero, else the resulting PyLong won't be\r
+ normalized */\r
+ ob->ob_digit[size-1] = d;\r
+ return (PyObject *)ob;\r
+ bad_digit:\r
+ Py_DECREF(ob);\r
+ PyErr_SetString(PyExc_ValueError,\r
+ "bad marshal data (digit out of range in long)");\r
+ return NULL;\r
+}\r
+\r
+\r
+static PyObject *\r
+r_object(RFILE *p)\r
+{\r
+ /* NULL is a valid return value, it does not necessarily means that\r
+ an exception is set. */\r
+ PyObject *v, *v2;\r
+ long i, n;\r
+ int type = r_byte(p);\r
+ PyObject *retval;\r
+\r
+ p->depth++;\r
+\r
+ if (p->depth > MAX_MARSHAL_STACK_DEPTH) {\r
+ p->depth--;\r
+ PyErr_SetString(PyExc_ValueError, "recursion limit exceeded");\r
+ return NULL;\r
+ }\r
+\r
+ switch (type) {\r
+\r
+ case EOF:\r
+ PyErr_SetString(PyExc_EOFError,\r
+ "EOF read where object expected");\r
+ retval = NULL;\r
+ break;\r
+\r
+ case TYPE_NULL:\r
+ retval = NULL;\r
+ break;\r
+\r
+ case TYPE_NONE:\r
+ Py_INCREF(Py_None);\r
+ retval = Py_None;\r
+ break;\r
+\r
+ case TYPE_STOPITER:\r
+ Py_INCREF(PyExc_StopIteration);\r
+ retval = PyExc_StopIteration;\r
+ break;\r
+\r
+ case TYPE_ELLIPSIS:\r
+ Py_INCREF(Py_Ellipsis);\r
+ retval = Py_Ellipsis;\r
+ break;\r
+\r
+ case TYPE_FALSE:\r
+ Py_INCREF(Py_False);\r
+ retval = Py_False;\r
+ break;\r
+\r
+ case TYPE_TRUE:\r
+ Py_INCREF(Py_True);\r
+ retval = Py_True;\r
+ break;\r
+\r
+ case TYPE_INT:\r
+ retval = PyInt_FromLong(r_long(p));\r
+ break;\r
+\r
+ case TYPE_INT64:\r
+ retval = r_long64(p);\r
+ break;\r
+\r
+ case TYPE_LONG:\r
+ retval = r_PyLong(p);\r
+ break;\r
+\r
+ case TYPE_FLOAT:\r
+ {\r
+ char buf[256];\r
+ double dx;\r
+ n = r_byte(p);\r
+ if (n == EOF || r_string(buf, n, p) != n) {\r
+ PyErr_SetString(PyExc_EOFError,\r
+ "EOF read where object expected");\r
+ retval = NULL;\r
+ break;\r
+ }\r
+ buf[n] = '\0';\r
+ dx = PyOS_string_to_double(buf, NULL, NULL);\r
+ if (dx == -1.0 && PyErr_Occurred()) {\r
+ retval = NULL;\r
+ break;\r
+ }\r
+ retval = PyFloat_FromDouble(dx);\r
+ break;\r
+ }\r
+\r
+ case TYPE_BINARY_FLOAT:\r
+ {\r
+ unsigned char buf[8];\r
+ double x;\r
+ if (r_string((char*)buf, 8, p) != 8) {\r
+ PyErr_SetString(PyExc_EOFError,\r
+ "EOF read where object expected");\r
+ retval = NULL;\r
+ break;\r
+ }\r
+ x = _PyFloat_Unpack8(buf, 1);\r
+ if (x == -1.0 && PyErr_Occurred()) {\r
+ retval = NULL;\r
+ break;\r
+ }\r
+ retval = PyFloat_FromDouble(x);\r
+ break;\r
+ }\r
+\r
+#ifndef WITHOUT_COMPLEX\r
+ case TYPE_COMPLEX:\r
+ {\r
+ char buf[256];\r
+ Py_complex c;\r
+ n = r_byte(p);\r
+ if (n == EOF || r_string(buf, n, p) != n) {\r
+ PyErr_SetString(PyExc_EOFError,\r
+ "EOF read where object expected");\r
+ retval = NULL;\r
+ break;\r
+ }\r
+ buf[n] = '\0';\r
+ c.real = PyOS_string_to_double(buf, NULL, NULL);\r
+ if (c.real == -1.0 && PyErr_Occurred()) {\r
+ retval = NULL;\r
+ break;\r
+ }\r
+ n = r_byte(p);\r
+ if (n == EOF || r_string(buf, n, p) != n) {\r
+ PyErr_SetString(PyExc_EOFError,\r
+ "EOF read where object expected");\r
+ retval = NULL;\r
+ break;\r
+ }\r
+ buf[n] = '\0';\r
+ c.imag = PyOS_string_to_double(buf, NULL, NULL);\r
+ if (c.imag == -1.0 && PyErr_Occurred()) {\r
+ retval = NULL;\r
+ break;\r
+ }\r
+ retval = PyComplex_FromCComplex(c);\r
+ break;\r
+ }\r
+\r
+ case TYPE_BINARY_COMPLEX:\r
+ {\r
+ unsigned char buf[8];\r
+ Py_complex c;\r
+ if (r_string((char*)buf, 8, p) != 8) {\r
+ PyErr_SetString(PyExc_EOFError,\r
+ "EOF read where object expected");\r
+ retval = NULL;\r
+ break;\r
+ }\r
+ c.real = _PyFloat_Unpack8(buf, 1);\r
+ if (c.real == -1.0 && PyErr_Occurred()) {\r
+ retval = NULL;\r
+ break;\r
+ }\r
+ if (r_string((char*)buf, 8, p) != 8) {\r
+ PyErr_SetString(PyExc_EOFError,\r
+ "EOF read where object expected");\r
+ retval = NULL;\r
+ break;\r
+ }\r
+ c.imag = _PyFloat_Unpack8(buf, 1);\r
+ if (c.imag == -1.0 && PyErr_Occurred()) {\r
+ retval = NULL;\r
+ break;\r
+ }\r
+ retval = PyComplex_FromCComplex(c);\r
+ break;\r
+ }\r
+#endif\r
+\r
+ case TYPE_INTERNED:\r
+ case TYPE_STRING:\r
+ n = r_long(p);\r
+ if (n < 0 || n > SIZE32_MAX) {\r
+ PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)");\r
+ retval = NULL;\r
+ break;\r
+ }\r
+ v = PyString_FromStringAndSize((char *)NULL, n);\r
+ if (v == NULL) {\r
+ retval = NULL;\r
+ break;\r
+ }\r
+ if (r_string(PyString_AS_STRING(v), n, p) != n) {\r
+ Py_DECREF(v);\r
+ PyErr_SetString(PyExc_EOFError,\r
+ "EOF read where object expected");\r
+ retval = NULL;\r
+ break;\r
+ }\r
+ if (type == TYPE_INTERNED) {\r
+ PyString_InternInPlace(&v);\r
+ if (PyList_Append(p->strings, v) < 0) {\r
+ retval = NULL;\r
+ break;\r
+ }\r
+ }\r
+ retval = v;\r
+ break;\r
+\r
+ case TYPE_STRINGREF:\r
+ n = r_long(p);\r
+ if (n < 0 || n >= PyList_GET_SIZE(p->strings)) {\r
+ PyErr_SetString(PyExc_ValueError, "bad marshal data (string ref out of range)");\r
+ retval = NULL;\r
+ break;\r
+ }\r
+ v = PyList_GET_ITEM(p->strings, n);\r
+ Py_INCREF(v);\r
+ retval = v;\r
+ break;\r
+\r
+#ifdef Py_USING_UNICODE\r
+ case TYPE_UNICODE:\r
+ {\r
+ char *buffer;\r
+\r
+ n = r_long(p);\r
+ if (n < 0 || n > SIZE32_MAX) {\r
+ PyErr_SetString(PyExc_ValueError, "bad marshal data (unicode size out of range)");\r
+ retval = NULL;\r
+ break;\r
+ }\r
+ buffer = PyMem_NEW(char, n);\r
+ if (buffer == NULL) {\r
+ retval = PyErr_NoMemory();\r
+ break;\r
+ }\r
+ if (r_string(buffer, n, p) != n) {\r
+ PyMem_DEL(buffer);\r
+ PyErr_SetString(PyExc_EOFError,\r
+ "EOF read where object expected");\r
+ retval = NULL;\r
+ break;\r
+ }\r
+ v = PyUnicode_DecodeUTF8(buffer, n, NULL);\r
+ PyMem_DEL(buffer);\r
+ retval = v;\r
+ break;\r
+ }\r
+#endif\r
+\r
+ case TYPE_TUPLE:\r
+ n = r_long(p);\r
+ if (n < 0 || n > SIZE32_MAX) {\r
+ PyErr_SetString(PyExc_ValueError, "bad marshal data (tuple size out of range)");\r
+ retval = NULL;\r
+ break;\r
+ }\r
+ v = PyTuple_New(n);\r
+ if (v == NULL) {\r
+ retval = NULL;\r
+ break;\r
+ }\r
+ for (i = 0; i < n; i++) {\r
+ v2 = r_object(p);\r
+ if ( v2 == NULL ) {\r
+ if (!PyErr_Occurred())\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "NULL object in marshal data for tuple");\r
+ Py_DECREF(v);\r
+ v = NULL;\r
+ break;\r
+ }\r
+ PyTuple_SET_ITEM(v, i, v2);\r
+ }\r
+ retval = v;\r
+ break;\r
+\r
+ case TYPE_LIST:\r
+ n = r_long(p);\r
+ if (n < 0 || n > SIZE32_MAX) {\r
+ PyErr_SetString(PyExc_ValueError, "bad marshal data (list size out of range)");\r
+ retval = NULL;\r
+ break;\r
+ }\r
+ v = PyList_New(n);\r
+ if (v == NULL) {\r
+ retval = NULL;\r
+ break;\r
+ }\r
+ for (i = 0; i < n; i++) {\r
+ v2 = r_object(p);\r
+ if ( v2 == NULL ) {\r
+ if (!PyErr_Occurred())\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "NULL object in marshal data for list");\r
+ Py_DECREF(v);\r
+ v = NULL;\r
+ break;\r
+ }\r
+ PyList_SET_ITEM(v, i, v2);\r
+ }\r
+ retval = v;\r
+ break;\r
+\r
+ case TYPE_DICT:\r
+ v = PyDict_New();\r
+ if (v == NULL) {\r
+ retval = NULL;\r
+ break;\r
+ }\r
+ for (;;) {\r
+ PyObject *key, *val;\r
+ key = r_object(p);\r
+ if (key == NULL)\r
+ break;\r
+ val = r_object(p);\r
+ if (val != NULL)\r
+ PyDict_SetItem(v, key, val);\r
+ Py_DECREF(key);\r
+ Py_XDECREF(val);\r
+ }\r
+ if (PyErr_Occurred()) {\r
+ Py_DECREF(v);\r
+ v = NULL;\r
+ }\r
+ retval = v;\r
+ break;\r
+\r
+ case TYPE_SET:\r
+ case TYPE_FROZENSET:\r
+ n = r_long(p);\r
+ if (n < 0 || n > SIZE32_MAX) {\r
+ PyErr_SetString(PyExc_ValueError, "bad marshal data (set size out of range)");\r
+ retval = NULL;\r
+ break;\r
+ }\r
+ v = (type == TYPE_SET) ? PySet_New(NULL) : PyFrozenSet_New(NULL);\r
+ if (v == NULL) {\r
+ retval = NULL;\r
+ break;\r
+ }\r
+ for (i = 0; i < n; i++) {\r
+ v2 = r_object(p);\r
+ if ( v2 == NULL ) {\r
+ if (!PyErr_Occurred())\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "NULL object in marshal data for set");\r
+ Py_DECREF(v);\r
+ v = NULL;\r
+ break;\r
+ }\r
+ if (PySet_Add(v, v2) == -1) {\r
+ Py_DECREF(v);\r
+ Py_DECREF(v2);\r
+ v = NULL;\r
+ break;\r
+ }\r
+ Py_DECREF(v2);\r
+ }\r
+ retval = v;\r
+ break;\r
+\r
+ case TYPE_CODE:\r
+ if (PyEval_GetRestricted()) {\r
+ PyErr_SetString(PyExc_RuntimeError,\r
+ "cannot unmarshal code objects in "\r
+ "restricted execution mode");\r
+ retval = NULL;\r
+ break;\r
+ }\r
+ else {\r
+ int argcount;\r
+ int nlocals;\r
+ int stacksize;\r
+ int flags;\r
+ PyObject *code = NULL;\r
+ PyObject *consts = NULL;\r
+ PyObject *names = NULL;\r
+ PyObject *varnames = NULL;\r
+ PyObject *freevars = NULL;\r
+ PyObject *cellvars = NULL;\r
+ PyObject *filename = NULL;\r
+ PyObject *name = NULL;\r
+ int firstlineno;\r
+ PyObject *lnotab = NULL;\r
+\r
+ v = NULL;\r
+\r
+ /* XXX ignore long->int overflows for now */\r
+ argcount = (int)r_long(p);\r
+ nlocals = (int)r_long(p);\r
+ stacksize = (int)r_long(p);\r
+ flags = (int)r_long(p);\r
+ code = r_object(p);\r
+ if (code == NULL)\r
+ goto code_error;\r
+ consts = r_object(p);\r
+ if (consts == NULL)\r
+ goto code_error;\r
+ names = r_object(p);\r
+ if (names == NULL)\r
+ goto code_error;\r
+ varnames = r_object(p);\r
+ if (varnames == NULL)\r
+ goto code_error;\r
+ freevars = r_object(p);\r
+ if (freevars == NULL)\r
+ goto code_error;\r
+ cellvars = r_object(p);\r
+ if (cellvars == NULL)\r
+ goto code_error;\r
+ filename = r_object(p);\r
+ if (filename == NULL)\r
+ goto code_error;\r
+ name = r_object(p);\r
+ if (name == NULL)\r
+ goto code_error;\r
+ firstlineno = (int)r_long(p);\r
+ lnotab = r_object(p);\r
+ if (lnotab == NULL)\r
+ goto code_error;\r
+\r
+ v = (PyObject *) PyCode_New(\r
+ argcount, nlocals, stacksize, flags,\r
+ code, consts, names, varnames,\r
+ freevars, cellvars, filename, name,\r
+ firstlineno, lnotab);\r
+\r
+ code_error:\r
+ Py_XDECREF(code);\r
+ Py_XDECREF(consts);\r
+ Py_XDECREF(names);\r
+ Py_XDECREF(varnames);\r
+ Py_XDECREF(freevars);\r
+ Py_XDECREF(cellvars);\r
+ Py_XDECREF(filename);\r
+ Py_XDECREF(name);\r
+ Py_XDECREF(lnotab);\r
+\r
+ }\r
+ retval = v;\r
+ break;\r
+\r
+ default:\r
+ /* Bogus data got written, which isn't ideal.\r
+ This will let you keep working and recover. */\r
+ PyErr_SetString(PyExc_ValueError, "bad marshal data (unknown type code)");\r
+ retval = NULL;\r
+ break;\r
+\r
+ }\r
+ p->depth--;\r
+ return retval;\r
+}\r
+\r
+static PyObject *\r
+read_object(RFILE *p)\r
+{\r
+ PyObject *v;\r
+ if (PyErr_Occurred()) {\r
+ fprintf(stderr, "XXX readobject called with exception set\n");\r
+ return NULL;\r
+ }\r
+ v = r_object(p);\r
+ if (v == NULL && !PyErr_Occurred())\r
+ PyErr_SetString(PyExc_TypeError, "NULL object in marshal data for object");\r
+ return v;\r
+}\r
+\r
+int\r
+PyMarshal_ReadShortFromFile(FILE *fp)\r
+{\r
+ RFILE rf;\r
+ assert(fp);\r
+ rf.fp = fp;\r
+ rf.strings = NULL;\r
+ rf.end = rf.ptr = NULL;\r
+ return r_short(&rf);\r
+}\r
+\r
+long\r
+PyMarshal_ReadLongFromFile(FILE *fp)\r
+{\r
+ RFILE rf;\r
+ rf.fp = fp;\r
+ rf.strings = NULL;\r
+ rf.ptr = rf.end = NULL;\r
+ return r_long(&rf);\r
+}\r
+\r
+#ifdef HAVE_FSTAT\r
+/* Return size of file in bytes; < 0 if unknown. */\r
+static off_t\r
+getfilesize(FILE *fp)\r
+{\r
+ struct stat st;\r
+ if (fstat(fileno(fp), &st) != 0)\r
+ return -1;\r
+ else\r
+ return st.st_size;\r
+}\r
+#endif\r
+\r
+/* If we can get the size of the file up-front, and it's reasonably small,\r
+ * read it in one gulp and delegate to ...FromString() instead. Much quicker\r
+ * than reading a byte at a time from file; speeds .pyc imports.\r
+ * CAUTION: since this may read the entire remainder of the file, don't\r
+ * call it unless you know you're done with the file.\r
+ */\r
+PyObject *\r
+PyMarshal_ReadLastObjectFromFile(FILE *fp)\r
+{\r
+/* REASONABLE_FILE_LIMIT is by defn something big enough for Tkinter.pyc. */\r
+#define REASONABLE_FILE_LIMIT (1L << 18)\r
+#ifdef HAVE_FSTAT\r
+ off_t filesize;\r
+ filesize = getfilesize(fp);\r
+ if (filesize > 0 && filesize <= REASONABLE_FILE_LIMIT) {\r
+ char* pBuf = (char *)PyMem_MALLOC(filesize);\r
+ if (pBuf != NULL) {\r
+ size_t n = fread(pBuf, 1, (size_t)filesize, fp);\r
+ PyObject* v = PyMarshal_ReadObjectFromString(pBuf, n);\r
+ PyMem_FREE(pBuf);\r
+ return v;\r
+ }\r
+\r
+ }\r
+#endif\r
+ /* We don't have fstat, or we do but the file is larger than\r
+ * REASONABLE_FILE_LIMIT or malloc failed -- read a byte at a time.\r
+ */\r
+ return PyMarshal_ReadObjectFromFile(fp);\r
+\r
+#undef REASONABLE_FILE_LIMIT\r
+}\r
+\r
+PyObject *\r
+PyMarshal_ReadObjectFromFile(FILE *fp)\r
+{\r
+ RFILE rf;\r
+ PyObject *result;\r
+ rf.fp = fp;\r
+ rf.strings = PyList_New(0);\r
+ rf.depth = 0;\r
+ rf.ptr = rf.end = NULL;\r
+ result = r_object(&rf);\r
+ Py_DECREF(rf.strings);\r
+ return result;\r
+}\r
+\r
+PyObject *\r
+PyMarshal_ReadObjectFromString(char *str, Py_ssize_t len)\r
+{\r
+ RFILE rf;\r
+ PyObject *result;\r
+ rf.fp = NULL;\r
+ rf.ptr = str;\r
+ rf.end = str + len;\r
+ rf.strings = PyList_New(0);\r
+ rf.depth = 0;\r
+ result = r_object(&rf);\r
+ Py_DECREF(rf.strings);\r
+ return result;\r
+}\r
+\r
+static void\r
+set_error(int error)\r
+{\r
+ switch (error) {\r
+ case WFERR_NOMEMORY:\r
+ PyErr_NoMemory();\r
+ break;\r
+ case WFERR_UNMARSHALLABLE:\r
+ PyErr_SetString(PyExc_ValueError, "unmarshallable object");\r
+ break;\r
+ case WFERR_NESTEDTOODEEP:\r
+ default:\r
+ PyErr_SetString(PyExc_ValueError,\r
+ "object too deeply nested to marshal");\r
+ break;\r
+ }\r
+}\r
+\r
+PyObject *\r
+PyMarshal_WriteObjectToString(PyObject *x, int version)\r
+{\r
+ WFILE wf;\r
+ wf.fp = NULL;\r
+ wf.str = PyString_FromStringAndSize((char *)NULL, 50);\r
+ if (wf.str == NULL)\r
+ return NULL;\r
+ wf.ptr = PyString_AS_STRING((PyStringObject *)wf.str);\r
+ wf.end = wf.ptr + PyString_Size(wf.str);\r
+ wf.error = WFERR_OK;\r
+ wf.depth = 0;\r
+ wf.version = version;\r
+ wf.strings = (version > 0) ? PyDict_New() : NULL;\r
+ w_object(x, &wf);\r
+ Py_XDECREF(wf.strings);\r
+ if (wf.str != NULL) {\r
+ char *base = PyString_AS_STRING((PyStringObject *)wf.str);\r
+ if (wf.ptr - base > PY_SSIZE_T_MAX) {\r
+ Py_DECREF(wf.str);\r
+ PyErr_SetString(PyExc_OverflowError,\r
+ "too much marshall data for a string");\r
+ return NULL;\r
+ }\r
+ if (_PyString_Resize(&wf.str, (Py_ssize_t)(wf.ptr - base)))\r
+ return NULL;\r
+ }\r
+ if (wf.error != WFERR_OK) {\r
+ Py_XDECREF(wf.str);\r
+ set_error(wf.error);\r
+ return NULL;\r
+ }\r
+ return wf.str;\r
+}\r
+\r
+/* And an interface for Python programs... */\r
+\r
+static PyObject *\r
+marshal_dump(PyObject *self, PyObject *args)\r
+{\r
+ WFILE wf;\r
+ PyObject *x;\r
+ PyObject *f;\r
+ int version = Py_MARSHAL_VERSION;\r
+ if (!PyArg_ParseTuple(args, "OO|i:dump", &x, &f, &version))\r
+ return NULL;\r
+ if (!PyFile_Check(f)) {\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "marshal.dump() 2nd arg must be file");\r
+ return NULL;\r
+ }\r
+ wf.fp = PyFile_AsFile(f);\r
+ wf.str = NULL;\r
+ wf.ptr = wf.end = NULL;\r
+ wf.error = WFERR_OK;\r
+ wf.depth = 0;\r
+ wf.strings = (version > 0) ? PyDict_New() : 0;\r
+ wf.version = version;\r
+ w_object(x, &wf);\r
+ Py_XDECREF(wf.strings);\r
+ if (wf.error != WFERR_OK) {\r
+ set_error(wf.error);\r
+ return NULL;\r
+ }\r
+ Py_INCREF(Py_None);\r
+ return Py_None;\r
+}\r
+\r
+PyDoc_STRVAR(dump_doc,\r
+"dump(value, file[, version])\n\\r
+\n\\r
+Write the value on the open file. The value must be a supported type.\n\\r
+The file must be an open file object such as sys.stdout or returned by\n\\r
+open() or os.popen(). It must be opened in binary mode ('wb' or 'w+b').\n\\r
+\n\\r
+If the value has (or contains an object that has) an unsupported type, a\n\\r
+ValueError exception is raised — but garbage data will also be written\n\\r
+to the file. The object will not be properly read back by load()\n\\r
+\n\\r
+New in version 2.4: The version argument indicates the data format that\n\\r
+dump should use.");\r
+\r
+static PyObject *\r
+marshal_load(PyObject *self, PyObject *f)\r
+{\r
+ RFILE rf;\r
+ PyObject *result;\r
+ if (!PyFile_Check(f)) {\r
+ PyErr_SetString(PyExc_TypeError,\r
+ "marshal.load() arg must be file");\r
+ return NULL;\r
+ }\r
+ rf.fp = PyFile_AsFile(f);\r
+ rf.strings = PyList_New(0);\r
+ rf.depth = 0;\r
+ result = read_object(&rf);\r
+ Py_DECREF(rf.strings);\r
+ return result;\r
+}\r
+\r
+PyDoc_STRVAR(load_doc,\r
+"load(file)\n\\r
+\n\\r
+Read one value from the open file and return it. If no valid value is\n\\r
+read (e.g. because the data has a different Python version’s\n\\r
+incompatible marshal format), raise EOFError, ValueError or TypeError.\n\\r
+The file must be an open file object opened in binary mode ('rb' or\n\\r
+'r+b').\n\\r
+\n\\r
+Note: If an object containing an unsupported type was marshalled with\n\\r
+dump(), load() will substitute None for the unmarshallable type.");\r
+\r
+\r
+static PyObject *\r
+marshal_dumps(PyObject *self, PyObject *args)\r
+{\r
+ PyObject *x;\r
+ int version = Py_MARSHAL_VERSION;\r
+ if (!PyArg_ParseTuple(args, "O|i:dumps", &x, &version))\r
+ return NULL;\r
+ return PyMarshal_WriteObjectToString(x, version);\r
+}\r
+\r
+PyDoc_STRVAR(dumps_doc,\r
+"dumps(value[, version])\n\\r
+\n\\r
+Return the string that would be written to a file by dump(value, file).\n\\r
+The value must be a supported type. Raise a ValueError exception if\n\\r
+value has (or contains an object that has) an unsupported type.\n\\r
+\n\\r
+New in version 2.4: The version argument indicates the data format that\n\\r
+dumps should use.");\r
+\r
+\r
+static PyObject *\r
+marshal_loads(PyObject *self, PyObject *args)\r
+{\r
+ RFILE rf;\r
+ char *s;\r
+ Py_ssize_t n;\r
+ PyObject* result;\r
+ if (!PyArg_ParseTuple(args, "s#:loads", &s, &n))\r
+ return NULL;\r
+ rf.fp = NULL;\r
+ rf.ptr = s;\r
+ rf.end = s + n;\r
+ rf.strings = PyList_New(0);\r
+ rf.depth = 0;\r
+ result = read_object(&rf);\r
+ Py_DECREF(rf.strings);\r
+ return result;\r
+}\r
+\r
+PyDoc_STRVAR(loads_doc,\r
+"loads(string)\n\\r
+\n\\r
+Convert the string to a value. If no valid value is found, raise\n\\r
+EOFError, ValueError or TypeError. Extra characters in the string are\n\\r
+ignored.");\r
+\r
+static PyMethodDef marshal_methods[] = {\r
+ {"dump", marshal_dump, METH_VARARGS, dump_doc},\r
+ {"load", marshal_load, METH_O, load_doc},\r
+ {"dumps", marshal_dumps, METH_VARARGS, dumps_doc},\r
+ {"loads", marshal_loads, METH_VARARGS, loads_doc},\r
+ {NULL, NULL} /* sentinel */\r
+};\r
+\r
+PyDoc_STRVAR(marshal_doc,\r
+"This module contains functions that can read and write Python values in\n\\r
+a binary format. The format is specific to Python, but independent of\n\\r
+machine architecture issues.\n\\r
+\n\\r
+Not all Python object types are supported; in general, only objects\n\\r
+whose value is independent from a particular invocation of Python can be\n\\r
+written and read by this module. The following types are supported:\n\\r
+None, integers, long integers, floating point numbers, strings, Unicode\n\\r
+objects, tuples, lists, sets, dictionaries, and code objects, where it\n\\r
+should be understood that tuples, lists and dictionaries are only\n\\r
+supported as long as the values contained therein are themselves\n\\r
+supported; and recursive lists and dictionaries should not be written\n\\r
+(they will cause infinite loops).\n\\r
+\n\\r
+Variables:\n\\r
+\n\\r
+version -- indicates the format that the module uses. Version 0 is the\n\\r
+ historical format, version 1 (added in Python 2.4) shares interned\n\\r
+ strings and version 2 (added in Python 2.5) uses a binary format for\n\\r
+ floating point numbers. (New in version 2.4)\n\\r
+\n\\r
+Functions:\n\\r
+\n\\r
+dump() -- write value to a file\n\\r
+load() -- read value from a file\n\\r
+dumps() -- write value to a string\n\\r
+loads() -- read value from a string");\r
+\r
+\r
+PyMODINIT_FUNC\r
+PyMarshal_Init(void)\r
+{\r
+ PyObject *mod = Py_InitModule3("marshal", marshal_methods,\r
+ marshal_doc);\r
+ if (mod == NULL)\r
+ return;\r
+ PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION);\r
+}\r
--- /dev/null
+#include "Python.h"\r
+#ifdef MS_WINDOWS\r
+#include <windows.h>\r
+#else\r
+#include <fcntl.h>\r
+#endif\r
+\r
+#ifdef Py_DEBUG\r
+int _Py_HashSecret_Initialized = 0;\r
+#else\r
+static int _Py_HashSecret_Initialized = 0;\r
+#endif\r
+\r
+#ifdef MS_WINDOWS\r
+typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\\r
+ LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\\r
+ DWORD dwFlags );\r
+typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\\r
+ BYTE *pbBuffer );\r
+\r
+static CRYPTGENRANDOM pCryptGenRandom = NULL;\r
+/* This handle is never explicitly released. Instead, the operating\r
+ system will release it when the process terminates. */\r
+static HCRYPTPROV hCryptProv = 0;\r
+\r
+static int\r
+win32_urandom_init(int raise)\r
+{\r
+ HINSTANCE hAdvAPI32 = NULL;\r
+ CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;\r
+\r
+ /* Obtain handle to the DLL containing CryptoAPI. This should not fail. */\r
+ hAdvAPI32 = GetModuleHandle("advapi32.dll");\r
+ if(hAdvAPI32 == NULL)\r
+ goto error;\r
+\r
+ /* Obtain pointers to the CryptoAPI functions. This will fail on some early\r
+ versions of Win95. */\r
+ pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(\r
+ hAdvAPI32, "CryptAcquireContextA");\r
+ if (pCryptAcquireContext == NULL)\r
+ goto error;\r
+\r
+ pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(hAdvAPI32,\r
+ "CryptGenRandom");\r
+ if (pCryptGenRandom == NULL)\r
+ goto error;\r
+\r
+ /* Acquire context */\r
+ if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,\r
+ PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))\r
+ goto error;\r
+\r
+ return 0;\r
+\r
+error:\r
+ if (raise)\r
+ PyErr_SetFromWindowsErr(0);\r
+ else\r
+ Py_FatalError("Failed to initialize Windows random API (CryptoGen)");\r
+ return -1;\r
+}\r
+\r
+/* Fill buffer with size pseudo-random bytes generated by the Windows CryptoGen\r
+ API. Return 0 on success, or -1 on error. */\r
+static int\r
+win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise)\r
+{\r
+ Py_ssize_t chunk;\r
+\r
+ if (hCryptProv == 0)\r
+ {\r
+ if (win32_urandom_init(raise) == -1)\r
+ return -1;\r
+ }\r
+\r
+ while (size > 0)\r
+ {\r
+ chunk = size > INT_MAX ? INT_MAX : size;\r
+ if (!pCryptGenRandom(hCryptProv, chunk, buffer))\r
+ {\r
+ /* CryptGenRandom() failed */\r
+ if (raise)\r
+ PyErr_SetFromWindowsErr(0);\r
+ else\r
+ Py_FatalError("Failed to initialized the randomized hash "\r
+ "secret using CryptoGen)");\r
+ return -1;\r
+ }\r
+ buffer += chunk;\r
+ size -= chunk;\r
+ }\r
+ return 0;\r
+}\r
+\r
+#elif HAVE_GETENTROPY\r
+/* Fill buffer with size pseudo-random bytes generated by getentropy().\r
+ Return 0 on success, or raise an exception and return -1 on error.\r
+ If fatal is nonzero, call Py_FatalError() instead of raising an exception\r
+ on error. */\r
+static int\r
+py_getentropy(unsigned char *buffer, Py_ssize_t size, int fatal)\r
+{\r
+ while (size > 0) {\r
+ Py_ssize_t len = size < 256 ? size : 256;\r
+ int res;\r
+\r
+ if (!fatal) {\r
+ Py_BEGIN_ALLOW_THREADS\r
+ res = getentropy(buffer, len);\r
+ Py_END_ALLOW_THREADS\r
+\r
+ if (res < 0) {\r
+ PyErr_SetFromErrno(PyExc_OSError);\r
+ return -1;\r
+ }\r
+ }\r
+ else {\r
+ res = getentropy(buffer, len);\r
+ if (res < 0)\r
+ Py_FatalError("getentropy() failed");\r
+ }\r
+\r
+ buffer += len;\r
+ size -= len;\r
+ }\r
+ return 0;\r
+}\r
+#endif\r
+\r
+#ifdef __VMS\r
+/* Use openssl random routine */\r
+#include <openssl/rand.h>\r
+static int\r
+vms_urandom(unsigned char *buffer, Py_ssize_t size, int raise)\r
+{\r
+ if (RAND_pseudo_bytes(buffer, size) < 0) {\r
+ if (raise) {\r
+ PyErr_Format(PyExc_ValueError,\r
+ "RAND_pseudo_bytes");\r
+ } else {\r
+ Py_FatalError("Failed to initialize the randomized hash "\r
+ "secret using RAND_pseudo_bytes");\r
+ }\r
+ return -1;\r
+ }\r
+ return 0;\r
+}\r
+#endif /* __VMS */\r
+\r
+\r
+#if !defined(MS_WINDOWS) && !defined(__VMS)\r
+\r
+static struct {\r
+ int fd;\r
+ dev_t st_dev;\r
+ ino_t st_ino;\r
+} urandom_cache = { -1 };\r
+\r
+/* Read size bytes from /dev/urandom into buffer.\r
+ Call Py_FatalError() on error. */\r
+static void\r
+dev_urandom_noraise(unsigned char *buffer, Py_ssize_t size)\r
+{\r
+ int fd;\r
+ Py_ssize_t n;\r
+\r
+ assert (0 < size);\r
+\r
+ fd = open("/dev/urandom", O_RDONLY);\r
+ if (fd < 0)\r
+ Py_FatalError("Failed to open /dev/urandom");\r
+\r
+ while (0 < size)\r
+ {\r
+ do {\r
+ n = read(fd, buffer, (size_t)size);\r
+ } while (n < 0 && errno == EINTR);\r
+ if (n <= 0)\r
+ {\r
+ /* stop on error or if read(size) returned 0 */\r
+ Py_FatalError("Failed to read bytes from /dev/urandom");\r
+ break;\r
+ }\r
+ buffer += n;\r
+ size -= (Py_ssize_t)n;\r
+ }\r
+ close(fd);\r
+}\r
+\r
+/* Read size bytes from /dev/urandom into buffer.\r
+ Return 0 on success, raise an exception and return -1 on error. */\r
+static int\r
+dev_urandom_python(char *buffer, Py_ssize_t size)\r
+{\r
+ int fd;\r
+ Py_ssize_t n;\r
+ struct stat st;\r
+ int attr;\r
+\r
+ if (size <= 0)\r
+ return 0;\r
+\r
+ if (urandom_cache.fd >= 0) {\r
+ /* Does the fd point to the same thing as before? (issue #21207) */\r
+ if (fstat(urandom_cache.fd, &st)\r
+ || st.st_dev != urandom_cache.st_dev\r
+ || st.st_ino != urandom_cache.st_ino) {\r
+ /* Something changed: forget the cached fd (but don't close it,\r
+ since it probably points to something important for some\r
+ third-party code). */\r
+ urandom_cache.fd = -1;\r
+ }\r
+ }\r
+ if (urandom_cache.fd >= 0)\r
+ fd = urandom_cache.fd;\r
+ else {\r
+ Py_BEGIN_ALLOW_THREADS\r
+ fd = open("/dev/urandom", O_RDONLY);\r
+ Py_END_ALLOW_THREADS\r
+ if (fd < 0)\r
+ {\r
+ if (errno == ENOENT || errno == ENXIO ||\r
+ errno == ENODEV || errno == EACCES)\r
+ PyErr_SetString(PyExc_NotImplementedError,\r
+ "/dev/urandom (or equivalent) not found");\r
+ else\r
+ PyErr_SetFromErrno(PyExc_OSError);\r
+ return -1;\r
+ }\r
+\r
+ /* try to make the file descriptor non-inheritable, ignore errors */\r
+ attr = fcntl(fd, F_GETFD);\r
+ if (attr >= 0) {\r
+ attr |= FD_CLOEXEC;\r
+ (void)fcntl(fd, F_SETFD, attr);\r
+ }\r
+\r
+ if (urandom_cache.fd >= 0) {\r
+ /* urandom_fd was initialized by another thread while we were\r
+ not holding the GIL, keep it. */\r
+ close(fd);\r
+ fd = urandom_cache.fd;\r
+ }\r
+ else {\r
+ if (fstat(fd, &st)) {\r
+ PyErr_SetFromErrno(PyExc_OSError);\r
+ close(fd);\r
+ return -1;\r
+ }\r
+ else {\r
+ urandom_cache.fd = fd;\r
+ urandom_cache.st_dev = st.st_dev;\r
+ urandom_cache.st_ino = st.st_ino;\r
+ }\r
+ }\r
+ }\r
+\r
+ Py_BEGIN_ALLOW_THREADS\r
+ do {\r
+ do {\r
+ n = read(fd, buffer, (size_t)size);\r
+ } while (n < 0 && errno == EINTR);\r
+ if (n <= 0)\r
+ break;\r
+ buffer += n;\r
+ size -= (Py_ssize_t)n;\r
+ } while (0 < size);\r
+ Py_END_ALLOW_THREADS\r
+\r
+ if (n <= 0)\r
+ {\r
+ /* stop on error or if read(size) returned 0 */\r
+ if (n < 0)\r
+ PyErr_SetFromErrno(PyExc_OSError);\r
+ else\r
+ PyErr_Format(PyExc_RuntimeError,\r
+ "Failed to read %zi bytes from /dev/urandom",\r
+ size);\r
+ return -1;\r
+ }\r
+ return 0;\r
+}\r
+\r
+static void\r
+dev_urandom_close(void)\r
+{\r
+ if (urandom_cache.fd >= 0) {\r
+ close(urandom_cache.fd);\r
+ urandom_cache.fd = -1;\r
+ }\r
+}\r
+\r
+\r
+#endif /* !defined(MS_WINDOWS) && !defined(__VMS) */\r
+\r
+/* Fill buffer with pseudo-random bytes generated by a linear congruent\r
+ generator (LCG):\r
+\r
+ x(n+1) = (x(n) * 214013 + 2531011) % 2^32\r
+\r
+ Use bits 23..16 of x(n) to generate a byte. */\r
+static void\r
+lcg_urandom(unsigned int x0, unsigned char *buffer, size_t size)\r
+{\r
+ size_t index;\r
+ unsigned int x;\r
+\r
+ x = x0;\r
+ for (index=0; index < size; index++) {\r
+ x *= 214013;\r
+ x += 2531011;\r
+ /* modulo 2 ^ (8 * sizeof(int)) */\r
+ buffer[index] = (x >> 16) & 0xff;\r
+ }\r
+}\r
+\r
+/* Fill buffer with size pseudo-random bytes from the operating system random\r
+ number generator (RNG). It is suitable for most cryptographic purposes\r
+ except long living private keys for asymmetric encryption.\r
+\r
+ Return 0 on success, raise an exception and return -1 on error. */\r
+int\r
+_PyOS_URandom(void *buffer, Py_ssize_t size)\r
+{\r
+ if (size < 0) {\r
+ PyErr_Format(PyExc_ValueError,\r
+ "negative argument not allowed");\r
+ return -1;\r
+ }\r
+ if (size == 0)\r
+ return 0;\r
+\r
+#ifdef MS_WINDOWS\r
+ return win32_urandom((unsigned char *)buffer, size, 1);\r
+#elif HAVE_GETENTROPY\r
+ return py_getentropy(buffer, size, 0);\r
+#else\r
+# ifdef __VMS\r
+ return vms_urandom((unsigned char *)buffer, size, 1);\r
+# else\r
+ return dev_urandom_python((char*)buffer, size);\r
+# endif\r
+#endif\r
+}\r
+\r
+void\r
+_PyRandom_Init(void)\r
+{\r
+ char *env;\r
+ void *secret = &_Py_HashSecret;\r
+ Py_ssize_t secret_size = sizeof(_Py_HashSecret_t);\r
+\r
+ if (_Py_HashSecret_Initialized)\r
+ return;\r
+ _Py_HashSecret_Initialized = 1;\r
+\r
+ /*\r
+ By default, hash randomization is disabled, and only\r
+ enabled if PYTHONHASHSEED is set to non-empty or if\r
+ "-R" is provided at the command line:\r
+ */\r
+ if (!Py_HashRandomizationFlag) {\r
+ /* Disable the randomized hash: */\r
+ memset(secret, 0, secret_size);\r
+ return;\r
+ }\r
+\r
+ /*\r
+ Hash randomization is enabled. Generate a per-process secret,\r
+ using PYTHONHASHSEED if provided.\r
+ */\r
+\r
+ env = Py_GETENV("PYTHONHASHSEED");\r
+ if (env && *env != '\0' && strcmp(env, "random") != 0) {\r
+ char *endptr = env;\r
+ unsigned long seed;\r
+ seed = strtoul(env, &endptr, 10);\r
+ if (*endptr != '\0'\r
+ || seed > 4294967295UL\r
+ || (errno == ERANGE && seed == ULONG_MAX))\r
+ {\r
+ Py_FatalError("PYTHONHASHSEED must be \"random\" or an integer "\r
+ "in range [0; 4294967295]");\r
+ }\r
+ if (seed == 0) {\r
+ /* disable the randomized hash */\r
+ memset(secret, 0, secret_size);\r
+ }\r
+ else {\r
+ lcg_urandom(seed, (unsigned char*)secret, secret_size);\r
+ }\r
+ }\r
+ else {\r
+#ifdef MS_WINDOWS\r
+ (void)win32_urandom((unsigned char *)secret, secret_size, 0);\r
+#elif __VMS\r
+ vms_urandom((unsigned char *)secret, secret_size, 0);\r
+#elif HAVE_GETENTROPY\r
+ (void)py_getentropy(secret, secret_size, 1);\r
+#else\r
+ dev_urandom_noraise(secret, secret_size);\r
+#endif\r
+ }\r
+}\r
+\r
+void\r
+_PyRandom_Fini(void)\r
+{\r
+#ifdef MS_WINDOWS\r
+ if (hCryptProv) {\r
+ CryptReleaseContext(hCryptProv, 0);\r
+ hCryptProv = 0;\r
+ }\r
+#elif HAVE_GETENTROPY\r
+ /* nothing to clean */\r
+#else\r
+ dev_urandom_close();\r
+#endif\r
+}\r
--- /dev/null
+## @file\r
+# PythonCore.inf\r
+#\r
+# Copyright (c) 2015, Daryl McDaniel. All rights reserved.<BR>\r
+# Copyright (c) 2011-2012, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+##\r
+\r
+[Defines]\r
+ INF_VERSION = 0x00010016\r
+ BASE_NAME = Python\r
+ FILE_GUID = ca5627c4-51ba-4dcb-ac62-c076ebd37ddb\r
+ MODULE_TYPE = UEFI_APPLICATION\r
+ VERSION_STRING = 0.8\r
+ ENTRY_POINT = ShellCEntryLib\r
+\r
+ DEFINE PYTHON_VERSION = 2.7.2\r
+\r
+#\r
+# VALID_ARCHITECTURES = IA32 X64 IPF\r
+#\r
+\r
+[Packages]\r
+ StdLib/StdLib.dec\r
+ MdePkg/MdePkg.dec\r
+\r
+[LibraryClasses]\r
+ UefiLib\r
+ DebugLib\r
+ LibC\r
+ LibString\r
+ LibStdio\r
+ LibGdtoa\r
+ LibMath\r
+ LibWchar\r
+ LibGen\r
+ LibNetUtil\r
+ DevMedia\r
+ #\r
+ # Comment out the following two library classes if socket support is\r
+ # NOT being built in to Python.\r
+ #BsdSocketLib\r
+ #EfiSocketLib\r
+\r
+[FixedPcd]\r
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0F\r
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000040\r
+\r
+[Sources]\r
+#EFI -- EFI specific code\r
+ Efi/config.c\r
+ Efi/edk2module.c\r
+ Efi/getpath.c\r
+\r
+#Parser\r
+ Python-$(PYTHON_VERSION)/Parser/acceler.c\r
+ Python-$(PYTHON_VERSION)/Parser/bitset.c\r
+ Python-$(PYTHON_VERSION)/Parser/firstsets.c\r
+ Python-$(PYTHON_VERSION)/Parser/grammar.c\r
+ Python-$(PYTHON_VERSION)/Parser/grammar1.c\r
+ Python-$(PYTHON_VERSION)/Parser/listnode.c\r
+ Python-$(PYTHON_VERSION)/Parser/metagrammar.c\r
+ Python-$(PYTHON_VERSION)/Parser/myreadline.c\r
+ Python-$(PYTHON_VERSION)/Parser/node.c\r
+ Python-$(PYTHON_VERSION)/Parser/parser.c\r
+ Python-$(PYTHON_VERSION)/Parser/parsetok.c\r
+ Python-$(PYTHON_VERSION)/Parser/tokenizer.c\r
+\r
+#Python\r
+ PyMod-$(PYTHON_VERSION)/Python/getcopyright.c\r
+ PyMod-$(PYTHON_VERSION)/Python/marshal.c\r
+ PyMod-$(PYTHON_VERSION)/Python/import.c\r
+\r
+ Python-$(PYTHON_VERSION)/Python/_warnings.c\r
+ Python-$(PYTHON_VERSION)/Python/Python-ast.c\r
+ Python-$(PYTHON_VERSION)/Python/asdl.c\r
+ Python-$(PYTHON_VERSION)/Python/ast.c\r
+ Python-$(PYTHON_VERSION)/Python/bltinmodule.c\r
+ Python-$(PYTHON_VERSION)/Python/ceval.c\r
+ Python-$(PYTHON_VERSION)/Python/codecs.c\r
+ Python-$(PYTHON_VERSION)/Python/compile.c\r
+ Python-$(PYTHON_VERSION)/Python/dtoa.c\r
+ Python-$(PYTHON_VERSION)/Python/dynload_stub.c\r
+ Python-$(PYTHON_VERSION)/Python/errors.c\r
+ Python-$(PYTHON_VERSION)/Python/formatter_string.c\r
+ Python-$(PYTHON_VERSION)/Python/formatter_unicode.c\r
+ Python-$(PYTHON_VERSION)/Python/frozen.c\r
+ Python-$(PYTHON_VERSION)/Python/future.c\r
+ Python-$(PYTHON_VERSION)/Python/getargs.c\r
+ Python-$(PYTHON_VERSION)/Python/getcompiler.c\r
+ Python-$(PYTHON_VERSION)/Python/getopt.c\r
+ Python-$(PYTHON_VERSION)/Python/getplatform.c\r
+ Python-$(PYTHON_VERSION)/Python/getversion.c\r
+ Python-$(PYTHON_VERSION)/Python/graminit.c\r
+ Python-$(PYTHON_VERSION)/Python/importdl.c\r
+ Python-$(PYTHON_VERSION)/Python/modsupport.c\r
+ Python-$(PYTHON_VERSION)/Python/mysnprintf.c\r
+ Python-$(PYTHON_VERSION)/Python/mystrtoul.c\r
+ Python-$(PYTHON_VERSION)/Python/peephole.c\r
+ Python-$(PYTHON_VERSION)/Python/pyarena.c\r
+ Python-$(PYTHON_VERSION)/Python/pyctype.c\r
+ Python-$(PYTHON_VERSION)/Python/pyfpe.c\r
+ Python-$(PYTHON_VERSION)/Python/pymath.c\r
+ Python-$(PYTHON_VERSION)/Python/pystate.c\r
+ Python-$(PYTHON_VERSION)/Python/pystrcmp.c\r
+ Python-$(PYTHON_VERSION)/Python/pystrtod.c\r
+ Python-$(PYTHON_VERSION)/Python/pythonrun.c\r
+ Python-$(PYTHON_VERSION)/Python/structmember.c\r
+ Python-$(PYTHON_VERSION)/Python/symtable.c\r
+ Python-$(PYTHON_VERSION)/Python/sysmodule.c\r
+ Python-$(PYTHON_VERSION)/Python/traceback.c\r
+\r
+#Objects\r
+ PyMod-$(PYTHON_VERSION)/Objects/longobject.c\r
+\r
+ Python-$(PYTHON_VERSION)/Objects/abstract.c\r
+ Python-$(PYTHON_VERSION)/Objects/boolobject.c\r
+ Python-$(PYTHON_VERSION)/Objects/bufferobject.c\r
+ Python-$(PYTHON_VERSION)/Objects/bytearrayobject.c\r
+ Python-$(PYTHON_VERSION)/Objects/bytes_methods.c\r
+ Python-$(PYTHON_VERSION)/Objects/capsule.c\r
+ Python-$(PYTHON_VERSION)/Objects/cellobject.c\r
+ Python-$(PYTHON_VERSION)/Objects/classobject.c\r
+ Python-$(PYTHON_VERSION)/Objects/cobject.c\r
+ Python-$(PYTHON_VERSION)/Objects/codeobject.c\r
+ Python-$(PYTHON_VERSION)/Objects/complexobject.c\r
+ Python-$(PYTHON_VERSION)/Objects/descrobject.c\r
+ Python-$(PYTHON_VERSION)/Objects/dictobject.c\r
+ Python-$(PYTHON_VERSION)/Objects/enumobject.c\r
+ Python-$(PYTHON_VERSION)/Objects/exceptions.c\r
+ Python-$(PYTHON_VERSION)/Objects/fileobject.c\r
+ Python-$(PYTHON_VERSION)/Objects/floatobject.c\r
+ Python-$(PYTHON_VERSION)/Objects/frameobject.c\r
+ Python-$(PYTHON_VERSION)/Objects/funcobject.c\r
+ Python-$(PYTHON_VERSION)/Objects/genobject.c\r
+ Python-$(PYTHON_VERSION)/Objects/intobject.c\r
+ Python-$(PYTHON_VERSION)/Objects/iterobject.c\r
+ Python-$(PYTHON_VERSION)/Objects/listobject.c\r
+ Python-$(PYTHON_VERSION)/Objects/memoryobject.c\r
+ Python-$(PYTHON_VERSION)/Objects/methodobject.c\r
+ Python-$(PYTHON_VERSION)/Objects/moduleobject.c\r
+ Python-$(PYTHON_VERSION)/Objects/object.c\r
+ Python-$(PYTHON_VERSION)/Objects/obmalloc.c\r
+ Python-$(PYTHON_VERSION)/Objects/rangeobject.c\r
+ Python-$(PYTHON_VERSION)/Objects/setobject.c\r
+ Python-$(PYTHON_VERSION)/Objects/sliceobject.c\r
+ Python-$(PYTHON_VERSION)/Objects/stringobject.c\r
+ Python-$(PYTHON_VERSION)/Objects/structseq.c\r
+ Python-$(PYTHON_VERSION)/Objects/tupleobject.c\r
+ Python-$(PYTHON_VERSION)/Objects/typeobject.c\r
+ Python-$(PYTHON_VERSION)/Objects/unicodectype.c\r
+ Python-$(PYTHON_VERSION)/Objects/unicodeobject.c\r
+ Python-$(PYTHON_VERSION)/Objects/weakrefobject.c\r
+\r
+#Modules -- See Efi/config.c\r
+ # Mandatory Modules -- These must always be built in.\r
+ PyMod-$(PYTHON_VERSION)/Modules/errnomodule.c\r
+ Python-$(PYTHON_VERSION)/Modules/_functoolsmodule.c\r
+ Python-$(PYTHON_VERSION)/Modules/gcmodule.c\r
+ Python-$(PYTHON_VERSION)/Modules/getbuildinfo.c\r
+ PyMod-$(PYTHON_VERSION)/Modules/main.c\r
+ Python-$(PYTHON_VERSION)/Modules/python.c\r
+\r
+ # Optional Modules -- See Python/Efi/config.c\r
+ PyMod-$(PYTHON_VERSION)/Modules/_sre.c #\r
+ PyMod-$(PYTHON_VERSION)/Modules/selectmodule.c #\r
+ #\r
+ Python-$(PYTHON_VERSION)/Modules/_bisectmodule.c #\r
+ Python-$(PYTHON_VERSION)/Modules/_codecsmodule.c #\r
+ Python-$(PYTHON_VERSION)/Modules/_collectionsmodule.c #\r
+ Python-$(PYTHON_VERSION)/Modules/_csv.c #\r
+ Python-$(PYTHON_VERSION)/Modules/_heapqmodule.c #\r
+ Python-$(PYTHON_VERSION)/Modules/_json.c #\r
+ Python-$(PYTHON_VERSION)/Modules/_localemodule.c #\r
+ Python-$(PYTHON_VERSION)/Modules/_math.c #\r
+ Python-$(PYTHON_VERSION)/Modules/_randommodule.c #\r
+ Python-$(PYTHON_VERSION)/Modules/_struct.c #\r
+ Python-$(PYTHON_VERSION)/Modules/_weakref.c #\r
+ Python-$(PYTHON_VERSION)/Modules/arraymodule.c #\r
+ Python-$(PYTHON_VERSION)/Modules/binascii.c #\r
+ Python-$(PYTHON_VERSION)/Modules/cmathmodule.c #\r
+ Python-$(PYTHON_VERSION)/Modules/cPickle.c #\r
+ Python-$(PYTHON_VERSION)/Modules/cStringIO.c #\r
+ Python-$(PYTHON_VERSION)/Modules/datetimemodule.c #\r
+ Python-$(PYTHON_VERSION)/Modules/future_builtins.c #\r
+ Python-$(PYTHON_VERSION)/Modules/itertoolsmodule.c #\r
+ Python-$(PYTHON_VERSION)/Modules/mathmodule.c #\r
+ Python-$(PYTHON_VERSION)/Modules/md5.c #\r
+ Python-$(PYTHON_VERSION)/Modules/md5module.c #\r
+ Python-$(PYTHON_VERSION)/Modules/operator.c #\r
+ Python-$(PYTHON_VERSION)/Modules/parsermodule.c #\r
+ Python-$(PYTHON_VERSION)/Modules/sha256module.c #\r
+ Python-$(PYTHON_VERSION)/Modules/sha512module.c #\r
+ Python-$(PYTHON_VERSION)/Modules/shamodule.c #\r
+ Python-$(PYTHON_VERSION)/Modules/signalmodule.c #\r
+ Python-$(PYTHON_VERSION)/Modules/socketmodule.c #\r
+ Python-$(PYTHON_VERSION)/Modules/stropmodule.c #\r
+ Python-$(PYTHON_VERSION)/Modules/symtablemodule.c #\r
+ Python-$(PYTHON_VERSION)/Modules/timemodule.c #\r
+ Python-$(PYTHON_VERSION)/Modules/unicodedata.c #\r
+ Python-$(PYTHON_VERSION)/Modules/xxsubtype.c #\r
+ Python-$(PYTHON_VERSION)/Modules/zipimport.c #\r
+ Python-$(PYTHON_VERSION)/Modules/zlibmodule.c #\r
+\r
+#Modules/_io\r
+ Python-$(PYTHON_VERSION)/Modules/_io/_iomodule.c #\r
+ Python-$(PYTHON_VERSION)/Modules/_io/bufferedio.c #\r
+ Python-$(PYTHON_VERSION)/Modules/_io/bytesio.c #\r
+ Python-$(PYTHON_VERSION)/Modules/_io/fileio.c #\r
+ Python-$(PYTHON_VERSION)/Modules/_io/iobase.c #\r
+ Python-$(PYTHON_VERSION)/Modules/_io/stringio.c #\r
+ Python-$(PYTHON_VERSION)/Modules/_io/textio.c #\r
+\r
+#Modules/cjkcodecs\r
+ Python-$(PYTHON_VERSION)/Modules/cjkcodecs/multibytecodec.c #\r
+ Python-$(PYTHON_VERSION)/Modules/cjkcodecs/_codecs_cn.c #\r
+ Python-$(PYTHON_VERSION)/Modules/cjkcodecs/_codecs_hk.c #\r
+ Python-$(PYTHON_VERSION)/Modules/cjkcodecs/_codecs_iso2022.c #\r
+ Python-$(PYTHON_VERSION)/Modules/cjkcodecs/_codecs_jp.c #\r
+ Python-$(PYTHON_VERSION)/Modules/cjkcodecs/_codecs_kr.c #\r
+ Python-$(PYTHON_VERSION)/Modules/cjkcodecs/_codecs_tw.c #\r
+\r
+#Modules/expat\r
+ Python-$(PYTHON_VERSION)/Modules/pyexpat.c #\r
+ PyMod-$(PYTHON_VERSION)/Modules/expat/xmlparse.c #\r
+ Python-$(PYTHON_VERSION)/Modules/expat/xmlrole.c #\r
+ Python-$(PYTHON_VERSION)/Modules/expat/xmltok.c #\r
+\r
+#Modules/zlib\r
+ Python-$(PYTHON_VERSION)/Modules/zlib/adler32.c #\r
+ Python-$(PYTHON_VERSION)/Modules/zlib/compress.c #\r
+ Python-$(PYTHON_VERSION)/Modules/zlib/crc32.c #\r
+ Python-$(PYTHON_VERSION)/Modules/zlib/deflate.c #\r
+ Python-$(PYTHON_VERSION)/Modules/zlib/gzio.c #\r
+ Python-$(PYTHON_VERSION)/Modules/zlib/infback.c #\r
+ Python-$(PYTHON_VERSION)/Modules/zlib/inffast.c #\r
+ Python-$(PYTHON_VERSION)/Modules/zlib/inflate.c #\r
+ Python-$(PYTHON_VERSION)/Modules/zlib/inftrees.c #\r
+ Python-$(PYTHON_VERSION)/Modules/zlib/trees.c #\r
+ Python-$(PYTHON_VERSION)/Modules/zlib/uncompr.c #\r
+ Python-$(PYTHON_VERSION)/Modules/zlib/zutil.c #\r
+\r
+[BuildOptions]\r
+ 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\r
+ 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\r
+ 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\r
+ 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\r
+ GCC:*_*_IPF_SYMRENAME_FLAGS = --redefine-syms=$(WORKSPACE)/StdLib/GccSymRename.txt\r
--- /dev/null
+/** @file\r
+ Manually generated Python Configuration file for EDK II.\r
+\r
+ Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials are licensed and made available under\r
+ the terms and conditions of the BSD License that accompanies this distribution.\r
+ The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+**/\r
+#ifndef Py_PYCONFIG_H\r
+#define Py_PYCONFIG_H\r
+\r
+#include <Uefi.h>\r
+\r
+#define PLATFORM "uefi"\r
+\r
+/* Define if building universal (internal helper macro) */\r
+#undef AC_APPLE_UNIVERSAL_BUILD\r
+\r
+/* Define for AIX if your compiler is a genuine IBM xlC/xlC_r and you want\r
+ support for AIX C++ shared extension modules. */\r
+#undef AIX_GENUINE_CPLUSPLUS\r
+\r
+/* Define this if you have AtheOS threads. */\r
+#undef ATHEOS_THREADS\r
+\r
+/* Define this if you have BeOS threads. */\r
+#undef BEOS_THREADS\r
+\r
+/* Define if you have the Mach cthreads package */\r
+#undef C_THREADS\r
+\r
+/* Define if C doubles are 64-bit IEEE 754 binary format, stored in ARM\r
+ mixed-endian order (byte order 45670123) */\r
+#undef DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754\r
+\r
+/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the most\r
+ significant byte first */\r
+#undef DOUBLE_IS_BIG_ENDIAN_IEEE754\r
+\r
+/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the\r
+ least significant byte first */\r
+#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754\r
+\r
+/* Define if --enable-ipv6 is specified */\r
+#undef ENABLE_IPV6\r
+\r
+/* Define if flock needs to be linked with bsd library. */\r
+#undef FLOCK_NEEDS_LIBBSD\r
+\r
+/* Define if getpgrp() must be called as getpgrp(0). */\r
+#undef GETPGRP_HAVE_ARG\r
+\r
+/* Define if gettimeofday() does not have second (timezone) argument This is\r
+ the case on Motorola V4 (R40V4.2) */\r
+#undef GETTIMEOFDAY_NO_TZ\r
+\r
+/* Define to 1 if you have the 'acosh' function. */\r
+#undef HAVE_ACOSH\r
+\r
+/* struct addrinfo (netdb.h) */\r
+#undef HAVE_ADDRINFO\r
+\r
+/* Define to 1 if you have the 'alarm' function. */\r
+#undef HAVE_ALARM\r
+\r
+/* Define this if your time.h defines altzone. */\r
+#undef HAVE_ALTZONE\r
+\r
+/* Define to 1 if you have the 'asinh' function. */\r
+#undef HAVE_ASINH\r
+\r
+/* Define to 1 if you have the <asm/types.h> header file. */\r
+#undef HAVE_ASM_TYPES_H\r
+\r
+/* Define to 1 if you have the 'atanh' function. */\r
+#undef HAVE_ATANH\r
+\r
+/* Define if GCC supports __attribute__((format(PyArg_ParseTuple, 2, 3))) */\r
+#undef HAVE_ATTRIBUTE_FORMAT_PARSETUPLE\r
+\r
+/* Define to 1 if you have the 'bind_textdomain_codeset' function. */\r
+#undef HAVE_BIND_TEXTDOMAIN_CODESET\r
+\r
+/* Define to 1 if you have the <bluetooth/bluetooth.h> header file. */\r
+#undef HAVE_BLUETOOTH_BLUETOOTH_H\r
+\r
+/* Define to 1 if you have the <bluetooth.h> header file. */\r
+#undef HAVE_BLUETOOTH_H\r
+\r
+/* Define if nice() returns success/failure instead of the new priority. */\r
+#undef HAVE_BROKEN_NICE\r
+\r
+/* Define if the system reports an invalid PIPE_BUF value. */\r
+#undef HAVE_BROKEN_PIPE_BUF\r
+\r
+/* Define if poll() sets errno on invalid file descriptors. */\r
+#undef HAVE_BROKEN_POLL\r
+\r
+/* Define if the Posix semaphores do not work on your system */\r
+#define HAVE_BROKEN_POSIX_SEMAPHORES 1\r
+\r
+/* Define if pthread_sigmask() does not work on your system. */\r
+#define HAVE_BROKEN_PTHREAD_SIGMASK 1\r
+\r
+/* define to 1 if your sem_getvalue is broken. */\r
+#define HAVE_BROKEN_SEM_GETVALUE 1\r
+\r
+/* Define this if you have the type _Bool. */\r
+#define HAVE_C99_BOOL 1\r
+\r
+/* Define to 1 if you have the 'chflags' function. */\r
+#undef HAVE_CHFLAGS\r
+\r
+/* Define to 1 if you have the 'chown' function. */\r
+#undef HAVE_CHOWN\r
+\r
+/* Define if you have the 'chroot' function. */\r
+#undef HAVE_CHROOT\r
+\r
+/* Define to 1 if you have the 'clock' function. */\r
+#define HAVE_CLOCK 1\r
+\r
+/* Define to 1 if you have the 'confstr' function. */\r
+#undef HAVE_CONFSTR\r
+\r
+/* Define to 1 if you have the <conio.h> header file. */\r
+#undef HAVE_CONIO_H\r
+\r
+/* Define to 1 if you have the 'copysign' function. */\r
+#undef HAVE_COPYSIGN\r
+\r
+/* Define to 1 if you have the 'ctermid' function. */\r
+#undef HAVE_CTERMID\r
+\r
+/* Define if you have the 'ctermid_r' function. */\r
+#undef HAVE_CTERMID_R\r
+\r
+/* Define to 1 if you have the <curses.h> header file. */\r
+#undef HAVE_CURSES_H\r
+\r
+/* Define if you have the 'is_term_resized' function. */\r
+#undef HAVE_CURSES_IS_TERM_RESIZED\r
+\r
+/* Define if you have the 'resizeterm' function. */\r
+#undef HAVE_CURSES_RESIZETERM\r
+\r
+/* Define if you have the 'resize_term' function. */\r
+#undef HAVE_CURSES_RESIZE_TERM\r
+\r
+/* Define to 1 if you have the declaration of 'isfinite', and to 0 if you\r
+ don't. */\r
+#define HAVE_DECL_ISFINITE 0\r
+\r
+/* Define to 1 if you have the declaration of 'isinf', and to 0 if you don't.\r
+ */\r
+#define HAVE_DECL_ISINF 1\r
+\r
+/* Define to 1 if you have the declaration of 'isnan', and to 0 if you don't.\r
+ */\r
+#define HAVE_DECL_ISNAN 1\r
+\r
+/* Define to 1 if you have the declaration of 'tzname', and to 0 if you don't.\r
+ */\r
+#define HAVE_DECL_TZNAME 0\r
+\r
+/* Define to 1 if you have the device macros. */\r
+#undef HAVE_DEVICE_MACROS\r
+\r
+/* Define if we have /dev/ptc. */\r
+#undef HAVE_DEV_PTC\r
+\r
+/* Define if we have /dev/ptmx. */\r
+#undef HAVE_DEV_PTMX\r
+\r
+/* Define to 1 if you have the <direct.h> header file. */\r
+#undef HAVE_DIRECT_H\r
+\r
+/* Define to 1 if you have the <dirent.h> header file, and it defines 'DIR'.\r
+ */\r
+#define HAVE_DIRENT_H 1\r
+\r
+/* Define to 1 if you have the <dlfcn.h> header file. */\r
+#undef HAVE_DLFCN_H\r
+\r
+/* Define to 1 if you have the 'dlopen' function. */\r
+#undef HAVE_DLOPEN\r
+\r
+/* Define to 1 if you have the 'dup2' function. */\r
+#define HAVE_DUP2 1\r
+\r
+/* Defined when any dynamic module loading is enabled. */\r
+#undef HAVE_DYNAMIC_LOADING\r
+\r
+/* Define if you have the 'epoll' functions. */\r
+#undef HAVE_EPOLL\r
+\r
+/* Define to 1 if you have the 'erf' function. */\r
+#undef HAVE_ERF\r
+\r
+/* Define to 1 if you have the 'erfc' function. */\r
+#undef HAVE_ERFC\r
+\r
+/* Define to 1 if you have the <errno.h> header file. */\r
+#define HAVE_ERRNO_H 1\r
+\r
+/* Define to 1 if you have the 'execv' function. */\r
+#undef HAVE_EXECV\r
+\r
+/* Define to 1 if you have the 'expm1' function. */\r
+#undef HAVE_EXPM1\r
+\r
+/* Define if you have the 'fchdir' function. */\r
+#undef HAVE_FCHDIR\r
+\r
+/* Define to 1 if you have the 'fchmod' function. */\r
+#undef HAVE_FCHMOD\r
+\r
+/* Define to 1 if you have the 'fchown' function. */\r
+#undef HAVE_FCHOWN\r
+\r
+/* Define to 1 if you have the <fcntl.h> header file. */\r
+#define HAVE_FCNTL_H 1\r
+\r
+/* Define if you have the 'fdatasync' function. */\r
+#undef HAVE_FDATASYNC\r
+\r
+/* Define to 1 if you have the 'finite' function. */\r
+#define HAVE_FINITE 1\r
+\r
+/* Define to 1 if you have the 'flock' function. */\r
+#undef HAVE_FLOCK\r
+\r
+/* Define to 1 if you have the 'fork' function. */\r
+#undef HAVE_FORK\r
+\r
+/* Define to 1 if you have the 'forkpty' function. */\r
+#undef HAVE_FORKPTY\r
+\r
+/* Define to 1 if you have the 'fpathconf' function. */\r
+#undef HAVE_FPATHCONF\r
+\r
+/* Define to 1 if you have the 'fseek64' function. */\r
+#undef HAVE_FSEEK64\r
+\r
+/* Define to 1 if you have the 'fseeko' function. */\r
+#define HAVE_FSEEKO 1\r
+\r
+/* Define to 1 if you have the 'fstatvfs' function. */\r
+#undef HAVE_FSTATVFS\r
+\r
+/* Define if you have the 'fsync' function. */\r
+#undef HAVE_FSYNC\r
+\r
+/* Define to 1 if you have the 'ftell64' function. */\r
+#undef HAVE_FTELL64\r
+\r
+/* Define to 1 if you have the 'ftello' function. */\r
+#define HAVE_FTELLO 1\r
+\r
+/* Define to 1 if you have the 'ftime' function. */\r
+#undef HAVE_FTIME\r
+\r
+/* Define to 1 if you have the 'ftruncate' function. */\r
+#undef HAVE_FTRUNCATE\r
+\r
+/* Define to 1 if you have the 'gai_strerror' function. */\r
+#undef HAVE_GAI_STRERROR\r
+\r
+/* Define to 1 if you have the 'gamma' function. */\r
+#undef HAVE_GAMMA\r
+\r
+/* Define if we can use gcc inline assembler to get and set x87 control word\r
+*/\r
+#if defined(__GNUC__)\r
+ #define HAVE_GCC_ASM_FOR_X87 1\r
+#else\r
+ #undef HAVE_GCC_ASM_FOR_X87\r
+#endif\r
+\r
+/* Define if you have the getaddrinfo function. */\r
+#undef HAVE_GETADDRINFO\r
+\r
+/* Define to 1 if you have the 'getcwd' function. */\r
+#define HAVE_GETCWD 1\r
+\r
+/* Define this if you have flockfile(), getc_unlocked(), and funlockfile() */\r
+#undef HAVE_GETC_UNLOCKED\r
+\r
+/* Define to 1 if you have the 'getgroups' function. */\r
+#undef HAVE_GETGROUPS\r
+\r
+/* Define to 1 if you have the 'gethostbyname' function. */\r
+#undef HAVE_GETHOSTBYNAME\r
+\r
+/* Define this if you have some version of gethostbyname_r() */\r
+#undef HAVE_GETHOSTBYNAME_R\r
+\r
+/* Define this if you have the 3-arg version of gethostbyname_r(). */\r
+#undef HAVE_GETHOSTBYNAME_R_3_ARG\r
+\r
+/* Define this if you have the 5-arg version of gethostbyname_r(). */\r
+#undef HAVE_GETHOSTBYNAME_R_5_ARG\r
+\r
+/* Define this if you have the 6-arg version of gethostbyname_r(). */\r
+#undef HAVE_GETHOSTBYNAME_R_6_ARG\r
+\r
+/* Define to 1 if you have the 'getitimer' function. */\r
+#undef HAVE_GETITIMER\r
+\r
+/* Define to 1 if you have the 'getloadavg' function. */\r
+#undef HAVE_GETLOADAVG\r
+\r
+/* Define to 1 if you have the 'getlogin' function. */\r
+#undef HAVE_GETLOGIN\r
+\r
+/* Define to 1 if you have the 'getnameinfo' function. */\r
+#undef HAVE_GETNAMEINFO\r
+\r
+/* Define if you have the 'getpagesize' function. */\r
+#undef HAVE_GETPAGESIZE\r
+\r
+/* Define to 1 if you have the 'getpeername' function. */\r
+#define HAVE_GETPEERNAME 1\r
+\r
+/* Define to 1 if you have the 'getpgid' function. */\r
+#undef HAVE_GETPGID\r
+\r
+/* Define to 1 if you have the 'getpgrp' function. */\r
+#undef HAVE_GETPGRP\r
+\r
+/* Define to 1 if you have the 'getpid' function. */\r
+#undef HAVE_GETPID\r
+\r
+/* Define to 1 if you have the 'getpriority' function. */\r
+#undef HAVE_GETPRIORITY\r
+\r
+/* Define to 1 if you have the 'getpwent' function. */\r
+#undef HAVE_GETPWENT\r
+\r
+/* Define to 1 if you have the 'getresgid' function. */\r
+#undef HAVE_GETRESGID\r
+\r
+/* Define to 1 if you have the 'getresuid' function. */\r
+#undef HAVE_GETRESUID\r
+\r
+/* Define to 1 if you have the 'getsid' function. */\r
+#undef HAVE_GETSID\r
+\r
+/* Define to 1 if you have the 'getspent' function. */\r
+#undef HAVE_GETSPENT\r
+\r
+/* Define to 1 if you have the 'getspnam' function. */\r
+#undef HAVE_GETSPNAM\r
+\r
+/* Define to 1 if you have the 'gettimeofday' function. */\r
+#undef HAVE_GETTIMEOFDAY\r
+\r
+/* Define to 1 if you have the 'getwd' function. */\r
+#undef HAVE_GETWD\r
+\r
+/* Define to 1 if you have the <grp.h> header file. */\r
+#undef HAVE_GRP_H\r
+\r
+/* Define if you have the 'hstrerror' function. */\r
+#undef HAVE_HSTRERROR\r
+\r
+/* Define to 1 if you have the 'hypot' function. */\r
+#undef HAVE_HYPOT\r
+\r
+/* Define to 1 if you have the <ieeefp.h> header file. */\r
+#undef HAVE_IEEEFP_H\r
+\r
+/* Define if you have the 'inet_aton' function. */\r
+#define HAVE_INET_ATON 1\r
+\r
+/* Define if you have the 'inet_pton' function. */\r
+#define HAVE_INET_PTON 1\r
+\r
+/* Define to 1 if you have the 'initgroups' function. */\r
+#undef HAVE_INITGROUPS\r
+\r
+/* Define to 1 if you have the <inttypes.h> header file. */\r
+#define HAVE_INTTYPES_H 1\r
+\r
+/* Define to 1 if you have the <io.h> header file. */\r
+#undef HAVE_IO_H\r
+\r
+/* Define to 1 if you have the 'kill' function. */\r
+#undef HAVE_KILL\r
+\r
+/* Define to 1 if you have the 'killpg' function. */\r
+#undef HAVE_KILLPG\r
+\r
+/* Define if you have the 'kqueue' functions. */\r
+#undef HAVE_KQUEUE\r
+\r
+/* Define to 1 if you have the <langinfo.h> header file. */\r
+#undef HAVE_LANGINFO_H /* non-functional in EFI. */\r
+\r
+/* Defined to enable large file support when an off_t is bigger than a long\r
+ and long long is available and at least as big as an off_t. You may need to\r
+ add some flags for configuration and compilation to enable this mode. (For\r
+ Solaris and Linux, the necessary defines are already defined.) */\r
+#undef HAVE_LARGEFILE_SUPPORT\r
+\r
+/* Define to 1 if you have the 'lchflags' function. */\r
+#undef HAVE_LCHFLAGS\r
+\r
+/* Define to 1 if you have the 'lchmod' function. */\r
+#undef HAVE_LCHMOD\r
+\r
+/* Define to 1 if you have the 'lchown' function. */\r
+#undef HAVE_LCHOWN\r
+\r
+/* Define to 1 if you have the 'lgamma' function. */\r
+#undef HAVE_LGAMMA\r
+\r
+/* Define to 1 if you have the 'dl' library (-ldl). */\r
+#undef HAVE_LIBDL\r
+\r
+/* Define to 1 if you have the 'dld' library (-ldld). */\r
+#undef HAVE_LIBDLD\r
+\r
+/* Define to 1 if you have the 'ieee' library (-lieee). */\r
+#undef HAVE_LIBIEEE\r
+\r
+/* Define to 1 if you have the <libintl.h> header file. */\r
+#undef HAVE_LIBINTL_H\r
+\r
+/* Define if you have the readline library (-lreadline). */\r
+#undef HAVE_LIBREADLINE\r
+\r
+/* Define to 1 if you have the 'resolv' library (-lresolv). */\r
+#undef HAVE_LIBRESOLV\r
+\r
+/* Define to 1 if you have the <libutil.h> header file. */\r
+#undef HAVE_LIBUTIL_H\r
+\r
+/* Define if you have the 'link' function. */\r
+#undef HAVE_LINK\r
+\r
+/* Define to 1 if you have the <linux/netlink.h> header file. */\r
+#undef HAVE_LINUX_NETLINK_H\r
+\r
+/* Define to 1 if you have the <linux/tipc.h> header file. */\r
+#undef HAVE_LINUX_TIPC_H\r
+\r
+/* Define to 1 if you have the 'log1p' function. */\r
+#undef HAVE_LOG1P\r
+\r
+/* Define this if you have the type long double. */\r
+#undef HAVE_LONG_DOUBLE\r
+\r
+/* Define this if you have the type long long. */\r
+#define HAVE_LONG_LONG 1\r
+\r
+/* Define to 1 if you have the 'lstat' function. */\r
+#define HAVE_LSTAT 1\r
+\r
+/* Define this if you have the makedev macro. */\r
+#undef HAVE_MAKEDEV\r
+\r
+/* Define to 1 if you have the 'memmove' function. */\r
+#define HAVE_MEMMOVE 1\r
+\r
+/* Define to 1 if you have the <memory.h> header file. */\r
+#undef HAVE_MEMORY_H\r
+\r
+/* Define to 1 if you have the 'mkfifo' function. */\r
+#undef HAVE_MKFIFO\r
+\r
+/* Define to 1 if you have the 'mknod' function. */\r
+#undef HAVE_MKNOD\r
+\r
+/* Define to 1 if you have the 'mktime' function. */\r
+#define HAVE_MKTIME 1\r
+\r
+/* Define to 1 if you have the 'mremap' function. */\r
+#undef HAVE_MREMAP\r
+\r
+/* Define to 1 if you have the <ncurses.h> header file. */\r
+#undef HAVE_NCURSES_H\r
+\r
+/* Define to 1 if you have the <ndir.h> header file, and it defines 'DIR'. */\r
+#undef HAVE_NDIR_H\r
+\r
+/* Define to 1 if you have the <netpacket/packet.h> header file. */\r
+#undef HAVE_NETPACKET_PACKET_H\r
+\r
+/* Define to 1 if you have the 'nice' function. */\r
+#undef HAVE_NICE\r
+\r
+/* Define to 1 if you have the 'openpty' function. */\r
+#undef HAVE_OPENPTY\r
+\r
+/* Define if compiling using MacOS X 10.5 SDK or later. */\r
+#undef HAVE_OSX105_SDK\r
+\r
+/* Define to 1 if you have the 'pathconf' function. */\r
+#undef HAVE_PATHCONF\r
+\r
+/* Define to 1 if you have the 'pause' function. */\r
+#undef HAVE_PAUSE\r
+\r
+/* Define to 1 if you have the 'plock' function. */\r
+#undef HAVE_PLOCK\r
+\r
+/* Define to 1 if you have the 'poll' function. */\r
+#define HAVE_POLL 1\r
+\r
+/* Define to 1 if you have the <poll.h> header file. */\r
+#undef HAVE_POLL_H\r
+\r
+/* Define to 1 if you have the <process.h> header file. */\r
+#undef HAVE_PROCESS_H\r
+\r
+/* Define if your compiler supports function prototype */\r
+#define HAVE_PROTOTYPES 1\r
+\r
+/* Define if you have GNU PTH threads. */\r
+#undef HAVE_PTH\r
+\r
+/* Defined for Solaris 2.6 bug in pthread header. */\r
+#undef HAVE_PTHREAD_DESTRUCTOR\r
+\r
+/* Define to 1 if you have the <pthread.h> header file. */\r
+#undef HAVE_PTHREAD_H\r
+\r
+/* Define to 1 if you have the 'pthread_init' function. */\r
+#undef HAVE_PTHREAD_INIT\r
+\r
+/* Define to 1 if you have the 'pthread_sigmask' function. */\r
+#undef HAVE_PTHREAD_SIGMASK\r
+\r
+/* Define to 1 if you have the <pty.h> header file. */\r
+#undef HAVE_PTY_H\r
+\r
+/* Define to 1 if you have the 'putenv' function. */\r
+#undef HAVE_PUTENV\r
+\r
+/* Define to 1 if you have the 'readlink' function. */\r
+#undef HAVE_READLINK\r
+\r
+/* Define to 1 if you have the 'realpath' function. */\r
+#define HAVE_REALPATH 1\r
+\r
+/* Define if you have readline 2.1 */\r
+#undef HAVE_RL_CALLBACK\r
+\r
+/* Define if you can turn off readline's signal handling. */\r
+#undef HAVE_RL_CATCH_SIGNAL\r
+\r
+/* Define if you have readline 2.2 */\r
+#undef HAVE_RL_COMPLETION_APPEND_CHARACTER\r
+\r
+/* Define if you have readline 4.0 */\r
+#undef HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK\r
+\r
+/* Define if you have readline 4.2 */\r
+#undef HAVE_RL_COMPLETION_MATCHES\r
+\r
+/* Define if you have rl_completion_suppress_append */\r
+#undef HAVE_RL_COMPLETION_SUPPRESS_APPEND\r
+\r
+/* Define if you have readline 4.0 */\r
+#undef HAVE_RL_PRE_INPUT_HOOK\r
+\r
+/* Define to 1 if you have the 'round' function. */\r
+#undef HAVE_ROUND\r
+\r
+/* Define to 1 if you have the 'select' function. */\r
+#define HAVE_SELECT 1\r
+\r
+/* Define to 1 if you have the 'sem_getvalue' function. */\r
+#undef HAVE_SEM_GETVALUE\r
+\r
+/* Define to 1 if you have the 'sem_open' function. */\r
+#undef HAVE_SEM_OPEN\r
+\r
+/* Define to 1 if you have the 'sem_timedwait' function. */\r
+#undef HAVE_SEM_TIMEDWAIT\r
+\r
+/* Define to 1 if you have the 'sem_unlink' function. */\r
+#undef HAVE_SEM_UNLINK\r
+\r
+/* Define to 1 if you have the 'setegid' function. */\r
+#undef HAVE_SETEGID\r
+\r
+/* Define to 1 if you have the 'seteuid' function. */\r
+#undef HAVE_SETEUID\r
+\r
+/* Define to 1 if you have the 'setgid' function. */\r
+#undef HAVE_SETGID\r
+\r
+/* Define if you have the 'setgroups' function. */\r
+#undef HAVE_SETGROUPS\r
+\r
+/* Define to 1 if you have the 'setitimer' function. */\r
+#undef HAVE_SETITIMER\r
+\r
+/* Define to 1 if you have the 'setlocale' function. */\r
+#define HAVE_SETLOCALE 1\r
+\r
+/* Define to 1 if you have the 'setpgid' function. */\r
+#undef HAVE_SETPGID\r
+\r
+/* Define to 1 if you have the 'setpgrp' function. */\r
+#undef HAVE_SETPGRP\r
+\r
+/* Define to 1 if you have the 'setregid' function. */\r
+#undef HAVE_SETREGID\r
+\r
+/* Define to 1 if you have the 'setresgid' function. */\r
+#undef HAVE_SETRESGID\r
+\r
+/* Define to 1 if you have the 'setresuid' function. */\r
+#undef HAVE_SETRESUID\r
+\r
+/* Define to 1 if you have the 'setreuid' function. */\r
+#undef HAVE_SETREUID\r
+\r
+/* Define to 1 if you have the 'setsid' function. */\r
+#undef HAVE_SETSID\r
+\r
+/* Define to 1 if you have the 'setuid' function. */\r
+#undef HAVE_SETUID\r
+\r
+/* Define to 1 if you have the 'setvbuf' function. */\r
+#define HAVE_SETVBUF 1\r
+\r
+/* Define to 1 if you have the <shadow.h> header file. */\r
+#undef HAVE_SHADOW_H\r
+\r
+/* Define to 1 if you have the 'sigaction' function. */\r
+#undef HAVE_SIGACTION\r
+\r
+/* Define to 1 if you have the 'siginterrupt' function. */\r
+#undef HAVE_SIGINTERRUPT\r
+\r
+/* Define to 1 if you have the <signal.h> header file. */\r
+#define HAVE_SIGNAL_H 1\r
+\r
+/* Define to 1 if you have the 'sigrelse' function. */\r
+#undef HAVE_SIGRELSE\r
+\r
+/* Define to 1 if you have the 'snprintf' function. */\r
+#define HAVE_SNPRINTF 1\r
+\r
+/* Define if sockaddr has sa_len member */\r
+#undef HAVE_SOCKADDR_SA_LEN\r
+\r
+/* struct sockaddr_storage (sys/socket.h) */\r
+#undef HAVE_SOCKADDR_STORAGE\r
+\r
+/* Define if you have the 'socketpair' function. */\r
+#undef HAVE_SOCKETPAIR\r
+\r
+/* Define to 1 if you have the <spawn.h> header file. */\r
+#undef HAVE_SPAWN_H\r
+\r
+/* Define if your compiler provides ssize_t */\r
+#define HAVE_SSIZE_T 1\r
+\r
+/* Define to 1 if you have the 'statvfs' function. */\r
+#undef HAVE_STATVFS\r
+\r
+/* Define if you have struct stat.st_mtim.tv_nsec */\r
+#undef HAVE_STAT_TV_NSEC\r
+\r
+/* Define if you have struct stat.st_mtimensec */\r
+#undef HAVE_STAT_TV_NSEC2\r
+\r
+/* Define if your compiler supports variable length function prototypes (e.g.\r
+ void fprintf(FILE *, char *, ...);) *and* <stdarg.h> */\r
+#define HAVE_STDARG_PROTOTYPES 1\r
+\r
+/* Define to 1 if you have the <stdint.h> header file. */\r
+#define HAVE_STDINT_H 1\r
+\r
+/* Define to 1 if you have the <stdlib.h> header file. */\r
+#define HAVE_STDLIB_H 1\r
+\r
+/* Define to 1 if you have the 'strdup' function. */\r
+#define HAVE_STRDUP 1\r
+\r
+/* Define to 1 if you have the 'strftime' function. */\r
+#define HAVE_STRFTIME 1\r
+\r
+/* Define to 1 if you have the <strings.h> header file. */\r
+#undef HAVE_STRINGS_H\r
+\r
+/* Define to 1 if you have the <string.h> header file. */\r
+#define HAVE_STRING_H 1\r
+\r
+/* Define to 1 if you have the <stropts.h> header file. */\r
+#undef HAVE_STROPTS_H\r
+\r
+/* Define to 1 if 'st_birthtime' is a member of 'struct stat'. */\r
+#define HAVE_STRUCT_STAT_ST_BIRTHTIME 1\r
+\r
+/* Define to 1 if 'st_blksize' is a member of 'struct stat'. */\r
+#define HAVE_STRUCT_STAT_ST_BLKSIZE 1\r
+\r
+/* Define to 1 if 'st_blocks' is a member of 'struct stat'. */\r
+#undef HAVE_STRUCT_STAT_ST_BLOCKS\r
+\r
+/* Define to 1 if 'st_flags' is a member of 'struct stat'. */\r
+#undef HAVE_STRUCT_STAT_ST_FLAGS\r
+\r
+/* Define to 1 if 'st_gen' is a member of 'struct stat'. */\r
+#undef HAVE_STRUCT_STAT_ST_GEN\r
+\r
+/* Define to 1 if 'st_rdev' is a member of 'struct stat'. */\r
+#undef HAVE_STRUCT_STAT_ST_RDEV\r
+\r
+/* Define to 1 if 'tm_zone' is a member of 'struct tm'. */\r
+#undef HAVE_STRUCT_TM_TM_ZONE\r
+\r
+/* Define to 1 if your 'struct stat' has 'st_blocks'. Deprecated, use\r
+ 'HAVE_STRUCT_STAT_ST_BLOCKS' instead. */\r
+#undef HAVE_ST_BLOCKS\r
+\r
+/* Define if you have the 'symlink' function. */\r
+#undef HAVE_SYMLINK\r
+\r
+/* Define to 1 if you have the 'sysconf' function. */\r
+#undef HAVE_SYSCONF\r
+\r
+/* Define to 1 if you have the <sysexits.h> header file. */\r
+#undef HAVE_SYSEXITS_H\r
+\r
+/* Define to 1 if you have the <sys/audioio.h> header file. */\r
+#undef HAVE_SYS_AUDIOIO_H\r
+\r
+/* Define to 1 if you have the <sys/bsdtty.h> header file. */\r
+#undef HAVE_SYS_BSDTTY_H\r
+\r
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines 'DIR'.\r
+ */\r
+#undef HAVE_SYS_DIR_H\r
+\r
+/* Define to 1 if you have the <sys/epoll.h> header file. */\r
+#undef HAVE_SYS_EPOLL_H\r
+\r
+/* Define to 1 if you have the <sys/event.h> header file. */\r
+#undef HAVE_SYS_EVENT_H\r
+\r
+/* Define to 1 if you have the <sys/file.h> header file. */\r
+#undef HAVE_SYS_FILE_H\r
+\r
+/* Define to 1 if you have the <sys/loadavg.h> header file. */\r
+#undef HAVE_SYS_LOADAVG_H\r
+\r
+/* Define to 1 if you have the <sys/lock.h> header file. */\r
+#undef HAVE_SYS_LOCK_H\r
+\r
+/* Define to 1 if you have the <sys/mkdev.h> header file. */\r
+#undef HAVE_SYS_MKDEV_H\r
+\r
+/* Define to 1 if you have the <sys/modem.h> header file. */\r
+#undef HAVE_SYS_MODEM_H\r
+\r
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines 'DIR'.\r
+ */\r
+#undef HAVE_SYS_NDIR_H\r
+\r
+/* Define to 1 if you have the <sys/param.h> header file. */\r
+#define HAVE_SYS_PARAM_H 1\r
+\r
+/* Define to 1 if you have the <sys/poll.h> header file. */\r
+#define HAVE_SYS_POLL_H 1\r
+\r
+/* Define to 1 if you have the <sys/resource.h> header file. */\r
+#define HAVE_SYS_RESOURCE_H 1\r
+\r
+/* Define to 1 if you have the <sys/select.h> header file. */\r
+#define HAVE_SYS_SELECT_H 1\r
+\r
+/* Define to 1 if you have the <sys/socket.h> header file. */\r
+#define HAVE_SYS_SOCKET_H 1\r
+\r
+/* Define to 1 if you have the <sys/statvfs.h> header file. */\r
+#undef HAVE_SYS_STATVFS_H\r
+\r
+/* Define to 1 if you have the <sys/stat.h> header file. */\r
+#define HAVE_SYS_STAT_H 1\r
+\r
+/* Define to 1 if you have the <sys/termio.h> header file. */\r
+#undef HAVE_SYS_TERMIO_H\r
+\r
+/* Define to 1 if you have the <sys/times.h> header file. */\r
+#undef HAVE_SYS_TIMES_H\r
+\r
+/* Define to 1 if you have the <sys/time.h> header file. */\r
+#define HAVE_SYS_TIME_H 1\r
+\r
+/* Define to 1 if you have the <sys/types.h> header file. */\r
+#define HAVE_SYS_TYPES_H 1\r
+\r
+/* Define to 1 if you have the <sys/un.h> header file. */\r
+#undef HAVE_SYS_UN_H\r
+\r
+/* Define to 1 if you have the <sys/utsname.h> header file. */\r
+#undef HAVE_SYS_UTSNAME_H\r
+\r
+/* Define to 1 if you have the <sys/wait.h> header file. */\r
+#undef HAVE_SYS_WAIT_H\r
+\r
+/* Define to 1 if you have the system() command. */\r
+#define HAVE_SYSTEM 1\r
+\r
+/* Define to 1 if you have the 'tcgetpgrp' function. */\r
+#undef HAVE_TCGETPGRP\r
+\r
+/* Define to 1 if you have the 'tcsetpgrp' function. */\r
+#undef HAVE_TCSETPGRP\r
+\r
+/* Define to 1 if you have the 'tempnam' function. */\r
+#define HAVE_TEMPNAM 1\r
+\r
+/* Define to 1 if you have the <termios.h> header file. */\r
+#undef HAVE_TERMIOS_H\r
+\r
+/* Define to 1 if you have the <term.h> header file. */\r
+#undef HAVE_TERM_H\r
+\r
+/* Define to 1 if you have the 'tgamma' function. */\r
+#undef HAVE_TGAMMA\r
+\r
+/* Define to 1 if you have the <thread.h> header file. */\r
+#undef HAVE_THREAD_H\r
+\r
+/* Define to 1 if you have the 'timegm' function. */\r
+#undef HAVE_TIMEGM\r
+\r
+/* Define to 1 if you have the 'times' function. */\r
+#undef HAVE_TIMES\r
+\r
+/* Define to 1 if you have the 'tmpfile' function. */\r
+#define HAVE_TMPFILE 1\r
+\r
+/* Define to 1 if you have the 'tmpnam' function. */\r
+#define HAVE_TMPNAM 1\r
+\r
+/* Define to 1 if you have the 'tmpnam_r' function. */\r
+#undef HAVE_TMPNAM_R\r
+\r
+/* Define to 1 if your 'struct tm' has 'tm_zone'. Deprecated, use\r
+ 'HAVE_STRUCT_TM_TM_ZONE' instead. */\r
+#undef HAVE_TM_ZONE\r
+\r
+/* Define to 1 if you have the 'truncate' function. */\r
+#undef HAVE_TRUNCATE\r
+\r
+/* Define to 1 if you don't have 'tm_zone' but do have the external array\r
+ 'tzname'. */\r
+#undef HAVE_TZNAME\r
+\r
+/* Define this if you have tcl and TCL_UTF_MAX==6 */\r
+#undef HAVE_UCS4_TCL\r
+\r
+/* Define to 1 if the system has the type 'uintptr_t'. */\r
+#define HAVE_UINTPTR_T 1\r
+\r
+/* Define to 1 if you have the 'uname' function. */\r
+#undef HAVE_UNAME\r
+\r
+/* Define to 1 if you have the <unistd.h> header file. */\r
+#define HAVE_UNISTD_H 1\r
+\r
+/* Define to 1 if you have the 'unsetenv' function. */\r
+#undef HAVE_UNSETENV\r
+\r
+/* Define if you have a useable wchar_t type defined in wchar.h; useable means\r
+ wchar_t must be an unsigned type with at least 16 bits. (see\r
+ Include/unicodeobject.h). */\r
+#define HAVE_USABLE_WCHAR_T 1\r
+\r
+/* Define to 1 if you have the <util.h> header file. */\r
+#undef HAVE_UTIL_H\r
+\r
+/* Define to 1 if you have the 'utimes' function. */\r
+#undef HAVE_UTIMES\r
+\r
+/* Define to 1 if you have the <utime.h> header file. */\r
+#define HAVE_UTIME_H 1\r
+\r
+/* Define to 1 if you have the 'wait3' function. */\r
+#undef HAVE_WAIT3\r
+\r
+/* Define to 1 if you have the 'wait4' function. */\r
+#undef HAVE_WAIT4\r
+\r
+/* Define to 1 if you have the 'waitpid' function. */\r
+#undef HAVE_WAITPID\r
+\r
+/* Define if the compiler provides a wchar.h header file. */\r
+#define HAVE_WCHAR_H 1\r
+\r
+/* Define to 1 if you have the 'wcscoll' function. */\r
+#define HAVE_WCSCOLL 1\r
+\r
+/* Define if tzset() actually switches the local timezone in a meaningful way.\r
+ */\r
+#undef HAVE_WORKING_TZSET\r
+\r
+/* Define if the zlib library has inflateCopy */\r
+#undef HAVE_ZLIB_COPY\r
+\r
+/* Define to 1 if you have the '_getpty' function. */\r
+#undef HAVE__GETPTY\r
+\r
+/* Define if you are using Mach cthreads directly under /include */\r
+#undef HURD_C_THREADS\r
+\r
+/* Define if you are using Mach cthreads under mach / */\r
+#undef MACH_C_THREADS\r
+\r
+/* Define to 1 if 'major', 'minor', and 'makedev' are declared in <mkdev.h>.\r
+ */\r
+#undef MAJOR_IN_MKDEV\r
+\r
+/* Define to 1 if 'major', 'minor', and 'makedev' are declared in\r
+ <sysmacros.h>. */\r
+#undef MAJOR_IN_SYSMACROS\r
+\r
+/* Define if mvwdelch in curses.h is an expression. */\r
+#undef MVWDELCH_IS_EXPRESSION\r
+\r
+/* Define to the address where bug reports for this package should be sent. */\r
+#define PACKAGE_BUGREPORT "edk2-devel@lists.sourceforge.net"\r
+\r
+/* Define to the full name of this package. */\r
+#define PACKAGE_NAME "EDK II Python Package"\r
+\r
+/* Define to the full name and version of this package. */\r
+#define PACKAGE_STRING "EDK II Python Package V0.8"\r
+\r
+/* Define to the one symbol short name of this package. */\r
+#define PACKAGE_TARNAME "EADK_Python"\r
+\r
+/* Define to the home page for this package. */\r
+#define PACKAGE_URL "http://edk2.tianocore.org/toolkit/python"\r
+\r
+/* Define to the version of this package. */\r
+#define PACKAGE_VERSION "V0.8"\r
+\r
+/* Define if POSIX semaphores aren't enabled on your system */\r
+#define POSIX_SEMAPHORES_NOT_ENABLED 1\r
+\r
+/* Defined if PTHREAD_SCOPE_SYSTEM supported. */\r
+#undef PTHREAD_SYSTEM_SCHED_SUPPORTED\r
+\r
+/* Define as the preferred size in bits of long digits */\r
+#undef PYLONG_BITS_IN_DIGIT\r
+\r
+/* Define to printf format modifier for long long type */\r
+#define PY_FORMAT_LONG_LONG "ll"\r
+\r
+/* Define to printf format modifier for Py_ssize_t */\r
+#define PY_FORMAT_SIZE_T "z"\r
+\r
+/* Define as the integral type used for Unicode representation. */\r
+#define PY_UNICODE_TYPE wchar_t\r
+\r
+/* Define if you want to build an interpreter with many run-time checks. */\r
+#undef Py_DEBUG\r
+\r
+/* Defined if Python is built as a shared library. */\r
+#undef Py_ENABLE_SHARED\r
+\r
+/* Define as the size of the unicode type. */\r
+#define Py_UNICODE_SIZE 2\r
+\r
+/* Define if you want to have a Unicode type. */\r
+#define Py_USING_UNICODE\r
+\r
+/* assume C89 semantics that RETSIGTYPE is always void */\r
+#undef RETSIGTYPE\r
+\r
+/* Define if setpgrp() must be called as setpgrp(0, 0). */\r
+#undef SETPGRP_HAVE_ARG\r
+\r
+/* Define this to be extension of shared libraries (including the dot!). */\r
+#undef SHLIB_EXT\r
+\r
+/* Define if i>>j for signed int i does not extend the sign bit when i < 0 */\r
+#undef SIGNED_RIGHT_SHIFT_ZERO_FILLS\r
+\r
+/* The size of 'double', as computed by sizeof. */\r
+#define SIZEOF_DOUBLE 8\r
+\r
+/* The size of 'float', as computed by sizeof. */\r
+#define SIZEOF_FLOAT 4\r
+\r
+/* The size of 'fpos_t', as computed by sizeof. */\r
+#define SIZEOF_FPOS_T 8\r
+\r
+/* The size of 'int', as computed by sizeof. */\r
+#define SIZEOF_INT 4\r
+\r
+/* The size of 'long', as computed by sizeof. */\r
+#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */\r
+#define SIZEOF_LONG 4\r
+#else\r
+#define SIZEOF_LONG 8\r
+#endif\r
+\r
+/* The size of 'long double', as computed by sizeof. */\r
+#undef SIZEOF_LONG_DOUBLE\r
+\r
+/* The size of 'long long', as computed by sizeof. */\r
+#define SIZEOF_LONG_LONG 8\r
+\r
+/* The size of 'off_t', as computed by sizeof. */\r
+#define SIZEOF_OFF_T 8\r
+\r
+/* The size of 'pid_t', as computed by sizeof. */\r
+#define SIZEOF_PID_T 4\r
+\r
+/* The size of 'pthread_t', as computed by sizeof. */\r
+#undef SIZEOF_PTHREAD_T\r
+\r
+/* The size of 'short', as computed by sizeof. */\r
+#define SIZEOF_SHORT 2\r
+\r
+/* The size of 'size_t', as computed by sizeof. */\r
+#define SIZEOF_SIZE_T 8\r
+\r
+/* The size of 'time_t', as computed by sizeof. */\r
+#define SIZEOF_TIME_T 4\r
+\r
+/* The size of 'uintptr_t', as computed by sizeof. */\r
+#define SIZEOF_UINTPTR_T 8\r
+\r
+/* The size of 'void *', as computed by sizeof. */\r
+#define SIZEOF_VOID_P 8\r
+\r
+/* The size of 'wchar_t', as computed by sizeof. */\r
+#define SIZEOF_WCHAR_T 2\r
+\r
+/* The size of '_Bool', as computed by sizeof. */\r
+#define SIZEOF__BOOL 1\r
+\r
+/* Define to 1 if you have the ANSI C header files. */\r
+#define STDC_HEADERS 1\r
+\r
+/* Define if you can safely include both <sys/select.h> and <sys/time.h>\r
+ (which you can't on SCO ODT 3.0). */\r
+#undef SYS_SELECT_WITH_SYS_TIME\r
+\r
+/* Define if tanh(-0.) is -0., or if platform doesn't have signed zeros */\r
+#undef TANH_PRESERVES_ZERO_SIGN\r
+\r
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */\r
+#undef TIME_WITH_SYS_TIME\r
+\r
+/* Define to 1 if your <sys/time.h> declares 'struct tm'. */\r
+#undef TM_IN_SYS_TIME\r
+\r
+/* Enable extensions on AIX 3, Interix. */\r
+#ifndef _ALL_SOURCE\r
+# undef _ALL_SOURCE\r
+#endif\r
+/* Enable GNU extensions on systems that have them. */\r
+#ifndef _GNU_SOURCE\r
+# undef _GNU_SOURCE\r
+#endif\r
+/* Enable threading extensions on Solaris. */\r
+#ifndef _POSIX_PTHREAD_SEMANTICS\r
+# undef _POSIX_PTHREAD_SEMANTICS\r
+#endif\r
+/* Enable extensions on HP NonStop. */\r
+#ifndef _TANDEM_SOURCE\r
+# undef _TANDEM_SOURCE\r
+#endif\r
+/* Enable general extensions on Solaris. */\r
+#ifndef __EXTENSIONS__\r
+# undef __EXTENSIONS__\r
+#endif\r
+\r
+\r
+/* Define if you want to use MacPython modules on MacOSX in unix-Python. */\r
+#undef USE_TOOLBOX_OBJECT_GLUE\r
+\r
+/* Define if a va_list is an array of some kind */\r
+#undef VA_LIST_IS_ARRAY\r
+\r
+/* Define if you want SIGFPE handled (see Include/pyfpe.h). */\r
+#undef WANT_SIGFPE_HANDLER\r
+\r
+/* Define if you want wctype.h functions to be used instead of the one\r
+ supplied by Python itself. (see Include/unicodectype.h). */\r
+#define WANT_WCTYPE_FUNCTIONS 1\r
+\r
+/* Define if WINDOW in curses.h offers a field _flags. */\r
+#undef WINDOW_HAS_FLAGS\r
+\r
+/* Define if you want documentation strings in extension modules */\r
+#undef WITH_DOC_STRINGS\r
+\r
+/* Define if you want to use the new-style (Openstep, Rhapsody, MacOS) dynamic\r
+ linker (dyld) instead of the old-style (NextStep) dynamic linker (rld).\r
+ Dyld is necessary to support frameworks. */\r
+#undef WITH_DYLD\r
+\r
+/* Define to 1 if libintl is needed for locale functions. */\r
+#undef WITH_LIBINTL\r
+\r
+/* Define if you want to produce an OpenStep/Rhapsody framework (shared\r
+ library plus accessory files). */\r
+#undef WITH_NEXT_FRAMEWORK\r
+\r
+/* Define if you want to compile in Python-specific mallocs */\r
+#undef WITH_PYMALLOC\r
+\r
+/* Define if you want to compile in rudimentary thread support */\r
+#undef WITH_THREAD\r
+\r
+/* Define to profile with the Pentium timestamp counter */\r
+#undef WITH_TSC\r
+\r
+/* Define if you want pymalloc to be disabled when running under valgrind */\r
+#undef WITH_VALGRIND\r
+\r
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most\r
+ significant byte first (like Motorola and SPARC, unlike Intel). */\r
+#if defined AC_APPLE_UNIVERSAL_BUILD\r
+# if defined __BIG_ENDIAN__\r
+# define WORDS_BIGENDIAN 1\r
+# endif\r
+#else\r
+# ifndef WORDS_BIGENDIAN\r
+# undef WORDS_BIGENDIAN\r
+# endif\r
+#endif\r
+\r
+/* Define if arithmetic is subject to x87-style double rounding issue */\r
+#undef X87_DOUBLE_ROUNDING\r
+\r
+/* Define on OpenBSD to activate all library features */\r
+#undef _BSD_SOURCE\r
+\r
+/* Define on Irix to enable u_int */\r
+#undef _BSD_TYPES\r
+\r
+/* Define on Darwin to activate all library features */\r
+#undef _DARWIN_C_SOURCE\r
+\r
+/* This must be set to 64 on some systems to enable large file support. */\r
+#undef _FILE_OFFSET_BITS\r
+\r
+/* Define on Linux to activate all library features */\r
+#undef _GNU_SOURCE\r
+\r
+/* This must be defined on some systems to enable large file support. */\r
+#undef _LARGEFILE_SOURCE\r
+\r
+/* Define to 1 if on MINIX. */\r
+#undef _MINIX\r
+\r
+/* Define on NetBSD to activate all library features */\r
+#ifndef _NETBSD_SOURCE\r
+ #define _NETBSD_SOURCE 1\r
+#endif\r
+\r
+/* Define _OSF_SOURCE to get the makedev macro. */\r
+#undef _OSF_SOURCE\r
+\r
+/* Define to 2 if the system does not provide POSIX.1 features except with\r
+ this defined. */\r
+#undef _POSIX_1_SOURCE\r
+\r
+/* Define to activate features from IEEE Stds 1003.1-2001 */\r
+#undef _POSIX_C_SOURCE\r
+\r
+/* Define to 1 if you need to in order for 'stat' and other things to work. */\r
+#undef _POSIX_SOURCE\r
+\r
+/* Define if you have POSIX threads, and your system does not define that. */\r
+#undef _POSIX_THREADS\r
+\r
+/* Define to force use of thread-safe errno, h_errno, and other functions */\r
+#undef _REENTRANT\r
+\r
+/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,\r
+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the\r
+ #define below would cause a syntax error. */\r
+#undef _UINT32_T\r
+\r
+/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,\r
+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the\r
+ #define below would cause a syntax error. */\r
+#undef _UINT64_T\r
+\r
+/* Define to the level of X/Open that your system supports */\r
+#undef _XOPEN_SOURCE\r
+\r
+/* Define to activate Unix95-and-earlier features */\r
+#undef _XOPEN_SOURCE_EXTENDED\r
+\r
+/* Define on FreeBSD to activate all library features */\r
+#undef __BSD_VISIBLE\r
+\r
+/* Define to 1 if type 'char' is unsigned and you are not using gcc. */\r
+#ifndef __CHAR_UNSIGNED__\r
+# undef __CHAR_UNSIGNED__\r
+#endif\r
+\r
+/* Defined on Solaris to see additional function prototypes. */\r
+#undef __EXTENSIONS__\r
+\r
+/* Define to 'long' if <time.h> doesn't define. */\r
+//#undef clock_t\r
+\r
+/* Define to empty if 'const' does not conform to ANSI C. */\r
+//#undef const\r
+\r
+/* Define to 'int' if <sys/types.h> doesn't define. */\r
+//#undef gid_t\r
+\r
+/* Define to the type of a signed integer type of width exactly 32 bits if\r
+ such a type exists and the standard includes do not define it. */\r
+//#undef int32_t\r
+\r
+/* Define to the type of a signed integer type of width exactly 64 bits if\r
+ such a type exists and the standard includes do not define it. */\r
+//#undef int64_t\r
+\r
+/* Define to 'int' if <sys/types.h> does not define. */\r
+//#undef mode_t\r
+\r
+/* Define to 'long int' if <sys/types.h> does not define. */\r
+//#undef off_t\r
+\r
+/* Define to 'int' if <sys/types.h> does not define. */\r
+//#undef pid_t\r
+\r
+/* Define to empty if the keyword does not work. */\r
+//#undef signed\r
+\r
+/* Define to 'unsigned int' if <sys/types.h> does not define. */\r
+//#undef size_t\r
+\r
+/* Define to 'int' if <sys/socket.h> does not define. */\r
+//#undef socklen_t\r
+\r
+/* Define to 'int' if <sys/types.h> doesn't define. */\r
+//#undef uid_t\r
+\r
+/* Define to the type of an unsigned integer type of width exactly 32 bits if\r
+ such a type exists and the standard includes do not define it. */\r
+//#undef uint32_t\r
+\r
+/* Define to the type of an unsigned integer type of width exactly 64 bits if\r
+ such a type exists and the standard includes do not define it. */\r
+//#undef uint64_t\r
+\r
+/* Define to empty if the keyword does not work. */\r
+//#undef volatile\r
+\r
+#endif /*Py_PYCONFIG_H*/\r