Index: Python/dynload_mvs.c =================================================================== --- Python/dynload_mvs.c (revision 0) +++ Python/dynload_mvs.c (revision 0) @@ -0,0 +1,62 @@ + +/* Support for dynamic loading of extension modules for OS390 / ZOS IBM platforms */ + +#include +#include + +#include "Python.h" +#include "importdl.h" + +#define FUNCNAME_PATTERN "init%s" + +/* use '.dll' suffix naming rules for dll naming on MVS */ +const struct filedescr _PyImport_DynLoadFiletab[] = { + {".dll", "rb", C_EXTENSION}, + {"module.dll", "rb", C_EXTENSION}, + {0, 0} +}; + +dl_funcptr +_PyImport_GetDynLoadFunc(const char *fqname, const char *shortname, + const char *pathname, FILE * fp) +{ + dl_funcptr p = NULL; + char FuncName[258]; + dllhandle *pLib; + + if (Py_VerboseFlag) + printf("dllload %s \n", pathname); + + pLib = dllload(pathname); + + if (pLib == NULL) { + char errMsg[256]; + PyOS_snprintf(errMsg, sizeof (errMsg), + " fail to load %s errno = %i ", pathname, + errno); + + if (Py_VerboseFlag) + perror(errMsg); + return NULL; + } + + PyOS_snprintf (FuncName, sizeof(FuncName), FUNCNAME_PATTERN, + shortname); + + if (Py_VerboseFlag) + printf("dllqueryfn %s\n", FuncName); + + p = dllqueryfn(pLib, FuncName); + + if (p == NULL) { + char errMsg[256]; + PyOS_snprintf(errMsg, sizeof(errMsg), + " fail to get function %s errno = %i ", + FuncName, errno); + dllfree(pLib); + + if (Py_VerboseFlag) + perror(errMsg); + } + return p; +} Property changes on: Python/dynload_mvs.c ___________________________________________________________________ Name: svn:eol-style + native Index: Python/mystrtoul.c =================================================================== --- Python/mystrtoul.c (revision 58531) +++ Python/mystrtoul.c (working copy) @@ -150,7 +150,7 @@ ovlimit = digitlimit[base]; /* do the conversion until non-digit character encountered */ - while ((c = _PyLong_DigitValue[Py_CHARMASK(*str)]) < base) { + while ((c = _PyLong_DigitValue(*str)) < base) { if (ovlimit > 0) /* no overflow check required */ result = result * base + c; else { /* requires overflow check */ @@ -187,7 +187,7 @@ overflowed: if (ptr) { /* spool through remaining digit characters */ - while (_PyLong_DigitValue[Py_CHARMASK(*str)] < base) + while (_PyLong_DigitValue(*str) < base) ++str; *ptr = str; } Index: Include/pyport.h =================================================================== --- Include/pyport.h (revision 58531) +++ Include/pyport.h (working copy) @@ -596,6 +596,11 @@ #endif #endif +#ifdef __MVS__ +#define Py_CHARSET_CP1047 +#else +#define Py_CHARSET_ASCII +#endif /* Declarations for symbol visibility. @@ -737,6 +742,11 @@ #define LONG_MIN (-LONG_MAX-1) #endif +/* On z/OS, LONG_BIT is not defined suitably for preprocessor use. */ +#if defined(__MVS__) && defined(LONG_BIT) +# undef LONG_BIT +#endif + #ifndef LONG_BIT #define LONG_BIT (8 * SIZEOF_LONG) #endif Index: Include/py_curses.h =================================================================== --- Include/py_curses.h (revision 58531) +++ Include/py_curses.h (working copy) @@ -39,6 +39,10 @@ #endif #endif +#ifdef __MVS__ +#include +#endif + #ifdef HAVE_NCURSES_H #include #else Index: Include/unicodeobject.h =================================================================== --- Include/unicodeobject.h (revision 58531) +++ Include/unicodeobject.h (working copy) @@ -367,6 +367,14 @@ Py_UNICODE_ISDIGIT(ch) || \ Py_UNICODE_ISNUMERIC(ch)) +#ifdef Py_CHARSET_ASCII +# define Py_UNICODE_FROM_CHAR(c) ((Py_UNICODE)(unsigned char)(c)) +# define Py_UNICODE_AS_CHAR(u) (u < 0x80 ? (char)(unsigned char)(u) : '\0') +#else +# define Py_UNICODE_FROM_CHAR(c) _PyUnicode_FromChar(c) +# define Py_UNICODE_AS_CHAR(u) _PyUnicode_AsChar(u) +#endif + #define Py_UNICODE_COPY(target, source, length) \ Py_MEMCPY((target), (source), (length)*sizeof(Py_UNICODE)) @@ -1341,6 +1349,16 @@ Py_UNICODE ch /* Unicode character */ ); +/* === Conversion with platform character set============================== */ + +PyAPI_FUNC(char) _PyUnicode_AsChar( + Py_UNICODE ch /* Unicode character */ + ); + +PyAPI_FUNC(Py_UNICODE) _PyUnicode_FromChar( + char c + ); + #ifdef __cplusplus } #endif Index: Include/longobject.h =================================================================== --- Include/longobject.h (revision 58531) +++ Include/longobject.h (working copy) @@ -26,7 +26,7 @@ PyAPI_FUNC(Py_ssize_t) _PyLong_AsSsize_t(PyObject *); PyAPI_FUNC(PyObject *) _PyLong_FromSize_t(size_t); PyAPI_FUNC(PyObject *) _PyLong_FromSsize_t(Py_ssize_t); -PyAPI_DATA(int) _PyLong_DigitValue[256]; +PyAPI_FUNC(int) _PyLong_DigitValue(char c); /* _PyLong_AsScaledDouble returns a double x and an exponent e such that the true value is approximately equal to x * 2**(SHIFT*e). e is >= 0. Index: configure.in =================================================================== --- configure.in (revision 58531) +++ configure.in (working copy) @@ -187,6 +187,7 @@ darwin*) MACHDEP="darwin";; atheos*) MACHDEP="atheos";; irix646) MACHDEP="irix6";; + os390*) MACHDEP="mvs";; '') MACHDEP="unknown";; esac fi @@ -262,6 +263,10 @@ AC_DEFINE(_XOPEN_SOURCE, 500, Define to the level of X/Open that your system supports) ;; + OS/390/*) + AC_DEFINE(_XOPEN_SOURCE,500, + supported XOPEN for OS390 ) + ;; *) AC_DEFINE(_XOPEN_SOURCE, 600, Define to the level of X/Open that your system supports) @@ -276,15 +281,23 @@ # as it implies XPG4.2 case $ac_sys_system/$ac_sys_release in SunOS/5.10) + AC_DEFINE(_POSIX_C_SOURCE, 200112L, Define to activate features from IEEE Stds 1003.1-2001) ;; + OS/390/*) + AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, + Define to activate Unix95-and-earlier features) + AC_DEFINE(_OPEN_THREADS) + AC_DEFINE(_POSIX_THREADS) + AC_DEFINE(_POSIX_C_SOURCE, 2, Accepted level for MVS) + # Needed for dlopen and friends. + AC_DEFINE(_UNIX03_SOURCE) + ;; *) AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, Define to activate Unix95-and-earlier features) + AC_DEFINE(_POSIX_C_SOURCE, 200112L, Define to activate features from IEEE Stds 1003.1-2001) ;; esac - - AC_DEFINE(_POSIX_C_SOURCE, 200112L, Define to activate features from IEEE Stds 1003.1-2001) - fi # @@ -512,6 +525,25 @@ ;; esac +case $ac_sys_system in + OS/390) + # This is required to ensure that missing headers are correctly + # reported as errors. + _CC_ACCEPTABLE_RC=0 + export _CC_ACCEPTABLE_RC + # check for XPLINK linker optimization availability + AC_MSG_CHECKING(whether cc supports the XPLINK option) + AC_CACHE_VAL(ac_cv_xplink_ok, + [ac_save_cc="$CC" + CC="$CC -Wc,XPLINK -Wl,XPLINK" + AC_TRY_RUN([int main() { return 0; }], + ac_cv_xplink_ok=yes, + ac_cv_xplink_ok=no, + ac_cv_xplink_ok=no) + CC="$ac_save_cc"]) + AC_MSG_RESULT($ac_cv_xplink_ok) + ;; +esac AC_SUBST(LIBRARY) AC_MSG_CHECKING(LIBRARY) @@ -673,6 +705,10 @@ BLDLIBRARY='-L. -lpython$(VERSION)' RUNSHARED=DLL_PATH=`pwd`:${DLL_PATH:-/atheos/sys/libs:/atheos/autolnk/lib} ;; + OS/390*) + LDLIBRARY='libpython$(VERSION).x' + DLLLIBRARY='libpython$(VERSION).dll' + ;; esac else # shared is disabled case $ac_sys_system in @@ -841,6 +877,32 @@ SCO_SV*) BASECFLAGS="$BASECFLAGS -belf -Ki486 -DSCO5" ;; + OS/390*) + # LANGLVL(EXTENDED): accept some non-C89 language features + # FLOAT(IEEE): use IEEE floats, not HEX + # RENT: generate reentrant code + # XPLINK: use more efficient linkage + # GONUM: generate line number tables for debugging + MVS_CC_OPTS="LANGLVL(EXTENDED),FLOAT(IEEE),RENT" + if test $ac_cv_xplink_ok = yes; then + MVS_CC_OPTS="$MVS_CC_OPTS,XPLINK" + LDFLAGS="-Wl,XPLINK $LDFLAGS" + fi + if test "$Py_DEBUG" = 'true'; then + MVS_CC_OPTS="$MVS_CC_OPTS,GONUM" + fi + BASECFLAGS="-Wc,'$MVS_CC_OPTS'" + # The CFLAGS defined here are only used by autoconf's tests, not + # by the makefile that is generated. We want to use the same + # options for the tests as for the actual compilation. Also, since + # autoconf's tests use LDFLAGS, then CFLAGS must include XPLINK if + # LDFLAGS has them. + # + # The CFLAGS used by autoconf's macros must _not_ be + # shell-escaped, whereas the BASECFLAGS (used by the makefile) + # must be. Hence the lacking single quotes. + CFLAGS="-Wc,$MVS_CC_OPTS $CFLAGS" + ;; esac ;; esac @@ -923,6 +985,7 @@ AC_MSG_CHECKING(whether pthreads are available without options) AC_CACHE_VAL(ac_cv_pthread_is_default, [AC_TRY_RUN([ +#include #include void* routine(void* p){return NULL;} @@ -960,6 +1023,7 @@ [ac_save_cc="$CC" CC="$CC -Kpthread" AC_TRY_RUN([ +#include #include void* routine(void* p){return NULL;} @@ -991,6 +1055,7 @@ [ac_save_cc="$CC" CC="$CC -Kthread" AC_TRY_RUN([ +#include #include void* routine(void* p){return NULL;} @@ -1022,6 +1087,7 @@ [ac_save_cc="$CC" CC="$CC -pthread" AC_TRY_RUN([ +#include #include void* routine(void* p){return NULL;} @@ -1306,13 +1372,16 @@ fi AC_MSG_CHECKING(for pthread_t) have_pthread_t=no -AC_TRY_COMPILE([#include ], [pthread_t x; x = *(pthread_t*)0;], have_pthread_t=yes) +AC_TRY_COMPILE([ +#include ], [pthread_t x; x = *(pthread_t*)0;], have_pthread_t=yes) AC_MSG_RESULT($have_pthread_t) if test "$have_pthread_t" = yes ; then # AC_CHECK_SIZEOF() doesn't include . AC_MSG_CHECKING(size of pthread_t) AC_CACHE_VAL(ac_cv_sizeof_pthread_t, [AC_TRY_RUN([#include +#include +#include #include main() { @@ -1439,6 +1508,7 @@ esac ;; CYGWIN*) SO=.dll;; + OS/390*) SO=.dll;; *) SO=.so;; esac else @@ -1570,6 +1640,12 @@ SCO_SV*) LDSHARED='$(CC) -Wl,-G,-Bexport';; Monterey*) LDSHARED="cc -G -dy -Bdynamic -Bexport -L/usr/lib/ia64l64";; CYGWIN*) LDSHARED="gcc -shared -Wl,--enable-auto-image-base";; + OS/390*) + if test $ac_cv_xplink_ok = yes; then + LDSHARED='$(CC) -Wl,DLL,XPLINK' + else + LDSHARED='$(CC) -Wl,DLL' + fi;; atheos*) LDSHARED="gcc -shared";; *) LDSHARED="ld";; esac @@ -1610,6 +1686,7 @@ *gcc*) CCSHARED="-shared";; *) CCSHARED="";; esac;; + OS/390*) CCSHARED="-Wc,DLL,EXPORTALL";; atheos*) CCSHARED="-fPIC";; esac fi @@ -1650,6 +1727,7 @@ then LINKFORSHARED="-Wl,--export-dynamic" fi;; + OS/390*) LINKFORSHARED="-Wl,DLL";; SunOS/5*) case $CC in *gcc*) if $CC -Xlinker --help 2>&1 | grep export-dynamic >/dev/null @@ -1985,7 +2063,9 @@ AC_MSG_CHECKING(if PTHREAD_SCOPE_SYSTEM is supported) AC_CACHE_VAL(ac_cv_pthread_system_supported, - [AC_TRY_RUN([#include + [AC_TRY_RUN([ +#include +#include void *foo(void *parm) { return NULL; } @@ -2266,6 +2346,13 @@ # Use dynload_next.c only on 10.2 and below, which don't have native dlopen() Darwin/@<:@0156@:>@\..*) DYNLOADFILE="dynload_next.o";; atheos*) DYNLOADFILE="dynload_atheos.o";; + OS/390*) + # Support dynloading only if shared libraries are used. + if test $enable_shared = "yes" + then DYNLOADFILE="dynload_mvs.o" + else DYNLOADFILE="dynload_stub.o" + fi + ;; *) # use dynload_shlib.c and dlopen() if we have it; otherwise stub # out any dynamic loading @@ -3093,13 +3180,20 @@ # check for getc_unlocked and related locking functions AC_MSG_CHECKING(for getc_unlocked() and friends) -AC_CACHE_VAL(ac_cv_have_getc_unlocked, [ -AC_TRY_LINK([#include ],[ +if test "$ac_sys_system" = "OS/390" +then + # In z/OS the linkage would succeed even though the functions aren't + # available before 1.8. + ac_cv_have_getc_unlocked=no +else + AC_CACHE_VAL(ac_cv_have_getc_unlocked, [ + AC_TRY_LINK([#include ],[ FILE *f = fopen("/dev/null", "r"); flockfile(f); getc_unlocked(f); funlockfile(f); -], ac_cv_have_getc_unlocked=yes, ac_cv_have_getc_unlocked=no)]) + ], ac_cv_have_getc_unlocked=yes, ac_cv_have_getc_unlocked=no)]) +fi AC_MSG_RESULT($ac_cv_have_getc_unlocked) if test "$ac_cv_have_getc_unlocked" = yes then Index: setup.py =================================================================== --- setup.py (revision 58531) +++ setup.py (working copy) @@ -983,7 +983,7 @@ missing.append('resource') # Sun yellow pages. Some systems have the functions in libc. - if platform not in ['cygwin', 'atheos']: + if platform not in ['cygwin', 'atheos', 'mvs']: if (self.compiler.find_library_file(lib_dirs, 'nsl')): libs = ['nsl'] else: @@ -1433,6 +1433,8 @@ # -lGL -lGLU -lXext -lXmu \ def configure_ctypes(self, ext): + if sys.platform in ['mvs']: + return False if not self.use_system_libffi: (srcdir,) = sysconfig.get_config_vars('srcdir') ffi_builddir = os.path.join(self.build_temp, 'libffi') Index: Objects/unicodeobject.c =================================================================== --- Objects/unicodeobject.c (revision 58531) +++ Objects/unicodeobject.c (working copy) @@ -112,6 +112,46 @@ */ static char unicode_default_encoding[100]; + +/* Map from ASCII codes to the platform's execution character set, or to + '\0' if the corresponding character is not known. */ +static const char unicode_ascii_table[128] = + "\0\0\0\0\0\0\0\a\b\t\n\v\f\r\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + " !\"#$%&'()*+,-./0123456789:;<=>?" + "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" + "`abcdefghijklmnopqrstuvwxyz{|}~\0"; + +/* A reverse of the previous: maps platform characters (when cast to unsigned + char) to the corresponding ASCII values. */ +static Py_UNICODE unicode_reverse_ascii_table[UCHAR_MAX + 1] = { 0 }; + +static void unicode_ascii_init(void) +{ + Py_UNICODE u; + for (u = 0; u < 0x80; u++) { + char c = unicode_ascii_table[u]; + if (c != '\0') { + unicode_reverse_ascii_table[(unsigned char) c] = u; + } + } +} + +char _PyUnicode_AsChar(Py_UNICODE u) +{ + if (u >= 0x80) + return '\0'; + return unicode_ascii_table[u]; +} + +Py_UNICODE _PyUnicode_FromChar(char c) +{ + return unicode_reverse_ascii_table[(unsigned char) c]; +} + +#define U2C(u) Py_UNICODE_AS_CHAR(u) +#define C2U(c) Py_UNICODE_FROM_CHAR(c) + Py_UNICODE PyUnicode_GetMax(void) { @@ -2074,7 +2114,7 @@ /* Non-escape characters are interpreted as Unicode ordinals */ if (*s != '\\') { - *p++ = (unsigned char) *s++; + *p++ = C2U(*s++); continue; } @@ -2085,14 +2125,14 @@ /* \x escapes */ case '\n': break; - case '\\': *p++ = '\\'; break; - case '\'': *p++ = '\''; break; - case '\"': *p++ = '\"'; break; - case 'b': *p++ = '\b'; break; + case '\\': *p++ = C2U('\\'); break; + case '\'': *p++ = C2U('\''); break; + case '\"': *p++ = C2U('\"'); break; + case 'b': *p++ = C2U('\b'); break; case 'f': *p++ = '\014'; break; /* FF */ - case 't': *p++ = '\t'; break; - case 'n': *p++ = '\n'; break; - case 'r': *p++ = '\r'; break; + case 't': *p++ = C2U('\t'); break; + case 'n': *p++ = C2U('\n'); break; + case 'r': *p++ = C2U('\r'); break; case 'v': *p++ = '\013'; break; /* VT */ case 'a': *p++ = '\007'; break; /* BEL, not classic C */ @@ -2150,13 +2190,7 @@ goto onError; goto nextByte; } - chr = (chr<<4) & ~0xF; - if (c >= '0' && c <= '9') - chr += c - '0'; - else if (c >= 'a' && c <= 'f') - chr += 10 + c - 'a'; - else - chr += 10 + c - 'A'; + chr = ((chr<<4) & ~0xF) + _PyLong_DigitValue((char) c); } s += i; if (chr == 0xffffffff && PyErr_Occurred()) @@ -2346,12 +2380,13 @@ } while (size-- > 0) { Py_UNICODE ch = *s++; + char c = U2C(ch); /* Escape quotes and backslashes */ if ((quotes && - ch == (Py_UNICODE) PyString_AS_STRING(repr)[1]) || ch == '\\') { + c == PyString_AS_STRING(repr)[1]) || c == '\\') { *p++ = '\\'; - *p++ = (char) ch; + *p++ = c; continue; } @@ -2397,7 +2432,7 @@ size++; } #endif - + /* Map 16-bit characters to '\uxxxx' */ if (ch >= 256) { *p++ = '\\'; @@ -2409,15 +2444,15 @@ } /* Map special whitespace to '\t', \n', '\r' */ - else if (ch == '\t') { + else if (c == '\t') { *p++ = '\\'; *p++ = 't'; } - else if (ch == '\n') { + else if (c == '\n') { *p++ = '\\'; *p++ = 'n'; } - else if (ch == '\r') { + else if (c == '\r') { *p++ = '\\'; *p++ = 'r'; } @@ -2429,10 +2464,9 @@ *p++ = hexdigit[(ch >> 4) & 0x000F]; *p++ = hexdigit[ch & 0x000F]; } + else + *p++ = c; - /* Copy everything else as-is */ - else - *p++ = (char) ch; } if (quotes) *p++ = PyString_AS_STRING(repr)[1]; @@ -2494,7 +2528,7 @@ /* Non-escape characters are interpreted as Unicode ordinals */ if (*s != '\\') { - *p++ = (unsigned char)*s++; + *p++ = C2U(*s++); continue; } startinpos = s-starts; @@ -2505,7 +2539,7 @@ for (;s < end;) { if (*s != '\\') break; - *p++ = (unsigned char)*s++; + *p++ = C2U(*s++); } if (((s - bs) & 1) == 0 || s >= end || @@ -2530,13 +2564,7 @@ goto onError; goto nextByte; } - x = (x<<4) & ~0xF; - if (c >= '0' && c <= '9') - x += c - '0'; - else if (c >= 'a' && c <= 'f') - x += 10 + c - 'a'; - else - x += 10 + c - 'A'; + x = ((x<<4) & ~0xF) + _PyLong_DigitValue((char) c); } #ifndef Py_UNICODE_WIDE if (x > 0x10000) { @@ -2587,6 +2615,8 @@ p = q = PyString_AS_STRING(repr); while (size-- > 0) { Py_UNICODE ch = *s++; + char c = U2C(ch); + #ifdef Py_UNICODE_WIDE /* Map 32-bit characters to '\Uxxxxxxxx' */ if (ch >= 0x10000) { @@ -2603,8 +2633,8 @@ } else #endif - /* Map 16-bit characters to '\uxxxx' */ - if (ch >= 256) { + /* Map unrecodable and 16-bit characters to '\uxxxx' */ + if (ch >= 256 || (c == '\0' && ch != 0)) { *p++ = '\\'; *p++ = 'u'; *p++ = hexdigit[(ch >> 12) & 0xf]; @@ -2614,7 +2644,7 @@ } /* Copy everything else as-is */ else - *p++ = (char) ch; + *p++ = c; } *p = '\0'; _PyString_Resize(&repr, p - q); @@ -4427,7 +4457,7 @@ continue; } if (0 < ch && ch < 256) { - *output++ = (char)ch; + *output++ = U2C(ch); ++p; continue; } @@ -4487,8 +4517,8 @@ decimal = Py_UNICODE_TODECIMAL(ch); if (decimal >= 0) *output++ = '0' + decimal; - else if (0 < ch && ch < 256) - *output++ = (char)ch; + else if (U2C(ch) != '\0') + *output++ = U2C(ch); else { Py_DECREF(repunicode); raise_encode_exception(&exc, encoding, @@ -7502,7 +7532,7 @@ register Py_ssize_t i; Py_ssize_t len = strlen(charbuffer); for (i = len - 1; i >= 0; i--) - buffer[i] = (Py_UNICODE) charbuffer[i]; + buffer[i] = C2U(charbuffer[i]); return len; } @@ -7597,7 +7627,7 @@ return NULL; } for (i = 0; i < len; i++) - result->str[i] = buf[i]; + result->str[i] = C2U(buf[i]); result->str[len] = 0; Py_DECREF(str); return (PyObject*)result; @@ -7777,7 +7807,7 @@ dict = args; while (--fmtcnt >= 0) { - if (*fmt != '%') { + if (*fmt != C2U('%')) { if (--rescnt < 0) { rescnt = fmtcnt + 100; reslen += rescnt; @@ -7793,17 +7823,17 @@ int flags = 0; Py_ssize_t width = -1; int prec = -1; - Py_UNICODE c = '\0'; - Py_UNICODE fill; + char c = '\0'; + char fill; PyObject *v = NULL; PyObject *temp = NULL; Py_UNICODE *pbuf; - Py_UNICODE sign; + char sign; Py_ssize_t len; Py_UNICODE formatbuf[FORMATBUFLEN]; /* For format{float,int,char}() */ fmt++; - if (*fmt == '(') { + if (*fmt == C2U('(')) { Py_UNICODE *keystart; Py_ssize_t keylen; PyObject *key; @@ -7819,9 +7849,9 @@ keystart = fmt; /* Skip over balanced parentheses */ while (pcount > 0 && --fmtcnt >= 0) { - if (*fmt == ')') + if (*fmt == C2U(')')) --pcount; - else if (*fmt == '(') + else if (*fmt == C2U('(')) ++pcount; fmt++; } @@ -7858,7 +7888,7 @@ argidx = -2; } while (--fmtcnt >= 0) { - switch (c = *fmt++) { + switch (c = U2C(*fmt++)) { case '-': flags |= F_LJUST; continue; case '+': flags |= F_SIGN; continue; case ' ': flags |= F_BLANK; continue; @@ -7882,12 +7912,12 @@ width = -width; } if (--fmtcnt >= 0) - c = *fmt++; + c = U2C(*fmt++); } else if (c >= '0' && c <= '9') { width = c - '0'; while (--fmtcnt >= 0) { - c = *fmt++; + c = U2C(*fmt++); if (c < '0' || c > '9') break; if ((width*10) / 10 != width) { @@ -7901,7 +7931,7 @@ if (c == '.') { prec = 0; if (--fmtcnt >= 0) - c = *fmt++; + c = U2C(*fmt++); if (c == '*') { v = getnextarg(args, arglen, &argidx); if (v == NULL) @@ -7915,7 +7945,7 @@ if (prec < 0) prec = 0; if (--fmtcnt >= 0) - c = *fmt++; + c = U2C(*fmt++); } else if (c >= '0' && c <= '9') { prec = c - '0'; @@ -7935,7 +7965,7 @@ if (fmtcnt >= 0) { if (c == 'h' || c == 'l' || c == 'L') { if (--fmtcnt >= 0) - c = *fmt++; + c = U2C(*fmt++); } } if (fmtcnt < 0) { @@ -7955,7 +7985,7 @@ case '%': pbuf = formatbuf; /* presume that buffer length is at least 1 */ - pbuf[0] = '%'; + pbuf[0] = C2U('%'); len = 1; break; @@ -8063,8 +8093,10 @@ goto onError; } if (sign) { - if (*pbuf == '-' || *pbuf == '+') { - sign = *pbuf++; + char s = U2C(*pbuf); + if (s == '-' || s == '+') { + sign = s; + pbuf++; len--; } else if (flags & F_SIGN) @@ -8094,14 +8126,14 @@ } if (sign) { if (fill != ' ') - *res++ = sign; + *res++ = C2U(sign); rescnt--; if (width > len) width--; } if ((flags & F_ALT) && (c == 'x' || c == 'X')) { - assert(pbuf[0] == '0'); - assert(pbuf[1] == c); + assert(pbuf[0] == C2U('0')); + assert(pbuf[1] == C2U(c)); if (fill != ' ') { *res++ = *pbuf++; *res++ = *pbuf++; @@ -8115,15 +8147,15 @@ if (width > len && !(flags & F_LJUST)) { do { --rescnt; - *res++ = fill; + *res++ = C2U(fill); } while (--width > len); } if (fill == ' ') { if (sign) *res++ = sign; if ((flags & F_ALT) && (c == 'x' || c == 'X')) { - assert(pbuf[0] == '0'); - assert(pbuf[1] == c); + assert(pbuf[0] == C2U('0')); + assert(pbuf[1] == C2U(c)); *res++ = *pbuf++; *res++ = *pbuf++; } @@ -8133,7 +8165,7 @@ rescnt -= len; while (--width >= len) { --rescnt; - *res++ = ' '; + *res++ = C2U(' '); } if (dict && (argidx < arglen) && c != '%') { PyErr_SetString(PyExc_TypeError, @@ -8315,6 +8347,8 @@ linebreak, sizeof(linebreak) / sizeof(linebreak[0]) ); + unicode_ascii_init(); + PyType_Ready(&EncodingMapType); } Index: Objects/longobject.c =================================================================== --- Objects/longobject.c (revision 58531) +++ Objects/longobject.c (working copy) @@ -1337,10 +1337,10 @@ * '0' maps to 0, ..., '9' maps to 9. * 'a' and 'A' map to 10, ..., 'z' and 'Z' map to 35. * All other indices map to 37. - * Note that when converting a base B string, a char c is a legitimate - * base B digit iff _PyLong_DigitValue[Py_CHARMASK(c)] < B. + * Note that when converting a base B string, an ASCII code c is a legitimate + * base B digit iff _PyLong_DigitValue[c] < B. */ -int _PyLong_DigitValue[256] = { +static const int _PyLong_AsciiDigitValue[256] = { 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, @@ -1359,6 +1359,10 @@ 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, }; +int _PyLong_DigitValue(char c) { + return _PyLong_AsciiDigitValue[Py_UNICODE_FROM_CHAR(c)]; +} + /* *str points to the first digit in a string of base `base` digits. base * is a power of 2 (2, 4, 8, 16, or 32). *str is set to point to the first * non-digit (which may be *str!). A normalized long is returned. @@ -1383,7 +1387,7 @@ n >>= 1; /* n <- total # of bits needed, while setting p to end-of-string */ n = 0; - while (_PyLong_DigitValue[Py_CHARMASK(*p)] < base) + while (_PyLong_DigitValue(*p) < base) ++p; *str = p; /* n <- # of Python digits needed, = ceiling(n/SHIFT). */ @@ -1404,7 +1408,7 @@ bits_in_accum = 0; pdigit = z->ob_digit; while (--p >= start) { - int k = _PyLong_DigitValue[Py_CHARMASK(*p)]; + int k = _PyLong_DigitValue(*p); assert(k >= 0 && k < base); accum |= (twodigits)(k << bits_in_accum); bits_in_accum += bits_per_char; @@ -1582,7 +1586,7 @@ /* Find length of the string of numeric characters. */ scan = str; - while (_PyLong_DigitValue[Py_CHARMASK(*scan)] < base) + while (_PyLong_DigitValue(*scan) < base) ++scan; /* Create a long object that can contain the largest possible @@ -1608,10 +1612,10 @@ /* Work ;-) */ while (str < scan) { /* grab up to convwidth digits from the input string */ - c = (digit)_PyLong_DigitValue[Py_CHARMASK(*str++)]; + c = (digit)_PyLong_DigitValue(*str++); for (i = 1; i < convwidth && str != scan; ++i, ++str) { c = (twodigits)(c * base + - _PyLong_DigitValue[Py_CHARMASK(*str)]); + _PyLong_DigitValue(*str)); assert(c < BASE); } Index: Objects/stringobject.c =================================================================== --- Objects/stringobject.c (revision 58531) +++ Objects/stringobject.c (working copy) @@ -560,7 +560,7 @@ while (s < end) { if (*s != '\\') { non_esc: -#ifdef Py_USING_UNICODE +#if defined(Py_USING_UNICODE) && defined(Py_CHARSET_ASCII) if (recode_encoding && (*s & 0x80)) { PyObject *u, *w; char *r; @@ -601,18 +601,24 @@ goto failed; } switch (*s++) { - /* XXX This assumes ASCII! */ case '\n': break; case '\\': *p++ = '\\'; break; case '\'': *p++ = '\''; break; case '\"': *p++ = '\"'; break; case 'b': *p++ = '\b'; break; - case 'f': *p++ = '\014'; break; /* FF */ case 't': *p++ = '\t'; break; case 'n': *p++ = '\n'; break; case 'r': *p++ = '\r'; break; +#ifdef Py_CHARSET_ASCII + /* Some compilers might not know these character literals. */ + case 'f': *p++ = '\014'; break; /* FF */ case 'v': *p++ = '\013'; break; /* VT */ case 'a': *p++ = '\007'; break; /* BEL, not classic C */ +#else + case 'f': *p++ = '\f'; break; + case 'v': *p++ = '\v'; break; + case 'a': *p++ = '\a'; break; +#endif case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': c = s[-1] - '0'; @@ -626,25 +632,9 @@ case 'x': if (isxdigit(Py_CHARMASK(s[0])) && isxdigit(Py_CHARMASK(s[1]))) { - unsigned int x = 0; - c = Py_CHARMASK(*s); - s++; - if (isdigit(c)) - x = c - '0'; - else if (islower(c)) - x = 10 + c - 'a'; - else - x = 10 + c - 'A'; - x = x << 4; - c = Py_CHARMASK(*s); - s++; - if (isdigit(c)) - x += c - '0'; - else if (islower(c)) - x += 10 + c - 'a'; - else - x += 10 + c - 'A'; - *p++ = x; + int xh = _PyLong_DigitValue(*s++); + int xl = _PyLong_DigitValue(*s++); + *p++ = Py_CHARMASK(xh * 16 + xl); break; } if (!errors || strcmp(errors, "strict") == 0) { @@ -848,7 +838,7 @@ fprintf(fp, "\\n"); else if (c == '\r') fprintf(fp, "\\r"); - else if (c < ' ' || c >= 0x7f) + else if (!isprint((unsigned char) c)) fprintf(fp, "\\x%02x", c & 0xff); else fputc(c, fp); @@ -900,7 +890,7 @@ *p++ = '\\', *p++ = 'n'; else if (c == '\r') *p++ = '\\', *p++ = 'r'; - else if (c < ' ' || c >= 0x7f) { + else if (!isprint((unsigned char) c)) { /* For performance, we don't want to call PyOS_snprintf here (extra layers of function call). */ Index: Parser/tokenizer.c =================================================================== --- Parser/tokenizer.c (revision 58531) +++ Parser/tokenizer.c (working copy) @@ -489,6 +489,7 @@ } } #ifndef PGEN +#ifdef Py_CHARSET_ASCII /* The default encoding is ASCII, so make sure we don't have any non-ASCII bytes in it. */ if (line && !tok->encoding) { @@ -499,6 +500,7 @@ break; } } +#endif if (badchar) { char buf[500]; /* Need to add 1 to the line number, since this line Index: Lib/site.py =================================================================== --- Lib/site.py (revision 58531) +++ Lib/site.py (working copy) @@ -369,7 +369,10 @@ """Set the string encoding used by the Unicode implementation. The default is 'ascii', but if you're willing to experiment, you can change this.""" - encoding = "ascii" # Default value set by _PyUnicode_Init() + if sys.platform == 'mvs': + encoding = "cp1047" + else: + encoding = "ascii" if 0: # Enable to support locale aware default string encodings. import locale Index: Lib/stat.py =================================================================== --- Lib/stat.py (revision 58531) +++ Lib/stat.py (working copy) @@ -3,6 +3,10 @@ Suggested usage: from stat import * """ +import sys + +_zos = (sys.platform == 'mvs') + # XXX Strictly spoken, this module may have to be adapted for each POSIX # implementation; in practice, however, the numeric constants used by # stat() are almost universal (even for stat() emulations on non-UNIX @@ -26,19 +30,32 @@ def S_IMODE(mode): return mode & 07777 -def S_IFMT(mode): - return mode & 0170000 +if _zos: + def S_IFMT(mode): + return mode & 0xff000000 +else: + def S_IFMT(mode): + return mode & 0170000 # Constants used as S_IFMT() for various file types # (not all are implemented on all systems) -S_IFDIR = 0040000 -S_IFCHR = 0020000 -S_IFBLK = 0060000 -S_IFREG = 0100000 -S_IFIFO = 0010000 -S_IFLNK = 0120000 -S_IFSOCK = 0140000 +if _zos: + S_IFDIR = 0x01000000 + S_IFCHR = 0x02000000 + S_IFBLK = 0x06000000 + S_IFREG = 0x03000000 + S_IFIFO = 0x04000000 + S_IFLNK = 0x05000000 + S_IFSOCK = 0x07000000 +else: + S_IFDIR = 0040000 + S_IFCHR = 0020000 + S_IFBLK = 0060000 + S_IFREG = 0100000 + S_IFIFO = 0010000 + S_IFLNK = 0120000 + S_IFSOCK = 0140000 # Functions to test for each file type Index: Lib/distutils/unixccompiler.py =================================================================== --- Lib/distutils/unixccompiler.py (revision 58531) +++ Lib/distutils/unixccompiler.py (working copy) @@ -170,7 +170,7 @@ if sys.platform == 'darwin': compiler_so = _darwin_compiler_fixup(compiler_so, cc_args + extra_postargs) try: - self.spawn(compiler_so + cc_args + [src, '-o', obj] + + self.spawn(compiler_so + cc_args + ['-o', obj, src] + extra_postargs) except DistutilsExecError, msg: raise CompileError, msg @@ -218,8 +218,28 @@ output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): - ld_args = (objects + self.objects + - lib_opts + ['-o', output_filename]) + if sys.platform == 'mvs': + (major, minor, micro, release, serial) = sys.version_info + + # Unless we have _CC_CCMODE=1 in the environment, the + # z/OS cc expects other options to come _before_ the + # objects, and -l to come _after_. Hence we separate + # them. + l_opts = [o for o in lib_opts if o.startswith("-l")] + other_opts = [o for o in lib_opts if not o.startswith("-l")] + + # We hack and replace the static -lpython linkage with + # the dynamic libpython.x Note that this only works if + # libpython.x is in cwd, it is not searched from the + # path. TODO: this hack should be disabled if python + # wasn't compiled with --enable-shared. + l_opts = [o for o in l_opts if not o.startswith('-lpython')] + l_opts = ['libpython%d.%d.x' % (major, minor)] + l_opts + ld_args = (['-o', output_filename] + other_opts + objects + + self.objects + l_opts) + else: + ld_args = (objects + self.objects + + lib_opts + ['-o', output_filename]) if debug: ld_args[:0] = ['-g'] if extra_preargs: Index: Lib/encodings/__init__.py =================================================================== --- Lib/encodings/__init__.py (revision 58531) +++ Lib/encodings/__init__.py (working copy) @@ -34,12 +34,10 @@ _cache = {} _unknown = '--unknown--' _import_tail = ['*'] -_norm_encoding_map = (' . ' - '0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ ' - ' abcdefghijklmnopqrstuvwxyz ' - ' ' - ' ' - ' ') +_norm_encoding_chars = [' '] * 256 +for c in ".0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz": + _norm_encoding_chars[ord(c)] = c +_norm_encoding_map = ''.join(_norm_encoding_chars) _aliases = aliases.aliases class CodecRegistryError(LookupError, SystemError): Index: Lib/encodings/cp1047.py =================================================================== --- Lib/encodings/cp1047.py (revision 0) +++ Lib/encodings/cp1047.py (revision 0) @@ -0,0 +1,308 @@ +""" Python Character Mapping Codec cp1047 generated from 'jdk-1.5.0/CP1047.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1047', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\u0000' + u'\u0001' + u'\u0002' + u'\u0003' + u'\u009c' + u'\u0009' + u'\u0086' + u'\u007f' + u'\u0097' + u'\u008d' + u'\u008e' + u'\u000b' + u'\u000c' + u'\u000d' + u'\u000e' + u'\u000f' + u'\u0010' + u'\u0011' + u'\u0012' + u'\u0013' + u'\u009d' + u'\u000a' + u'\u0008' + u'\u0087' + u'\u0018' + u'\u0019' + u'\u0092' + u'\u008f' + u'\u001c' + u'\u001d' + u'\u001e' + u'\u001f' + u'\u0080' + u'\u0081' + u'\u0082' + u'\u0083' + u'\u0084' + u'\u0085' + u'\u0017' + u'\u001b' + u'\u0088' + u'\u0089' + u'\u008a' + u'\u008b' + u'\u008c' + u'\u0005' + u'\u0006' + u'\u0007' + u'\u0090' + u'\u0091' + u'\u0016' + u'\u0093' + u'\u0094' + u'\u0095' + u'\u0096' + u'\u0004' + u'\u0098' + u'\u0099' + u'\u009a' + u'\u009b' + u'\u0014' + u'\u0015' + u'\u009e' + u'\u001a' + u'\u0020' + u'\u00a0' + u'\u00e2' + u'\u00e4' + u'\u00e0' + u'\u00e1' + u'\u00e3' + u'\u00e5' + u'\u00e7' + u'\u00f1' + u'\u00a2' + u'\u002e' + u'\u003c' + u'\u0028' + u'\u002b' + u'\u007c' + u'\u0026' + u'\u00e9' + u'\u00ea' + u'\u00eb' + u'\u00e8' + u'\u00ed' + u'\u00ee' + u'\u00ef' + u'\u00ec' + u'\u00df' + u'\u0021' + u'\u0024' + u'\u002a' + u'\u0029' + u'\u003b' + u'\u005e' + u'\u002d' + u'\u002f' + u'\u00c2' + u'\u00c4' + u'\u00c0' + u'\u00c1' + u'\u00c3' + u'\u00c5' + u'\u00c7' + u'\u00d1' + u'\u00a6' + u'\u002c' + u'\u0025' + u'\u005f' + u'\u003e' + u'\u003f' + u'\u00f8' + u'\u00c9' + u'\u00ca' + u'\u00cb' + u'\u00c8' + u'\u00cd' + u'\u00ce' + u'\u00cf' + u'\u00cc' + u'\u0060' + u'\u003a' + u'\u0023' + u'\u0040' + u'\u0027' + u'\u003d' + u'\u0022' + u'\u00d8' + u'\u0061' + u'\u0062' + u'\u0063' + u'\u0064' + u'\u0065' + u'\u0066' + u'\u0067' + u'\u0068' + u'\u0069' + u'\u00ab' + u'\u00bb' + u'\u00f0' + u'\u00fd' + u'\u00fe' + u'\u00b1' + u'\u00b0' + u'\u006a' + u'\u006b' + u'\u006c' + u'\u006d' + u'\u006e' + u'\u006f' + u'\u0070' + u'\u0071' + u'\u0072' + u'\u00aa' + u'\u00ba' + u'\u00e6' + u'\u00b8' + u'\u00c6' + u'\u00a4' + u'\u00b5' + u'\u007e' + u'\u0073' + u'\u0074' + u'\u0075' + u'\u0076' + u'\u0077' + u'\u0078' + u'\u0079' + u'\u007a' + u'\u00a1' + u'\u00bf' + u'\u00d0' + u'\u005b' + u'\u00de' + u'\u00ae' + u'\u00ac' + u'\u00a3' + u'\u00a5' + u'\u00b7' + u'\u00a9' + u'\u00a7' + u'\u00b6' + u'\u00bc' + u'\u00bd' + u'\u00be' + u'\u00dd' + u'\u00a8' + u'\u00af' + u'\u005d' + u'\u00b4' + u'\u00d7' + u'\u007b' + u'\u0041' + u'\u0042' + u'\u0043' + u'\u0044' + u'\u0045' + u'\u0046' + u'\u0047' + u'\u0048' + u'\u0049' + u'\u00ad' + u'\u00f4' + u'\u00f6' + u'\u00f2' + u'\u00f3' + u'\u00f5' + u'\u007d' + u'\u004a' + u'\u004b' + u'\u004c' + u'\u004d' + u'\u004e' + u'\u004f' + u'\u0050' + u'\u0051' + u'\u0052' + u'\u00b9' + u'\u00fb' + u'\u00fc' + u'\u00f9' + u'\u00fa' + u'\u00ff' + u'\u005c' + u'\u00f7' + u'\u0053' + u'\u0054' + u'\u0055' + u'\u0056' + u'\u0057' + u'\u0058' + u'\u0059' + u'\u005a' + u'\u00b2' + u'\u00d4' + u'\u00d6' + u'\u00d2' + u'\u00d3' + u'\u00d5' + u'\u0030' + u'\u0031' + u'\u0032' + u'\u0033' + u'\u0034' + u'\u0035' + u'\u0036' + u'\u0037' + u'\u0038' + u'\u0039' + u'\u00b3' + u'\u00db' + u'\u00dc' + u'\u00d9' + u'\u00da' + u'\u009f' +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) + Index: Lib/plat-mvs/regen =================================================================== --- Lib/plat-mvs/regen (revision 0) +++ Lib/plat-mvs/regen (revision 0) @@ -0,0 +1,3 @@ +#! /bin/sh +set -v +python$EXE ../../Tools/scripts/h2py.py -i '(u_long)' /usr/include/netinet/in.h Index: Lib/pickle.py =================================================================== --- Lib/pickle.py (revision 58531) +++ Lib/pickle.py (working copy) @@ -48,7 +48,11 @@ # Keep in synch with cPickle. This is the highest protocol number we # know how to read. -HIGHEST_PROTOCOL = 2 +if sys.platform in ['mvs']: + # On EBCDIC platforms we only support text pickles. + HIGHEST_PROTOCOL = 0 +else: + HIGHEST_PROTOCOL = 2 # Why use struct.pack() for pickling but marshal.loads() for # unpickling? struct.pack() is 40% faster than marshal.dumps(), but Index: Makefile.pre.in =================================================================== --- Makefile.pre.in (revision 58531) +++ Makefile.pre.in (working copy) @@ -412,15 +412,28 @@ $(LN) -fsn Versions/Current/Headers $(PYTHONFRAMEWORKDIR)/Headers $(LN) -fsn Versions/Current/Resources $(PYTHONFRAMEWORKDIR)/Resources +# On Cygwin: # This rule builds the Cygwin Python DLL and import library if configured # for a shared core library; otherwise, this rule is a noop. +# +# On z/OS: +# This rule builds the shared library (.dll) and the side deck (.x). $(DLLLIBRARY) libpython$(VERSION).dll.a: $(LIBRARY_OBJS) + case $(MACHDEP) in \ + cygwin) \ if test -n "$(DLLLIBRARY)"; then \ $(LDSHARED) -Wl,--out-implib=$@ -o $(DLLLIBRARY) $^ \ $(LIBS) $(MODLIBS) $(SYSLIBS); \ else true; \ - fi + fi \ + ;; \ + mvs) \ + $(LDSHARED) -o $(DLLLIBRARY) $^ \ + ;; \ + esac +# On z/OS, the side deck is built as a byproduct of the DLL. +libpython$(VERSION).x: $(DLLLIBRARY) oldsharedmods: $(SHAREDMODS) @@ -478,8 +491,13 @@ -@$(INSTALL) -d Include -$(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C) +# The _CC_ACCEPTABLE_RC hack is needed on z/OS to ensure that a warning +# doesn't stop the compilation. The warning is caused by the fact that +# we're using shared library objects (with exported symbols) in a binary +# that doesn't export anything. $(PGEN): $(PGENOBJS) - $(CC) $(OPT) $(LDFLAGS) $(PGENOBJS) $(LIBS) -o $(PGEN) + _CC_ACCEPTABLE_RC=4 \ + $(CC) $(OPT) $(LDFLAGS) -o $(PGEN) $(PGENOBJS) $(LIBS) Parser/grammar.o: $(srcdir)/Parser/grammar.c \ $(srcdir)/Include/token.h \ @@ -680,8 +698,11 @@ done $(INSTALL_PROGRAM) $(BUILDPYTHON) $(DESTDIR)$(BINDIR)/python$(VERSION)$(EXE) if test -f libpython$(VERSION)$(SO); then \ - if test "$(SO)" = .dll; then \ + if test "$(MACHDEP)" = "cygwin"; then \ $(INSTALL_SHARED) libpython$(VERSION)$(SO) $(DESTDIR)$(BINDIR); \ + elif test "$(MACHDEP)" = "mvs"; then \ + $(INSTALL_SHARED) libpython$(VERSION)$(SO) $(DESTDIR)$(LIBDIR); \ + $(INSTALL_SHARED) libpython$(VERSION).x $(DESTDIR)$(LIBDIR); \ else \ $(INSTALL_SHARED) libpython$(VERSION)$(SO) $(DESTDIR)$(LIBDIR)/$(INSTSONAME); \ if test libpython$(VERSION)$(SO) != $(INSTSONAME); then \ @@ -845,7 +866,7 @@ done @if test -d $(LIBRARY); then :; else \ if test "$(PYTHONFRAMEWORKDIR)" = no-framework; then \ - if test "$(SO)" = .dll; then \ + if test "$(MACHDEP)" = "cygwin"; then \ $(INSTALL_DATA) $(LDLIBRARY) $(DESTDIR)$(LIBPL) ; \ else \ $(INSTALL_DATA) $(LIBRARY) $(DESTDIR)$(LIBPL)/$(LIBRARY) ; \ @@ -1029,7 +1050,9 @@ clean: pycremoval find . -name '*.o' -exec rm -f {} ';' + find . -name '*.x' -exec rm -f {} ';' find . -name '*.s[ol]' -exec rm -f {} ';' + find . -name '*.dll' -exec rm -f {} ';' find $(srcdir)/build -name 'fficonfig.h' -exec rm -f {} ';' || true find $(srcdir)/build -name 'fficonfig.py' -exec rm -f {} ';' || true Index: Modules/grpmodule.c =================================================================== --- Modules/grpmodule.c (revision 58531) +++ Modules/grpmodule.c (working copy) @@ -59,7 +59,7 @@ #define SET(i,val) PyStructSequence_SET_ITEM(v, i, val) SET(setIndex++, PyString_FromString(p->gr_name)); -#ifdef __VMS +#if defined(__VMS) || defined(__MVS__) SET(setIndex++, Py_None); Py_INCREF(Py_None); #else Index: Modules/dlmodule.c =================================================================== --- Modules/dlmodule.c (revision 58531) +++ Modules/dlmodule.c (working copy) @@ -65,7 +65,7 @@ Py_Type(args)->tp_name); return NULL; } - func = dlsym(xp->dl_handle, name); + func = (PyUnivPtr *) dlsym(xp->dl_handle, name); if (func == NULL) { Py_INCREF(Py_None); return Py_None; @@ -184,7 +184,7 @@ } #endif } - handle = dlopen(name, mode); + handle = (PyUnivPtr *) dlopen(name, mode); if (handle == NULL) { PyErr_SetString(Dlerror, dlerror()); return NULL; Index: Modules/makesetup =================================================================== --- Modules/makesetup (revision 58531) +++ Modules/makesetup (working copy) @@ -221,7 +221,7 @@ *) cc="$cc \$(PY_CFLAGS)";; esac - rule="$obj: $src; $cc $cpps -c $src -o $obj" + rule="$obj: $src; $cc $cpps -o $obj -c $src" echo "$rule" >>$rulesf done case $doconfig in @@ -238,7 +238,7 @@ no) SHAREDMODS="$SHAREDMODS $file";; esac rule="$file: $objs" - rule="$rule; \$(BLDSHARED) $objs $libs $ExtraLibs -o $file" + rule="$rule; \$(BLDSHARED) -o $file $objs $libs $ExtraLibs" echo "$rule" >>$rulesf done done Index: Modules/_ctypes/_ctypes_test.c =================================================================== --- Modules/_ctypes/_ctypes_test.c (revision 58531) +++ Modules/_ctypes/_ctypes_test.c (working copy) @@ -361,7 +361,9 @@ struct BITS { int A: 1, B:2, C:3, D:4, E: 5, F: 6, G: 7, H: 8, I: 9; +#ifndef __MVS__ short M: 1, N: 2, O: 3, P: 4, Q: 5, R: 6, S: 7; +#endif }; DL_EXPORT(void) set_bitfields(struct BITS *bits, char name, int value) @@ -376,7 +378,7 @@ case 'G': bits->G = value; break; case 'H': bits->H = value; break; case 'I': bits->I = value; break; - +#ifndef __MVS__ case 'M': bits->M = value; break; case 'N': bits->N = value; break; case 'O': bits->O = value; break; @@ -384,6 +386,7 @@ case 'Q': bits->Q = value; break; case 'R': bits->R = value; break; case 'S': bits->S = value; break; +#endif } } @@ -399,7 +402,7 @@ case 'G': return bits->G; case 'H': return bits->H; case 'I': return bits->I; - +#ifndef __MVS__ case 'M': return bits->M; case 'N': return bits->N; case 'O': return bits->O; @@ -407,6 +410,7 @@ case 'Q': return bits->Q; case 'R': return bits->R; case 'S': return bits->S; +#endif } return 0; } Index: Modules/socketmodule.c =================================================================== --- Modules/socketmodule.c (revision 58531) +++ Modules/socketmodule.c (working copy) @@ -70,6 +70,10 @@ # pragma weak inet_aton #endif +#ifdef __MVS__ +#define _OE_SOCKETS +#endif + #include "Python.h" #include "structmember.h" Index: Modules/mmapmodule.c =================================================================== --- Modules/mmapmodule.c (revision 58531) +++ Modules/mmapmodule.c (working copy) @@ -36,6 +36,7 @@ #ifdef UNIX #include #include +#include #if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE) static int Index: Modules/socketmodule.h =================================================================== --- Modules/socketmodule.h (revision 58531) +++ Modules/socketmodule.h (working copy) @@ -8,9 +8,16 @@ # include # endif # include +#ifdef __MVS__ +# ifndef __IPV6 + /* defined in netdb only if __IPV6 is defined !!! */ +# define NI_NUMERICHOST 0x02 +# endif +#else # if !(defined(__BEOS__) || defined(__CYGWIN__) || (defined(PYOS_OS2) && defined(PYCC_VACPP))) # include # endif +#endif #else /* MS_WINDOWS */ #if _MSC_VER >= 1300 Index: Modules/unicodedata.c =================================================================== --- Modules/unicodedata.c (revision 58531) +++ Modules/unicodedata.c (working copy) @@ -766,7 +766,7 @@ unsigned long h = 0; unsigned long ix; for (i = 0; i < len; i++) { - h = (h * scale) + (unsigned char) toupper(Py_CHARMASK(s[i])); + h = (h * scale) + Py_UNICODE_FROM_CHAR(toupper(Py_CHARMASK(s[i]))); ix = h & 0xff000000; if (ix) h = (h ^ ((ix>>24) & 0xff)) & 0x00ffffff; @@ -892,11 +892,11 @@ while (*w < 128) { if (i >= buflen) return 0; /* buffer overflow */ - buffer[i++] = *w++; + buffer[i++] = Py_UNICODE_AS_CHAR(*w++); } if (i >= buflen) return 0; /* buffer overflow */ - buffer[i++] = *w & 127; + buffer[i++] = Py_UNICODE_AS_CHAR(*w & 127); if (*w == 128) break; /* end of word */ } Index: Modules/resource.c =================================================================== --- Modules/resource.c (revision 58531) +++ Modules/resource.c (working copy) @@ -19,6 +19,16 @@ #define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001) +#ifndef RLIM_NLIMITS +# ifdef __MVS__ +/* On z/OS, RLIM_NLIMITS isn't defined. The RLIMIT_* -values range + from 0 to 7. */ +# define RLIM_NLIMITS 8 +# else +# error "RLIM_NLIMITS not defined" +# endif +#endif + static PyObject *ResourceError; PyDoc_STRVAR(struct_rusage__doc__, @@ -86,6 +96,7 @@ PyFloat_FromDouble(doubletime(ru.ru_utime))); PyStructSequence_SET_ITEM(result, 1, PyFloat_FromDouble(doubletime(ru.ru_stime))); +#ifndef __MVS__ PyStructSequence_SET_ITEM(result, 2, PyInt_FromLong(ru.ru_maxrss)); PyStructSequence_SET_ITEM(result, 3, PyInt_FromLong(ru.ru_ixrss)); PyStructSequence_SET_ITEM(result, 4, PyInt_FromLong(ru.ru_idrss)); @@ -100,7 +111,7 @@ PyStructSequence_SET_ITEM(result, 13, PyInt_FromLong(ru.ru_nsignals)); PyStructSequence_SET_ITEM(result, 14, PyInt_FromLong(ru.ru_nvcsw)); PyStructSequence_SET_ITEM(result, 15, PyInt_FromLong(ru.ru_nivcsw)); - +#endif if (PyErr_Occurred()) { Py_DECREF(result); return NULL; Index: Modules/pyexpat.c =================================================================== --- Modules/pyexpat.c (revision 58531) +++ Modules/pyexpat.c (working copy) @@ -85,8 +85,8 @@ static PyTypeObject Xmlparsetype; -typedef void (*xmlhandlersetter)(XML_Parser self, void *meth); -typedef void* xmlhandler; +typedef void (*xmlhandler)(); +typedef void (*xmlhandlersetter)(XML_Parser self, xmlhandler meth); struct HandlerInfo { const char *name; Index: Modules/pwdmodule.c =================================================================== --- Modules/pwdmodule.c (revision 58531) +++ Modules/pwdmodule.c (working copy) @@ -68,14 +68,14 @@ #define SETS(i,val) sets(v, i, val) SETS(setIndex++, p->pw_name); -#ifdef __VMS +#if defined(__VMS) || defined(__MVS__) SETS(setIndex++, ""); #else SETS(setIndex++, p->pw_passwd); #endif SETI(setIndex++, p->pw_uid); SETI(setIndex++, p->pw_gid); -#ifdef __VMS +#if defined(__VMS) || defined(__MVS__) SETS(setIndex++, ""); #else SETS(setIndex++, p->pw_gecos); Index: Modules/posixmodule.c =================================================================== --- Modules/posixmodule.c (revision 58531) +++ Modules/posixmodule.c (working copy) @@ -5596,6 +5596,7 @@ PyFloat_FromDouble(doubletime(ru->ru_utime))); PyStructSequence_SET_ITEM(result, 1, PyFloat_FromDouble(doubletime(ru->ru_stime))); +#ifndef __MVS__ #define SET_INT(result, index, value)\ PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value)) SET_INT(result, 2, ru->ru_maxrss); @@ -5613,6 +5614,7 @@ SET_INT(result, 14, ru->ru_nvcsw); SET_INT(result, 15, ru->ru_nivcsw); #undef SET_INT +#endif if (PyErr_Occurred()) { Py_DECREF(result); Index: Modules/_cursesmodule.c =================================================================== --- Modules/_cursesmodule.c (revision 58531) +++ Modules/_cursesmodule.c (working copy) @@ -104,12 +104,13 @@ #include "Python.h" -#ifdef __osf__ +#if defined(__osf__) || defined(__hpux) || defined(__MVS__) #define STRICT_SYSV_CURSES /* Don't use ncurses extensions */ #endif -#ifdef __hpux -#define STRICT_SYSV_CURSES +#ifndef __MVS__ +#define HAVE_GETATTRS +#define HAVE_GETSYX #endif #define CURSES_MODULE @@ -165,6 +166,23 @@ "must call start_color() first"); \ return 0; } +#ifdef HAVE_GETATTRS +#define SET_ATTRS(use_attrs, self, attr_old, attr) do { \ + if (use_attrs == TRUE) { \ + attr_old = getattrs(self->win); \ + wattrset(self->win, attr); \ + } \ +} while (0) + +#define RESTORE_ATTRS(use_attrs, self, attr_old) do { \ + if (use_attrs == TRUE) \ + wattrset(self->win, attr_old); \ +} while (0) +#else +#define SET_ATTRS(use_attrs, self, attr_old, attr) do { } while (0) +#define RESTORE_ATTRS(use_attrs, self, attr_old) do { } while (0) +#endif + #ifndef MIN #define MIN(x,y) ((x) < (y) ? (x) : (y)) #endif @@ -445,16 +463,12 @@ return NULL; } - if (use_attr == TRUE) { - attr_old = getattrs(self->win); - wattrset(self->win,attr); - } + SET_ATTRS(use_attr, self, attr_old, attr); if (use_xy == TRUE) rtn = mvwaddstr(self->win,y,x,str); else rtn = waddstr(self->win,str); - if (use_attr == TRUE) - wattrset(self->win,attr_old); + RESTORE_ATTRS(use_attr, self, attr_old); return PyCursesCheckERR(rtn, "addstr"); } @@ -491,16 +505,12 @@ return NULL; } - if (use_attr == TRUE) { - attr_old = getattrs(self->win); - wattrset(self->win,attr); - } + SET_ATTRS(use_attr, self, attr_old, attr); if (use_xy == TRUE) rtn = mvwaddnstr(self->win,y,x,str,n); else rtn = waddnstr(self->win,str,n); - if (use_attr == TRUE) - wattrset(self->win,attr_old); + RESTORE_ATTRS(use_attr, self, attr_old); return PyCursesCheckERR(rtn, "addnstr"); } @@ -1082,16 +1092,12 @@ return NULL; } - if (use_attr == TRUE) { - attr_old = getattrs(self->win); - wattrset(self->win,attr); - } + SET_ATTRS(use_attr, self, attr_old, attr); if (use_xy == TRUE) rtn = mvwinsstr(self->win,y,x,str); else rtn = winsstr(self->win,str); - if (use_attr == TRUE) - wattrset(self->win,attr_old); + RESTORE_ATTRS(use_attr, self, attr_old); return PyCursesCheckERR(rtn, "insstr"); } @@ -1128,16 +1134,12 @@ return NULL; } - if (use_attr == TRUE) { - attr_old = getattrs(self->win); - wattrset(self->win,attr); - } + SET_ATTRS(use_attr, self, attr_old, attr); if (use_xy == TRUE) rtn = mvwinsnstr(self->win,y,x,str,n); else rtn = winsnstr(self->win,str,n); - if (use_attr == TRUE) - wattrset(self->win,attr_old); + RESTORE_ATTRS(use_attr, self, attr_old); return PyCursesCheckERR(rtn, "insnstr"); } @@ -1692,6 +1694,7 @@ return PyString_FromStringAndSize(&ch, 1); } +#ifdef HAVE_GETSYX static PyObject * PyCurses_getsyx(PyObject *self) { @@ -1703,6 +1706,7 @@ return Py_BuildValue("(ii)", y, x); } +#endif #ifdef NCURSES_MOUSE_VERSION static PyObject * @@ -2576,7 +2580,9 @@ {"getmouse", (PyCFunction)PyCurses_GetMouse, METH_NOARGS}, {"ungetmouse", (PyCFunction)PyCurses_UngetMouse, METH_VARARGS}, #endif +#ifdef HAVE_GETSYX {"getsyx", (PyCFunction)PyCurses_getsyx, METH_NOARGS}, +#endif {"getwin", (PyCFunction)PyCurses_GetWin, METH_O}, {"has_colors", (PyCFunction)PyCurses_has_colors, METH_NOARGS}, {"has_ic", (PyCFunction)PyCurses_has_ic, METH_NOARGS}, Index: Modules/cPickle.c =================================================================== --- Modules/cPickle.c (revision 58531) +++ Modules/cPickle.c (working copy) @@ -15,7 +15,12 @@ #define WRITE_BUF_SIZE 256 /* Bump this when new opcodes are added to the pickle protocol. */ +#ifdef Py_CHARSET_ASCII #define HIGHEST_PROTOCOL 2 +#else +/* With EBCDIC we can only do plain-text pickles. */ +#define HIGHEST_PROTOCOL 0 +#endif /* * Pickle opcodes. These must be kept in synch with pickle.py. Extensive @@ -64,6 +69,7 @@ #define SETITEMS 'u' /* Protocol 2. */ +#if HIGHEST_PROTOCOL >= 2 #define PROTO '\x80' /* identify pickle protocol */ #define NEWOBJ '\x81' /* build object by applying cls.__new__ to argtuple */ #define EXT1 '\x82' /* push object from extension registry; 1-byte index */ @@ -76,6 +82,7 @@ #define NEWFALSE '\x89' /* push False */ #define LONG1 '\x8a' /* push long from < 256 bytes */ #define LONG4 '\x8b' /* push really big long */ +#endif /* There aren't opcodes -- they're ways to pickle bools before protocol 2, * so that unpicklers written before bools were introduced unpickle them @@ -962,13 +969,15 @@ static const char *buf[2] = {FALSE, TRUE}; static char len[2] = {sizeof(FALSE)-1, sizeof(TRUE)-1}; long l = PyInt_AS_LONG((PyIntObject *)args); - +#if HIGHEST_PROTOCOL >= 2 if (self->proto >= 2) { char opcode = l ? NEWTRUE : NEWFALSE; if (self->write_func(self, &opcode, 1) < 0) return -1; } - else if (self->write_func(self, buf[l], len[l]) < 0) + else +#endif + if (self->write_func(self, buf[l], len[l]) < 0) return -1; return 0; } @@ -1032,7 +1041,7 @@ PyObject *repr = NULL; static char l = LONG; - +#if HIGHEST_PROTOCOL >= 2 if (self->proto >= 2) { /* Linear-time pickling. */ size_t nbits; @@ -1110,7 +1119,7 @@ res = 0; goto finally; } - +#endif /* proto < 2: write the repr and newline. This is quadratic-time * (in the number of digits), in both directions. */ @@ -1406,8 +1415,9 @@ static char tuple = TUPLE; static char pop = POP; static char pop_mark = POP_MARK; +#if HIGHEST_PROTOCOL >= 2 static char len2opcode[] = {EMPTY_TUPLE, TUPLE1, TUPLE2, TUPLE3}; - +#endif if ((len = PyTuple_Size(args)) < 0) goto finally; @@ -1439,7 +1449,7 @@ py_tuple_id = PyLong_FromVoidPtr(args); if (py_tuple_id == NULL) goto finally; - +#if HIGHEST_PROTOCOL >= 2 if (len <= 3 && self->proto >= 2) { /* Use TUPLE{1,2,3} opcodes. */ if (store_tuple_elements(self, args, len) < 0) @@ -1460,7 +1470,7 @@ goto finally; goto memoize; } - +#endif /* proto < 2 and len > 0, or proto >= 2 and len > 3. * Generate MARK elt1 elt2 ... TUPLE */ @@ -1991,7 +2001,7 @@ goto finally; } Py_DECREF(klass); - +#if HIGHEST_PROTOCOL >= 2 if (self->proto >= 2) { /* See whether this is in the extension registry, and if * so generate an EXT opcode. @@ -2047,7 +2057,7 @@ res = 0; goto finally; /* and don't memoize */ } - +#endif gen_global: if (self->write_func(self, &global, 1) < 0) goto finally; @@ -2148,13 +2158,14 @@ PyObject *state = NULL; PyObject *listitems = NULL; PyObject *dictitems = NULL; - +#if HIGHEST_PROTOCOL >= 2 int use_newobj = self->proto >= 2; - + static char newobj = NEWOBJ; +#endif static char reduce = REDUCE; static char build = BUILD; - static char newobj = NEWOBJ; + if (! PyArg_UnpackTuple(args, "save_reduce", 2, 5, &callable, &argtup, @@ -2176,6 +2187,7 @@ if (dictitems == Py_None) dictitems = NULL; +#if HIGHEST_PROTOCOL >= 2 /* Protocol 2 special case: if callable's name is __newobj__, use * NEWOBJ. This consumes a lot of code. */ @@ -2258,7 +2270,9 @@ if (self->write_func(self, &newobj, 1) < 0) return -1; } - else { + else +#endif + { /* Not using NEWOBJ. */ if (save(self, callable, 0) < 0 || save(self, argtup, 0) < 0 || @@ -2566,7 +2580,7 @@ dump(Picklerobject *self, PyObject *args) { static char stop = STOP; - +#if HIGHEST_PROTOCOL >= 2 if (self->proto >= 2) { char bytes[2]; @@ -2576,7 +2590,7 @@ if (self->write_func(self, bytes, 2) < 0) return -1; } - +#endif if (save(self, args, 0) < 0) return -1; @@ -4476,7 +4490,7 @@ if (load_long(self) < 0) break; continue; - +#if HIGHEST_PROTOCOL >= 2 case LONG1: if (load_counted_long(self, 1) < 0) break; @@ -4486,7 +4500,7 @@ if (load_counted_long(self, 4) < 0) break; continue; - +#endif case FLOAT: if (load_float(self) < 0) break; @@ -4529,6 +4543,7 @@ break; continue; +#if HIGHEST_PROTOCOL >= 2 case TUPLE1: if (load_counted_tuple(self, 1) < 0) break; @@ -4543,7 +4558,7 @@ if (load_counted_tuple(self, 3) < 0) break; continue; - +#endif case TUPLE: if (load_tuple(self) < 0) break; @@ -4578,12 +4593,12 @@ if (load_inst(self) < 0) break; continue; - +#if HIGHEST_PROTOCOL >= 2 case NEWOBJ: if (load_newobj(self) < 0) break; continue; - +#endif case GLOBAL: if (load_global(self) < 0) break; @@ -4623,7 +4638,7 @@ if (load_get(self) < 0) break; continue; - +#if HIGHEST_PROTOCOL >= 2 case EXT1: if (load_extension(self, 1) < 0) break; @@ -4638,6 +4653,7 @@ if (load_extension(self, 4) < 0) break; continue; +#endif case MARK: if (load_mark(self) < 0) break; @@ -4695,7 +4711,7 @@ if (load_reduce(self) < 0) break; continue; - +#if HIGHEST_PROTOCOL >= 2 case PROTO: if (load_proto(self) < 0) break; @@ -4710,7 +4726,7 @@ if (load_bool(self, Py_False) < 0) break; continue; - +#endif case '\0': /* end of file */ PyErr_SetNone(PyExc_EOFError); @@ -4866,7 +4882,7 @@ if (load_long(self) < 0) break; continue; - +#if HIGHEST_PROTOCOL >= 2 case LONG1: if (load_counted_long(self, 1) < 0) break; @@ -4876,7 +4892,7 @@ if (load_counted_long(self, 4) < 0) break; continue; - +#endif case FLOAT: if (load_float(self) < 0) break; @@ -4918,7 +4934,7 @@ if (load_counted_tuple(self, 0) < 0) break; continue; - +#if HIGHEST_PROTOCOL >= 2 case TUPLE1: if (load_counted_tuple(self, 1) < 0) break; @@ -4933,7 +4949,7 @@ if (load_counted_tuple(self, 3) < 0) break; continue; - +#endif case TUPLE: if (load_tuple(self) < 0) break; @@ -4968,12 +4984,12 @@ if (noload_inst(self) < 0) break; continue; - +#if HIGHEST_PROTOCOL >= 2 case NEWOBJ: if (noload_newobj(self) < 0) break; continue; - +#endif case GLOBAL: if (noload_global(self) < 0) break; @@ -5013,7 +5029,7 @@ if (load_get(self) < 0) break; continue; - +#if HIGHEST_PROTOCOL >= 2 case EXT1: if (noload_extension(self, 1) < 0) break; @@ -5028,7 +5044,7 @@ if (noload_extension(self, 4) < 0) break; continue; - +#endif case MARK: if (load_mark(self) < 0) break; @@ -5086,7 +5102,7 @@ if (noload_reduce(self) < 0) break; continue; - +#if HIGHEST_PROTOCOL >= 2 case PROTO: if (load_proto(self) < 0) break; @@ -5101,6 +5117,7 @@ if (load_bool(self, Py_False) < 0) break; continue; +#endif default: cPickle_ErrFormat(UnpicklingError, "invalid load key, '%s'.", Index: pyconfig.h.in =================================================================== --- pyconfig.h.in (revision 58531) +++ pyconfig.h.in (working copy) @@ -967,6 +967,12 @@ /* Define to activate Unix95-and-earlier features */ #undef _XOPEN_SOURCE_EXTENDED +/* Define on z/OS to get partial SUSv3 support. */ +#undef _UNIX03_SOURCE + +/* Define on z/OS to make pthreads work. */ +#undef _OPEN_THREADS + /* Define on FreeBSD to activate all library features */ #undef __BSD_VISIBLE