From mhammond@skippinet.com.au Sat Apr 1 05:17:39 2000 From: mhammond@skippinet.com.au (Mark Hammond) Date: Sat, 1 Apr 2000 15:17:39 +1000 Subject: [Patches] test_winreg doesnt delete its test data. Message-ID: The call to remove the test data (also testing the delete functions) was commented out! diff -r1.1 test_winreg.py 125c125 < # DeleteTestData(root_key) --- > DeleteTestData(root_key) Release info: I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. Mark. From fdrake@acm.org Sat Apr 1 05:26:17 2000 From: fdrake@acm.org (Fred L. Drake, Jr.) Date: Sat, 1 Apr 2000 00:26:17 -0500 (EST) Subject: [Patches] test_winreg doesnt delete its test data. In-Reply-To: References: Message-ID: <14565.34937.561497.697032@seahag.cnri.reston.va.us> Mark Hammond writes: > The call to remove the test data (also testing the delete functions) > was commented out! Thanks Mark! -Fred -- Fred L. Drake, Jr. Corporation for National Research Initiatives From sjoerd@oratrix.nl Sat Apr 1 12:47:53 2000 From: sjoerd@oratrix.nl (Sjoerd Mullender) Date: Sat, 01 Apr 2000 14:47:53 +0200 Subject: [Patches] Lib/sre*.py modules checked in wrong Message-ID: <20000401124754.724B1301CF9@bireme.oratrix.nl> Please check the Lib/sre*.py modules in again, since they contain ^M's when I check them out on Linux. When I try to compile these modules using py_compile, it complains about syntax errors. Thanks. -- Sjoerd Mullender From mal@lemburg.com Sat Apr 1 19:40:22 2000 From: mal@lemburg.com (M.-A. Lemburg) Date: Sat, 01 Apr 2000 21:40:22 +0200 Subject: [Patches] Unicode Doc Snapshot 2000-04-01 Message-ID: <38E650A6.74C5B6E1@lemburg.com> This is a multi-part message in MIME format. --------------AC5A3AFAAB32FC257EC8E73D Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit No, not a joke... I added a fairly complete section to api.tex explaining the C API side of things. The patch also includes other patches for the different new APIs and small changes that were done in order to make Unicode intergrate well with strings and other objects. Please note that I have not checked whether the docs compile or not... there may be piles of those nice TeX errors in there ;-) -- Marc-Andre Lemburg ______________________________________________________________________ Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ --------------AC5A3AFAAB32FC257EC8E73D Content-Type: text/plain; charset=iso-8859-1; name="Unicode-Implementation-2000-04-01-Doc.patch" Content-Transfer-Encoding: 8bit Content-Disposition: inline; filename="Unicode-Implementation-2000-04-01-Doc.patch" diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS CVS-Python/Doc/api/api.tex Python+Unicode/Doc/api/api.tex --- CVS-Python/Doc/api/api.tex Fri Mar 31 10:37:59 2000 +++ Python+Unicode/Doc/api/api.tex Sat Apr 1 21:30:53 2000 @@ -1847,6 +1847,717 @@ \end{cfuncdesc} +\subsection{Unicode Objects \label{unicodeObjects}} + +%--- Unicode Type ------------------------------------------------------- + +These are the basic Unicode object types used for the Unicode +implementation in Python: + +\begin{ctypedesc}{Py_UNICODE} +This type represents a 16-bit unsigned storage type which is used by +Python internally as basis for holding Unicode ordinals. On platforms +where \ctype{wchar_t} is available and also has 16-bits, +\ctype{Py_UNICODE} is a typedef alias for \ctype{wchar_t} to enhance +native platform compatibility. On all other platforms, +\ctype{Py_UNICODE} is a typedef alias for \ctype{unsigned short}. +\end{ctypedesc} + +\begin{ctypedesc}{PyUnicodeObject} +This subtype of \ctype{PyObject} represents a Python Unicode object. +\end{ctypedesc} + +\begin{cvardesc}{PyTypeObject}{PyUnicode_Type} +This instance of \ctype{PyTypeObject} represents the Python Unicode type. +\end{cvardesc} + +%--- These are really C macros... is there a macrodesc TeX macro ? + +The following APIs are really C macros and can be used to do fast +checks and to access internal read-only data of Unicode objects: + +\begin{cfuncdesc}{int}{PyUnicode_Check}{PyObject *o} +Returns true if the object \var{o} is a Unicode object. +\end{cfuncdesc} + +\begin{cfuncdesc}{int}{PyUnicode_GET_SIZE}{PyObject *o} +Returns the size of the object. o has to be a +PyUnicodeObject (not checked). +\end{cfuncdesc} + +\begin{cfuncdesc}{int}{PyUnicode_GET_DATA_SIZE}{PyObject *o} +Returns the size of the object's internal buffer in bytes. o has to be +a PyUnicodeObject (not checked). +\end{cfuncdesc} + +\begin{cfuncdesc}{int}{PyUnicode_AS_UNICODE}{PyObject *o} +Returns a pointer to the internal Py_UNICODE buffer of the object. o +has to be a PyUnicodeObject (not checked). +\end{cfuncdesc} + +\begin{cfuncdesc}{int}{PyUnicode_AS_DATA}{PyObject *o} +Returns a (const char *) pointer to the internal buffer of the object. +o has to be a PyUnicodeObject (not checked). +\end{cfuncdesc} + +% --- Unicode character properties --------------------------------------- + +Unicode provides many different character properties. The most often +needed ones are available through these macros which are mapped to C +functions depending on the Python configuration. + +\begin{cfuncdesc}{int}{Py_UNICODE_ISSPACE}{Py_UNICODE ch} +Returns 1/0 depending on whether \var{ch} is a whitespace character. +\end{cfuncdesc} + +\begin{cfuncdesc}{int}{Py_UNICODE_ISLOWER}{Py_UNICODE ch} +Returns 1/0 depending on whether \var{ch} is a lowercase character. +\end{cfuncdesc} + +\begin{cfuncdesc}{int}{Py_UNICODE_ISUPPER}{Py_UNICODE ch} +Returns 1/0 depending on whether \var{ch} is a uppercase character. +\end{cfuncdesc} + +\begin{cfuncdesc}{int}{Py_UNICODE_ISTITLE}{Py_UNICODE ch} +Returns 1/0 depending on whether \var{ch} is a titlecase character. +\end{cfuncdesc} + +\begin{cfuncdesc}{int}{Py_UNICODE_ISLINEBREAK}{Py_UNICODE ch} +Returns 1/0 depending on whether \var{ch} is a linebreak character. +\end{cfuncdesc} + +\begin{cfuncdesc}{int}{Py_UNICODE_ISDECIMAL}{Py_UNICODE ch} +Returns 1/0 depending on whether \var{ch} is a decimal character. +\end{cfuncdesc} + +\begin{cfuncdesc}{int}{Py_UNICODE_ISDIGIT}{Py_UNICODE ch} +Returns 1/0 depending on whether \var{ch} is a digit character. +\end{cfuncdesc} + +\begin{cfuncdesc}{int}{Py_UNICODE_ISNUMERIC}{Py_UNICODE ch} +Returns 1/0 depending on whether \var{ch} is a numeric character. +\end{cfuncdesc} + +These APIs can be used for fast direct character conversions: + +\begin{cfuncdesc}{Py_UNICODE}{Py_UNICODE_TOLOWER}{Py_UNICODE ch} +Returns the character \var{ch} converted to lower case. +\end{cfuncdesc} + +\begin{cfuncdesc}{Py_UNICODE}{Py_UNICODE_TOUPPER}{Py_UNICODE ch} +Returns the character \var{ch} converted to upper case. +\end{cfuncdesc} + +\begin{cfuncdesc}{Py_UNICODE}{Py_UNICODE_TOTITLE}{Py_UNICODE ch} +Returns the character \var{ch} converted to title case. +\end{cfuncdesc} + +\begin{cfuncdesc}{int}{Py_UNICODE_TODECIMAL}{Py_UNICODE ch} +Returns the character \var{ch} converted to a decimal positive integer. +Returns -1 in case this is not possible. Does not raise exceptions. +\end{cfuncdesc} + +\begin{cfuncdesc}{int}{Py_UNICODE_TODIGIT}{Py_UNICODE ch} +Returns the character \var{ch} converted to a single digit integer. +Returns -1 in case this is not possible. Does not raise exceptions. +\end{cfuncdesc} + +\begin{cfuncdesc}{double}{Py_UNICODE_TONUMERIC}{Py_UNICODE ch} +Returns the character \var{ch} converted to a (positive) double. +Returns -1.0 in case this is not possible. Does not raise exceptions. +\end{cfuncdesc} + +% --- Plain Py_UNICODE --------------------------------------------------- + +To create Unicode objects and access their basic sequence properties, +use these APIs: + +\begin{cfuncdesc}{PyObject*}{PyUnicode_FromUnicode}{const Py_UNICODE *u, + int size} + +Create a Unicode Object from the Py_UNICODE buffer \var{u} of the +given size. \var{u} may be \NULL{} which causes the contents to be +undefined. It is the user's responsibility to fill in the needed data. +The buffer is copied into the new object. +\end{cfuncdesc} + +\begin{cfuncdesc}{Py_UNICODE *}{PyUnicode_AsUnicode}{PyObject *unicode} +Return a read-only pointer to the Unicode object's internal +\ctype{Py_UNICODE} buffer. +\end{cfuncdesc} + +\begin{cfuncdesc}{int}{PyUnicode_GetSize}{PyObject *unicode} +Return the length of the Unicode object. +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyUnicode_FromObject}{PyObject *obj} + +Coerce obj to an Unicode object and return a reference with +incremented refcount. + +Coercion is done in the following way: +\begin{enumerate} +\item Unicode objects are passed back as-is with incremented + refcount. + +\item String and other char buffer compatible objects are decoded + under the assumptions that they contain UTF-8 data. Decoding + is done in "strict" mode. + +\item All other objects raise an exception. +\end{enumerate} +The API returns NULL in case of an error. The caller is responsible +for decref'ing the returned objects. +\end{cfuncdesc} + +% --- wchar_t support for platforms which support it --------------------- + +If the platform supports \ctype{wchar_t} and provides a header file +wchar.h, Python can interface directly to this type using the +following functions. Support is optimized if Python's own +\ctype{Py_UNICODE} type is identical to the system's \ctype{wchar_t}. + +\begin{cfuncdesc}{PyObject*}{PyUnicode_FromWideChar}{const wchar_t *w, + int size} +Create a Unicode Object from the \ctype{whcar_t} buffer \var{w} of the +given size. Returns \NULL{} on failure. +\end{cfuncdesc} + +\begin{cfuncdesc}{int}{PyUnicode_AsWideChar}{PyUnicodeObject *unicode, + wchar_t *w, + int size} + +Copies the Unicode Object contents into the \ctype{whcar_t} buffer +\var{w}. At most \var{size} \ctype{whcar_t} characters are copied. +Returns the number of \ctype{whcar_t} characters copied or -1 in case +of an error. +\end{cfuncdesc} + + +\subsubsection{Builtin Codecs \label{builtinCodecs}} + +Python provides a set of builtin codecs which are written in C +for speed. All of these codecs are directly usable via the +following functions. + +Many of the following APIs take two arguments encoding and +errors. These parameters encoding and errors have the same semantics +as the ones of the builtin unicode() Unicode object constructor. + +Setting encoding to NULL causes the default encoding to be used which +is UTF-8. + +Error handling is set by errors which may also be set to NULL meaning +to use the default handling defined for the codec. Default error +handling for all builtin codecs is ``strict'' (ValueErrors are raised). + +The codecs all use a similar interface. Only deviation from the +following generic ones are documented for simplicity. + +% --- Generic Codecs ----------------------------------------------------- + +These are the generic codec APIs: + +\begin{cfuncdesc}{PyObject*}{PyUnicode_Decode}{const char *s, + int size, + const char *encoding, + const char *errors} + +Create a Unicode object by decoding \var{size} bytes of the encoded +string \var{s}. \var{encoding} and \var{errors} have the same meaning +as the parameters of the same name in the unicode() builtin +function. The codec to be used is looked up using the Python codec +registry. Returns \NULL{} in case an exception was raised by the +codec. +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyUnicode_Encode}{const Py_UNICODE *s, + int size, + const char *encoding, + const char *errors} + +Encodes the \ctype{Py_UNICODE} buffer of the given size and returns a +Python string object. \var{encoding} and \var{errors} have the same +meaning as the parameters of the same name in the Unicode .encode() +method. The codec to be used is looked up using the Python codec +registry. Returns \NULL{} in case an exception was raised by the +codec. +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyUnicode_AsEncodedString}{PyObject *unicode, + const char *encoding, + const char *errors} + +Encodes a Unicode object and returns the result as Python string +object. \var{encoding} and \var{errors} have the same meaning as the +parameters of the same name in the Unicode .encode() method. The codec +to be used is looked up using the Python codec registry. Returns +\NULL{} in case an exception was raised by the codec. +\end{cfuncdesc} + +% --- UTF-8 Codecs ------------------------------------------------------- + +These are the UTF-8 codec APIs: + +\begin{cfuncdesc}{PyObject*}{PyUnicode_DecodeUTF8}{const char *s, + int size, + const char *errors} + +Creates a Unicode object by decoding \var{size} bytes of the UTF-8 +encoded string \var{s}. Returns \NULL{} in case an exception was +raised by the codec. +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyUnicode_EncodeUTF8}{const Py_UNICODE *s, + int size, + const char *errors} + +Encodes the \ctype{Py_UNICODE} buffer of the given size using UTF-8 +and returns a Python string object. Returns \NULL{} in case an +exception was raised by the codec. +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyUnicode_AsUTF8String}{PyObject *unicode} + +Encodes a Unicode objects using UTF-8 and returns the result as Python +string object. Error handling is ``strict''. Returns +\NULL{} in case an exception was raised by the codec. +\end{cfuncdesc} + +% --- UTF-16 Codecs ------------------------------------------------------ */ + +These are the UTF-16 codec APIs: + +\begin{cfuncdesc}{PyObject*}{PyUnicode_DecodeUTF16}{const char *s, + int size, + const char *errors, + int *byteorder} + +Decodes \var{length} bytes from a UTF-16 encoded buffer string and +returns the corresponding Unicode object. + +\var{errors} (if non-NULL) defines the error handling. It defaults +to ``strict''. + +If \var{byteorder} is non-\NULL{}, the decoder starts decoding using +the given byte order: + +\begin{verbatim} + *byteorder == -1: little endian + *byteorder == 0: native order + *byteorder == 1: big endian +\end{verbatim} + +and then switches according to all byte order marks (BOM) it finds in +the input data. BOM marks are not copied into the resulting Unicode +string. After completion, \var{*byteorder} is set to the current byte +order at the end of input data. + +If \var{byteorder} is \NULL{}, the codec starts in native order mode. + +Returns \NULL{} in case an exception was raised by the codec. +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyUnicode_EncodeUTF16}{const Py_UNICODE *s, + int size, + const char *errors, + int byteorder} + +Returns a Python string object holding the UTF-16 encoded value of the +Unicode data in \var{s}. + +If \var{byteorder} is not 0, output is written according to the +following byte order: + +\begin{verbatim} + byteorder == -1: little endian + byteorder == 0: native byte order (writes a BOM mark) + byteorder == 1: big endian +\end{verbatim} + +If byteorder is 0, the output string will always start with the +Unicode BOM mark (U+FEFF). In the other two modes, no BOM mark is +prepended. + +Note that \ctype{Py_UNICODE} data is being interpreted as UTF-16 +reduced to UCS-2. This trick makes it possible to add full UTF-16 +capabilities at a later point without comprimising the APIs. + +Returns \NULL{} in case an exception was raised by the codec. +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyUnicode_AsUTF16String}{PyObject *unicode} + +Returns a Python string using the UTF-16 encoding in native byte +order. The string always starts with a BOM mark. Error handling is +``strict''. Returns \NULL{} in case an exception was raised by the +codec. +\end{cfuncdesc} + +% --- Unicode-Escape Codecs ---------------------------------------------- + +These are the ``Unicode Esacpe'' codec APIs: + +\begin{cfuncdesc}{PyObject*}{PyUnicode_DecodeUnicodeEscape}{const char *s, + int size, + const char *errors} + +Creates a Unicode object by decoding \var{size} bytes of the Unicode-Esacpe +encoded string \var{s}. Returns \NULL{} in case an exception was +raised by the codec. +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyUnicode_EncodeUnicodeEscape}{const Py_UNICODE *s, + int size, + const char *errors} + +Encodes the \ctype{Py_UNICODE} buffer of the given size using Unicode-Escape +and returns a Python string object. Returns \NULL{} in case an +exception was raised by the codec. +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyUnicode_AsUnicodeEscapeString}{PyObject *unicode} + +Encodes a Unicode objects using Unicode-Escape and returns the result +as Python string object. Error handling is ``strict''. Returns +\NULL{} in case an exception was raised by the codec. +\end{cfuncdesc} + +% --- Raw-Unicode-Escape Codecs ------------------------------------------ + +These are the ``Raw Unicode Esacpe'' codec APIs: + +\begin{cfuncdesc}{PyObject*}{PyUnicode_DecodeRawUnicodeEscape}{const char *s, + int size, + const char *errors} + +Creates a Unicode object by decoding \var{size} bytes of the Raw-Unicode-Esacpe +encoded string \var{s}. Returns \NULL{} in case an exception was +raised by the codec. +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyUnicode_EncodeRawUnicodeEscape}{const Py_UNICODE *s, + int size, + const char *errors} + +Encodes the \ctype{Py_UNICODE} buffer of the given size using Raw-Unicode-Escape +and returns a Python string object. Returns \NULL{} in case an +exception was raised by the codec. +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyUnicode_AsRawUnicodeEscapeString}{PyObject *unicode} + +Encodes a Unicode objects using Raw-Unicode-Escape and returns the result +as Python string object. Error handling is ``strict''. Returns +\NULL{} in case an exception was raised by the codec. +\end{cfuncdesc} + +% --- Latin-1 Codecs ----------------------------------------------------- + +These are the Latin-1 codec APIs: + +Latin-1 corresponds to the first 256 Unicode ordinals and only these +are accepted by the codecs during encoding. + +\begin{cfuncdesc}{PyObject*}{PyUnicode_DecodeLatin1}{const char *s, + int size, + const char *errors} + +Creates a Unicode object by decoding \var{size} bytes of the Latin-1 +encoded string \var{s}. Returns \NULL{} in case an exception was +raised by the codec. +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyUnicode_EncodeLatin1}{const Py_UNICODE *s, + int size, + const char *errors} + +Encodes the \ctype{Py_UNICODE} buffer of the given size using Latin-1 +and returns a Python string object. Returns \NULL{} in case an +exception was raised by the codec. +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyUnicode_AsLatin1String}{PyObject *unicode} + +Encodes a Unicode objects using Latin-1 and returns the result as +Python string object. Error handling is ``strict''. Returns +\NULL{} in case an exception was raised by the codec. +\end{cfuncdesc} + +% --- ASCII Codecs ------------------------------------------------------- + +These are the ASCII codec APIs: + +Only 7-bit ASCII data is excepted. All other codes generate errors. + +\begin{cfuncdesc}{PyObject*}{PyUnicode_DecodeASCII}{const char *s, + int size, + const char *errors} + +Creates a Unicode object by decoding \var{size} bytes of the ASCII +encoded string \var{s}. Returns \NULL{} in case an exception was +raised by the codec. +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyUnicode_EncodeASCII}{const Py_UNICODE *s, + int size, + const char *errors} + +Encodes the \ctype{Py_UNICODE} buffer of the given size using ASCII +and returns a Python string object. Returns \NULL{} in case an +exception was raised by the codec. +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyUnicode_AsASCIIString}{PyObject *unicode} + +Encodes a Unicode objects using ASCII and returns the result as Python +string object. Error handling is ``strict''. Returns +\NULL{} in case an exception was raised by the codec. +\end{cfuncdesc} + +% --- Character Map Codecs ----------------------------------------------- + +These are the mapping codec APIs: + +This codec is special in that it can be used to implement many +different codecs (and this is in fact what was done to obtain most of +the standard codecs included in the \module{encodings} package). The +codec uses mapping to encode and decode characters. + +Decoding mappings must map single string characters to single Unicode +characters, integers (which are then interpreted as Unicode ordinals) +or None (meaning "undefined mapping" and causing an error). + +Encoding mappings must map single Unicode characters to single string +characters, integers (which are then interpreted as Latin-1 ordinals) +or None (meaning "undefined mapping" and causing an error). + +The mapping objects provided must only support the __getitem__ mapping +interface. + +If a character lookup fails with a LookupError, the character is +copied as-is meaning that its ordinal value will be interpreted as +Unicode or Latin-1 ordinal resp. Because of this, mappings only need +to contain those mappings which map characters to different code +points. + +\begin{cfuncdesc}{PyObject*}{PyUnicode_DecodeCharmap}{const char *s, + int size, + PyObject *mapping, + const char *errors} + +Creates a Unicode object by decoding \var{size} bytes of the encoded +string \var{s} using the given \var{mapping} object. Returns \NULL{} +in case an exception was raised by the codec. +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyUnicode_EncodeCharmap}{const Py_UNICODE *s, + int size, + PyObject *mapping, + const char *errors} + +Encodes the \ctype{Py_UNICODE} buffer of the given size using the +given \var{mapping} object and returns a Python string object. +Returns \NULL{} in case an exception was raised by the codec. +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyUnicode_AsCharmapString}{PyObject *unicode, + PyObject *mapping} + +Encodes a Unicode objects using the given \var{mapping} object and +returns the result as Python string object. Error handling is +``strict''. Returns \NULL{} in case an exception was raised by the +codec. +\end{cfuncdesc} + +The following codec API is special in that maps Unicode to Unicode. + +\begin{cfuncdesc}{PyObject*}{PyUnicode_TranslateCharmap}{const Py_UNICODE *s, + int size, + PyObject *table, + const char *errors} + +Translates a \ctype{Py_UNICODE} buffer of the given length by applying +a character mapping \var{table} to it and returns the resulting +Unicode object. + +The \var{mapping} table must map Unicode ordinal integers to Unicode +ordinal integers or None (causing deletion of the character). + +Mapping tables must only provide the __getitem__ interface, +e.g. dictionaries or sequences. Unmapped character ordinals (ones +which cause a LookupError) are left untouched and are copied as-is. + +Returns \NULL{} in case an exception was raised by the codec. +\end{cfuncdesc} + +% --- MBCS codecs for Windows -------------------------------------------- + +These are the MBCS codec APIs. They are currently only available +Windows and use the Win32 MBCS converters to implement the +conversions. + +Note that MBCS (or DBCS) is a class of encodings, not just one. The +target encoding is defined by the user settings on the machine running +the codec. + +\begin{cfuncdesc}{PyObject*}{PyUnicode_DecodeMBCS}{const char *s, + int size, + const char *errors} + +Creates a Unicode object by decoding \var{size} bytes of the MBCS +encoded string \var{s}. Returns \NULL{} in case an exception was +raised by the codec. +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyUnicode_EncodeMBCS}{const Py_UNICODE *s, + int size, + const char *errors} + +Encodes the \ctype{Py_UNICODE} buffer of the given size using MBCS +and returns a Python string object. Returns \NULL{} in case an +exception was raised by the codec. +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyUnicode_AsMBCSString}{PyObject *unicode} + +Encodes a Unicode objects using MBCS and returns the result as Python +string object. Error handling is ``strict''. Returns +\NULL{} in case an exception was raised by the codec. +\end{cfuncdesc} + +% --- Methods & Slots ---------------------------------------------------- + +\subsubsection{Methods & Slot Functions \label{unicodeMethodsAndSlots}} + +The following APIs are capable of handling Unicode objects and strings +on input (we refer to them as strings in the descriptions) and return +Unicode objects or integers as apporpriate. + +They all return \NULL{} or -1 in case an exception occurrs. + +\begin{cfuncdesc}{PyObject*}{PyUnicode_Concat}{PyObject *left, + PyObject *right} + +Concat two strings giving a new Unicode string. +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyUnicode_Split}{PyObject *s, + PyObject *sep, + int maxsplit} + +Split a string giving a list of Unicode strings. + +If sep is NULL, splitting will be done at all whitespace +substrings. Otherwise, splits occur at the given separator. + +At most maxsplit splits will be done. If negative, no limit is set. + +Separators are not included in the resulting list. +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyUnicode_Splitlines}{PyObject *s, + int maxsplit} + +Dito, but split at line breaks. + +CRLF is considered to be one line break. Line breaks are not +included in the resulting list. +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyUnicode_Translate}{PyObject *str, + PyObject *table, + const char *errors} + +Translate a string by applying a character mapping table to it and +return the resulting Unicode object. + +The mapping table must map Unicode ordinal integers to Unicode ordinal +integers or None (causing deletion of the character). + +Mapping tables must only provide the __getitem__ interface, +e.g. dictionaries or sequences. Unmapped character ordinals (ones +which cause a LookupError) are left untouched and are copied as-is. + +\var{errors} has the usual meaning for codecs. It may be \NULL{} +which indicates to use the default error handling. + +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyUnicode_Join}{PyObject *separator, + PyObject *seq} + +Join a sequence of strings using the given separator and return +the resulting Unicode string. +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyUnicode_Tailmatch}{PyObject *str, + PyObject *substr, + int start, + int end, + int direction} + +Return 1 if \var{substr} matches \var{str}[\var{start}:\var{end}] at +the given tail end (\var{direction} == -1 means to do a prefix match, +\var{direction} == 1 a suffix match), 0 otherwise. +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyUnicode_Find}{PyObject *str, + PyObject *substr, + int start, + int end, + int direction} + +Return the first position of \var{substr} in +\var{str}[\var{start}:\var{end}] using the given \var{direction} +(\var{direction} == 1 means to do a forward search, +\var{direction} == -1 a backward search), 0 otherwise. +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyUnicode_Count}{PyObject *str, + PyObject *substr, + int start, + int end} + +Count the number of occurrences of \var{substr} in +\var{str}[\var{start}:\var{end}] +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyUnicode_Replace}{PyObject *str, + PyObject *substr, + PyObject *replstr, + int maxcount} + +Replace at most \var{maxcount} occurrences of \var{substr} in +\var{str} with \var{replstr} and return the resulting Unicode object. +\var{maxcount} == -1 means: replace all occurrences. +\end{cfuncdesc} + +\begin{cfuncdesc}{int}{PyUnicode_Compare}{PyObject *left, + PyObject *right} + +Compare two strings and return -1, 0, 1 for less than, equal, +greater than resp. +\end{cfuncdesc} + +\begin{cfuncdesc}{PyObject*}{PyUnicode_Format}{PyObject *format, + PyObject *args} +Returns a new string object from \var{format} and \var{args}. Analogous +to \code{\var{format} \% \var{args}}. The \var{args} argument must be +a tuple. +\end{cfuncdesc} + +\begin{cfuncdesc}{int}{PyUnicode_Contains}{PyObject *container, + PyObject *element} + +Checks whether \var{element} is contained in \var{container} and +returns 1/0 accordingly. + +\var{element} has to coerce to an one element Unicode string. -1 is +returned in case of an error. +\end{cfuncdesc} + + \subsection{Buffer Objects \label{bufferObjects}} XXX need a real description of buffers and buffer ''segments.`` diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS CVS-Python/Doc/lib/lib.tex Python+Unicode/Doc/lib/lib.tex --- CVS-Python/Doc/lib/lib.tex Wed Mar 1 10:22:28 2000 +++ Python+Unicode/Doc/lib/lib.tex Sat Apr 1 17:13:45 2000 @@ -128,6 +128,7 @@ \input{libcalendar} \input{libcmd} \input{libshlex} +\input{libcodecs} \input{liballos} % Generic Operating System Services \input{libos} diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS CVS-Python/Doc/lib/libcodecs.tex Python+Unicode/Doc/lib/libcodecs.tex --- CVS-Python/Doc/lib/libcodecs.tex Thu Jan 1 01:00:00 1970 +++ Python+Unicode/Doc/lib/libcodecs.tex Sat Apr 1 17:13:45 2000 @@ -0,0 +1,123 @@ +\section{\module{codecs} --- + Python codec registry and base classes.} +\declaremodule{standard}{codec} + +\modulesynopsis{Encode and decode data and streams.} + +\index{Unicode} +\index{Codecs} +\indexii{Codecs}{encode} +\indexii{Codecs}{decode} +\index{streams} +\indexii{stackable}{streams} + + +This module defines base classes for standard Python codecs (encoders +and decoders) and provides access to the internal Python codec +registry which manages the codec lookup process. + +It defines the following functions: + +\begin{funcdesc}{register}{search_function} +Register a codec search function. Search functions are expected to +take one argument, the encoding name in all lower case letters, and +return a tuple of functions \code{(\var{encoder}, \var{decoder}, \var{stream_reader}, +\var{stream_writer})} taking the following arguments: + + \var{encoder} and \var{decoder}: These must be functions or methods + which have the same interface as the .encode/.decode methods of + Codec instances (see Codec Interface). The functions/methods are + expected to work in a stateless mode. + + \var{stream_reader} and \var{stream_writer}: These have to be + factory functions providing the following interface: + + \code{factory(\var{stream},\var{errors}='strict')} + + The factory functions must return objects providing the interfaces + defined by the base classes + \class{StreamWriter}/\class{StreamReader} resp. Stream codecs can + maintain state. + + Possible values for errors are 'strict' (raise an exception in case + of an encoding error), 'replace' (replace malformed data with a + suitable replacement marker, e.g. '?') and 'ignore' (ignore + malformed data and continue without further notice). + +In case a search function cannot find a given encoding, it should +return None. +\end{funcdesc} + +\begin{funcdesc}{lookup}{encoding} +Looks up a codec tuple in the Python codec registry and returns the +function tuple as defined above. + +Encodings are first looked up in the registry's cache. If not found, +the list of registered search functions is scanned. If no codecs tuple +is found, a LookupError is raised. Otherwise, the codecs tuple is +stored in the cache and returned to the caller. +\end{funcdesc} + +To simplify working with encoded files or stream, the module +also defines these utility functions: + +\begin{funcdesc}{open}{filename, mode\optional{, encoding=None, errors='strict', buffering=1}} +Open an encoded file using the given \var{mode} and return +a wrapped version providing transparent encoding/decoding. + +Note: The wrapped version will only accept the object format defined +by the codecs, i.e. Unicode objects for most builtin codecs. Output is +also codec dependent and will usually by Unicode as well. + +\var{encoding} specifies the encoding which is to be used for the +the file. + +\var{errors} may be given to define the error handling. It defaults +to 'strict' which causes a \exception{ValueError} to be raised in case +an encoding error occurs. + +\var{buffering} has the same meaning as for the builtin open() API. +It defaults to line buffered. +\end{funcdesc} + +\begin{funcdesc}{EncodedFile}{file, input\optional{, output=None, errors='strict'}} + +Return a wrapped version of file which provides transparent +encoding translation. + +Strings written to the wrapped file are interpreted according to the +given \var{input} encoding and then written to the original file as +string using the \var{output} encoding. The intermediate encoding will +usually be Unicode but depends on the specified codecs. + +If \var{output} is not given, it defaults to input. + +\var{errors} may be given to define the error handling. It defaults to +'strict' which causes a \exception{ValueError} to be raised in case +an encoding error occurs. +\end{funcdesc} + + + +...XXX document codec base classes... + + + +The module also provides the following constants which are useful +for reading and writing to platform dependent files: + +\begin{datadesc}{BOM*} +\dataline{BOM} +\dataline{BOM_BE} +\dataline{BOM_LE} +\dataline{BOM32_BE} +\dataline{BOM32_LE} +\dataline{BOM64_BE} +\dataline{BOM64_LE} +These constants define the byte order marks (BOM) used in data +streams to indicate the byte order used in the stream or file. +\var{BOM} is set to either BOM_BE or BOM_LE depending on the platform's +native byte order, while the others represent big endian (_BE) and +little endian (_LE) byte order using 32-bit and 64-bit encodings. +\end{datadesc} + diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS CVS-Python/Doc/lib/libexcs.tex Python+Unicode/Doc/lib/libexcs.tex --- CVS-Python/Doc/lib/libexcs.tex Fri Dec 3 13:09:30 1999 +++ Python+Unicode/Doc/lib/libexcs.tex Sat Apr 1 17:13:45 2000 @@ -310,6 +310,11 @@ details about the type mismatch. \end{excdesc} +\begin{excdesc}{UnicodeError} + Raised when a Unicode related encoding/decoding error occurs. It is + a subclass of \exception{ValueError}. +\end{excdesc} + \begin{excdesc}{ValueError} Raised when a built-in operation or function receives an argument that has the right type but an inappropriate value, and the diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS CVS-Python/Doc/lib/libfuncs.tex Python+Unicode/Doc/lib/libfuncs.tex --- CVS-Python/Doc/lib/libfuncs.tex Wed Mar 1 10:22:28 2000 +++ Python+Unicode/Doc/lib/libfuncs.tex Sat Apr 1 17:13:45 2000 @@ -466,9 +466,11 @@ \end{funcdesc} \begin{funcdesc}{ord}{c} - Return the \ASCII{} value of a string of one character. E.g., - \code{ord('a')} returns the integer \code{97}. This is the inverse of - \function{chr()}. + Return the \ASCII{} value of a string of one character or a Unicode + character. E.g., \code{ord('a')} returns the integer \code{97}, + \code{ord(u'\\u2020')} returns \code{8224}. This is the inverse of + \function{chr()} for strings and of \function{unichr()} for Unicode + characters. \end{funcdesc} \begin{funcdesc}{pow}{x, y\optional{, z}} @@ -658,6 +660,21 @@ >>> import types >>> if type(x) == types.StringType: print "It's a string" \end{verbatim} +\end{funcdesc} + +\begin{funcdesc}{unichr}{i} + Return the Unicode string of one character whose Unicode code is the + integer \var{i}, e.g., \code{unichr(97)} returns the string + \code{u'a'}. This is the inverse of \function{ord()} for Unicode + strings. The argument must be in the range [0..65535], inclusive. + A \exception{ValueError} is raised otherwise. +\end{funcdesc} + +\begin{funcdesc}{unicode}{string\optional{,encoding='utf-8'}\optional{,errors='strict'}} +Decodes \var{string} using the codec found for \var{encoding}. Error +handling is done according to \var{errors}. Default is to decode UTF-8 +in strict mode, meaning that encoding errors raise a +\exception{ValueError}. \end{funcdesc} \begin{funcdesc}{vars}{\optional{object}} diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS CVS-Python/Doc/lib/libmarshal.tex Python+Unicode/Doc/lib/libmarshal.tex --- CVS-Python/Doc/lib/libmarshal.tex Mon Apr 26 21:02:36 1999 +++ Python+Unicode/Doc/lib/libmarshal.tex Sat Apr 1 17:13:45 2000 @@ -32,11 +32,11 @@ whose value is independent from a particular invocation of Python can be written and read by this module. The following types are supported: \code{None}, integers, long integers, floating point numbers, -strings, tuples, lists, dictionaries, and code objects, where it -should be understood that tuples, lists and dictionaries are only -supported as long as the values contained therein are themselves -supported; and recursive lists and dictionaries should not be written -(they will cause infinite loops). +strings, Unicode objects, tuples, lists, dictionaries, and code +objects, where it should be understood that tuples, lists and +dictionaries are only supported as long as the values contained +therein are themselves supported; and recursive lists and dictionaries +should not be written (they will cause infinite loops). \strong{Caveat:} On machines where C's \code{long int} type has more than 32 bits (such as the DEC Alpha), it diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS CVS-Python/Doc/lib/libpickle.tex Python+Unicode/Doc/lib/libpickle.tex --- CVS-Python/Doc/lib/libpickle.tex Tue Jul 27 14:12:21 1999 +++ Python+Unicode/Doc/lib/libpickle.tex Sat Apr 1 17:13:45 2000 @@ -199,7 +199,7 @@ \item integers, long integers, floating point numbers -\item strings +\item normal and Unicode strings \item tuples, lists and dictionaries containing only picklable objects diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS CVS-Python/Doc/lib/libtypes.tex Python+Unicode/Doc/lib/libtypes.tex --- CVS-Python/Doc/lib/libtypes.tex Mon Dec 21 23:24:12 1998 +++ Python+Unicode/Doc/lib/libtypes.tex Sat Apr 1 17:13:45 2000 @@ -56,6 +56,10 @@ The type of character strings (e.g. \code{'Spam'}). \end{datadesc} +\begin{datadesc}{UnicodeType} +The type of Unicode character strings (e.g. \code{u'Spam'}). +\end{datadesc} + \begin{datadesc}{TupleType} The type of tuples (e.g. \code{(1, 2, 3, 'Spam')}). \end{datadesc} diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS CVS-Python/Doc/ref/ref3.tex Python+Unicode/Doc/ref/ref3.tex --- CVS-Python/Doc/ref/ref3.tex Fri Dec 3 13:09:39 1999 +++ Python+Unicode/Doc/ref/ref3.tex Sat Apr 1 18:45:21 2000 @@ -278,6 +278,21 @@ \bifuncindex{chr} \bifuncindex{ord} +\item[Unicode] +The items of a Unicode object are Unicode characters. A Unicode +character is represented by a Unicode object of one item and can hold +a 16-bit value representing a Unicode ordinal. The built-in functions +\function{unichr()}\bifuncindex{unichr} and +\function{ord()}\bifuncindex{ord} convert between characters and +nonnegative integers representing the Unicode ordinals as defined in +the Unicode Standard 3.0. Conversion from and to other encodings are +possible through the Unicode method \method{encode} and the built-in +function \function{unicode()}\bifuncindex{unicode}. +\obindex{unicode} +\index{character} +\index{integer} +\index{Unicode@\UNICODE{}} + \item[Tuples] The items of a tuple are arbitrary Python objects. Tuples of two or more items are formed by comma-separated lists diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS CVS-Python/Doc/texinputs/python.sty Python+Unicode/Doc/texinputs/python.sty --- CVS-Python/Doc/texinputs/python.sty Fri Dec 3 13:09:39 1999 +++ Python+Unicode/Doc/texinputs/python.sty Sat Apr 1 17:13:45 2000 @@ -660,6 +660,7 @@ \newcommand{\UNIX}{{\sc Unix}} \newcommand{\POSIX}{POSIX} \newcommand{\ASCII}{{\sc ascii}} +\newcommand{\UNICODE}{{\sc unicode}} \newcommand{\Cpp}{C\protect\raisebox{.18ex}{++}} \newcommand{\C}{C} \newcommand{\EOF}{{\sc eof}} diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS CVS-Python/Doc/tut/tut.tex Python+Unicode/Doc/tut/tut.tex --- CVS-Python/Doc/tut/tut.tex Fri Dec 3 13:09:39 1999 +++ Python+Unicode/Doc/tut/tut.tex Sat Apr 1 17:13:46 2000 @@ -699,6 +699,104 @@ 34 \end{verbatim} +\subsection{Unicode Strings \label{unicodeStrings}} + +Starting with Python 1.6 a new data type for storing text data is +available to the programmer: the Unicode object. It can be used to +store and manipulate Unicode data (see ) and +intergrates well with the existing string objects providing +auto-conversions where necessary. + +Unicode has the advantage of providing one ordinal for every character +in every script used in modern and ancient texts. Previously, there +were only 256 possible ordinals for script characters and texts were +typically bound to a code page which mapped the ordinals to script +characters. This lead to very much confusion especially with respect +to internalization (usually written as 'i18n' -- 'i' + 18 characters + +'n') of software. Unicode solves these problems by defining one code +page for all scripts. + +Creating Unicode strings in Python is just as simple as creating +normal strings: + +\begin{verbatim} +>>> u'Hello World !' +u'Hello World !' +\end{verbatim} + +The small 'u' in front of the quote indicates that an Unicode string +is supposed to be created. If you want to include special characters +in the string, you can do so by using the Python \emph{Unicode-Escape} +encoding. The following example shows how: + +\begin{verbatim} +>>> u'Hello\\u0020World !' +u'Hello World !' +\end{verbatim} + +The escape sequence \code{\\u0020} indicates to insert the Unicode +character with the HEX ordinal 0x0020 (the space character) at the +given position. + +Other characters are interpreted by using their respective ordinal +value directly as Unicode ordinal. Due to the fact that the lower 256 +Unicode are the same as the standard Latin-1 encoding used in many +western countries, the process of entering Unicode is greatly +simplified. + +For experts, there is also a raw mode just like for normal +strings. You have to prepend the string with a small 'r' to have +Python use the \emph{Raw-Unicode-Escape} encoding. It will only apply +the above \code{\\uXXXX} conversion if there is an uneven number of +backslashes in front of the small 'u'. + +\begin{verbatim} +>>> ur'Hello\u0020World !' +u'Hello World !' +>>> ur'Hello\\u0020World !' +u'Hello\\\\u0020World !' +\end{verbatim} + +The raw mode is most useful when you have to enter lots of backslashes +e.g. in regular expressions. + +Apart from these standard encodings, Python provides a whole set of +other ways of creating Unicod strings on the basis of a known +encoding. + +The builtin \code{unicode()} provides access to all registered Unicode +codecs (COders and DECoders). Some of the more well known encodings +which these codecs can convert are +\emph{Latin-1}, \emph{ASCII}, \emph{UTF-8} and \emph{UTF-16}. The latter two +are variable length encodings which permit to store Unicode characters +in 8 or 16 bits. Python uses UTF-8 as default encoding. This becomes +noticable when printing Unicode strings or writing them to files. + +\begin{verbatim} +>>> u"äöü" +u'\344\366\374' +>>> str(u"äöü") +'\303\244\303\266\303\274' +\end{verbatim} + +If you have data in a specific encoding and want to produce a +corresponding Unicode string from it, you can use the \code{unicode()} +builtin with the encoding name as second argument. + +\begin{verbatim} +>>> unicode('\303\244\303\266\303\274','UTF-8') +u'\344\366\374' +\end{verbatim} + +To convert the Unicode string back into a string using the original +encoding, the objects provide an \code{.encode()} method. + +\begin{verbatim} +>>> u"äöü".encode('UTF-8') +'\303\244\303\266\303\274' +\end{verbatim} + + \subsection{Lists \label{lists}} Python knows a number of \emph{compound} data types, used to group --------------AC5A3AFAAB32FC257EC8E73D-- From pf@artcom-gmbh.de Sun Apr 2 23:58:04 2000 From: pf@artcom-gmbh.de (Peter Funk) Date: Mon, 3 Apr 2000 00:58:04 +0200 (MEST) Subject: [Patches] New lib module: UserString.py and testcase for it Message-ID: Dear Python patcher! Please add the files appended below and commit them into the CVS tree. (Note: the patch submission guide lines are not very clear about the mail format for a suite of new module files. I've used good old 'shar'. Please tell me if I should submit a context diff against null or a set of mime attachments instead.) --=-- argument: --=--=--=--=--=--=--=--=--=--=-->8--=- In Python 1.6 string objects have grown a bunch of methods. Users may wish to override particular methods in self defined classes. UserString wraps builtin string objects into a wrapper class similar to UserDict and UserList. UserString object instances are still immutable. For educational purposes a class `MutableString' derived from `UserString' is also provided. --=-- obligatory disclaimer: -=--=--=--=--=--=-->8--=- I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. --=-- dry signature: =--=--=--=--=--=--=--=--=-->8--=- note: In order to fullfil the formal requirements I have submitted the wet signature form per postal mail. This should arrive at your site in a week or so (I've applied air mail postage). Regards, Peter -- Peter Funk, Oldenburger Str.86, D-27777 Ganderkesee, Germany, Fax:+49 4222950260 office: +49 421 20419-0 (ArtCom GmbH, Grazer Str.8, D-28359 Bremen) --=-- shar file: --=--=--=--=--=--=--=--=--=--=--=-->8--=- #!/bin/sh # This is a shell archive (produced by GNU sharutils 4.2c). # To extract the files from this archive, save it to some FILE, remove # everything before the `!/bin/sh' line above, then type `sh FILE'. # # Made on 2000-04-03 00:53 MEST by . # Source directory was `/home/pf/archiv/freeware/python/CVS_01_04_00/dist'. # # Existing files will *not* be overwritten unless `-c' is specified. # # This shar contains: # length mode name # ------ ---------- ------------------------------------------ # 7077 -rwxrwxr-x src/Lib/UserString.py # 6599 -rwxrwxr-x src/Lib/test/test_userstring.py # 16 -rw-rw---- src/Lib/test/output/test_userstring # save_IFS="${IFS}" IFS="${IFS}:" gettext_dir=FAILED locale_dir=FAILED first_param="$1" for dir in $PATH do if test "$gettext_dir" = FAILED && test -f $dir/gettext \ && ($dir/gettext --version >/dev/null 2>&1) then set `$dir/gettext --version 2>&1` if test "$3" = GNU then gettext_dir=$dir fi fi if test "$locale_dir" = FAILED && test -f $dir/shar \ && ($dir/shar --print-text-domain-dir >/dev/null 2>&1) then locale_dir=`$dir/shar --print-text-domain-dir` fi done IFS="$save_IFS" if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED then echo=echo else TEXTDOMAINDIR=$locale_dir export TEXTDOMAINDIR TEXTDOMAIN=sharutils export TEXTDOMAIN echo="$gettext_dir/gettext -s" fi if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then shar_n= shar_c=' ' else shar_n=-n shar_c= fi else shar_n= shar_c='\c' fi touch -am 1231235999 $$.touch >/dev/null 2>&1 if test ! -f 1231235999 && test -f $$.touch; then shar_touch=touch else shar_touch=: echo $echo 'WARNING: not restoring timestamps. Consider getting and' $echo "installing GNU \`touch', distributed in GNU File Utilities..." echo fi rm -f 1231235999 $$.touch # $echo $shar_n 'x -' 'lock directory' "\`_sh29194': "$shar_c if mkdir _sh29194; then $echo 'created' else $echo 'failed to create' exit 1 fi # ============= src/Lib/UserString.py ============== if test ! -d 'src'; then $echo $echo_n 'x -' 'src: '$echo_c if mkdir 'src'; then $echo 'created'; else $echo 'failed to create'; fi fi if test ! -d 'src/Lib'; then $echo $echo_n 'x -' 'src/Lib: '$echo_c if mkdir 'src/Lib'; then $echo 'created'; else $echo 'failed to create'; fi fi if test -f 'src/Lib/UserString.py' && test "$first_param" != -c; then $echo 'x -' SKIPPING 'src/Lib/UserString.py' '(file already exists)' else $echo 'x -' extracting 'src/Lib/UserString.py' '(text)' sed 's/^X//' << 'SHAR_EOF' > 'src/Lib/UserString.py' && #!/usr/bin/env python ## vim:ts=4:et:nowrap """A user-defined wrapper around string objects X Note: string objects have grown methods in Python 1.6 This module requires Python 1.6 or later. """ from types import StringType, UnicodeType import sys X class UserString: X def __init__(self, seq): X if isinstance(seq, StringType) or isinstance(seq, UnicodeType): X self.data = seq X elif isinstance(seq, UserString): X self.data = seq.data[:] X else: X self.data = str(seq) X def __str__(self): return str(self.data) X def __repr__(self): return repr(self.data) X def __int__(self): return int(self.data) X def __long__(self): return long(self.data) X def __float__(self): return float(self.data) X def __complex__(self): return complex(self.data) X def __hash__(self): return hash(self.data) X X def __cmp__(self, string): X if isinstance(string, UserString): X return cmp(self.data, string.data) X else: X return cmp(self.data, string) X def __contains__(self, char): X return char in self.data X X def __len__(self): return len(self.data) X def __getitem__(self, index): return self.__class__(self.data[index]) X def __getslice__(self, start, end): X start = max(start, 0); end = max(end, 0) X return self.__class__(self.data[start:end]) X X def __add__(self, other): X if isinstance(other, UserString): X return self.__class__(self.data + other.data) X elif isinstance(other, StringType) or isinstance(other, UnicodeType): X return self.__class__(self.data + other) X else: X return self.__class__(self.data + str(other)) X def __radd__(self, other): X if isinstance(other, StringType) or isinstance(other, UnicodeType): X return self.__class__(other + self.data) X else: X return self.__class__(str(other) + self.data) X def __mul__(self, n): X return self.__class__(self.data*n) X __rmul__ = __mul__ X X # the following methods are defined in alphabetical order: X def capitalize(self): return self.__class__(self.data.capitalize()) X def center(self, width): return self.__class__(self.data.center(width)) X def count(self, sub, start=0, end=sys.maxint): X return self.data.count(sub, start, end) X def encode(self, encoding=None, errors=None): # XXX improve this? X if encoding: X if errors: X return self.__class__(self.data.encode(encoding, errors)) X else: X return self.__class__(self.data.encode(encoding)) X else: X return self.__class__(self.data.encode()) X def endswith(self, suffix, start=0, end=sys.maxint): X return self.data.endswith(suffix, start, end) X def expandtabs(self, tabsize=8): X return self.__class__(self.data.expandtabs(tabsize)) X def find(self, sub, start=0, end=sys.maxint): X return self.data.find(sub, start, end) X def index(self, sub, start=0, end=sys.maxint): X return self.data.index(sub, start, end) X def isdecimal(self): return self.data.isdecimal() X def isdigit(self): return self.data.isdigit() X def islower(self): return self.data.islower() X def isnumeric(self): return self.data.isnumeric() X def isspace(self): return self.data.isspace() X def istitle(self): return self.data.istitle() X def isupper(self): return self.data.isupper() X def join(self, seq): return self.data.join(seq) X def ljust(self, width): return self.__class__(self.data.ljust(width)) X def lower(self): return self.__class__(self.data.lower()) X def lstrip(self): return self.__class__(self.data.lstrip()) X def replace(self, old, new, maxsplit=-1): X return self.__class__(self.data.replace(old, new, maxsplit)) X def rfind(self, sub, start=0, end=sys.maxint): X return self.data.rfind(sub, start, end) X def rindex(self, sub, start=0, end=sys.maxint): X return self.data.rindex(sub, start, end) X def rjust(self, width): return self.__class__(self.data.rjust(width)) X def rstrip(self): return self.__class__(self.data.rstrip()) X def split(self, sep=None, maxsplit=-1): X return self.data.split(sep, maxsplit) X def splitlines(self, maxsplit=-1): return self.data.splitlines(maxsplit) X def startswith(self, prefix, start=0, end=sys.maxint): X return self.data.startswith(prefix, start, end) X def strip(self): return self.__class__(self.data.strip()) X def swapcase(self): return self.__class__(self.data.swapcase()) X def title(self): return self.__class__(self.data.title()) X def translate(self, table, deletechars=""): X return self.__class__(self.data.translate(table, deletechars)) X def upper(self): return self.__class__(self.data.upper()) X class MutableString(UserString): X """mutable string objects X X Python strings are immutable objects. This has the advantage, that X strings may be used as dictionary keys. If this property isn't needed X and you insist on changing string values in place instead, you may cheat X and use MutableString. X X But the purpose of this class is an educational one: to prevent X people from inventing their own mutable string class derived X from UserString and than forget thereby to remove (override) the X __hash__ method inherited from ^UserString. This would lead to X errors that would be very hard to track down. X X A faster and better solution is to rewrite your program using lists.""" X def __init__(self, string=""): X self.data = string X def __hash__(self): X raise TypeError, "unhashable type (it is mutable)" X def __setitem__(self, index, sub): X if index < 0 or index >= len(self.data): raise IndexError X self.data = self.data[:index] + sub + self.data[index+1:] X def __delitem__(self, index): X if index < 0 or index >= len(self.data): raise IndexError X self.data = self.data[:index] + self.data[index+1:] X def __setslice__(self, start, end, sub): X start = max(start, 0); end = max(end, 0) X if isinstance(sub, UserString): X self.data = self.data[:start]+sub.data+self.data[end:] X elif isinstance(sub, StringType) or isinstance(sub, UnicodeType): X self.data = self.data[:start]+sub+self.data[end:] X else: X self.data = self.data[:start]+str(sub)+self.data[end:] X def __delslice__(self, start, end): X start = max(start, 0); end = max(end, 0) X self.data = self.data[:start] + self.data[end:] X def immutable(self): X return UserString(self.data) X if __name__ == "__main__": X # execute the regression test to stdout, if called as a script: X import os X called_in_dir, called_as = os.path.split(sys.argv[0]) X called_in_dir = os.path.abspath(called_in_dir) X called_as, py = os.path.splitext(called_as) X sys.path.append(os.path.join(called_in_dir, 'test')) X if '-q' in sys.argv: X import test_support X test_support.verbose = 0 X __import__('test_' + called_as.lower()) SHAR_EOF $shar_touch -am 04030006100 'src/Lib/UserString.py' && chmod 0775 'src/Lib/UserString.py' || $echo 'restore of' 'src/Lib/UserString.py' 'failed' if ( md5sum --help &1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ && ( md5sum --version &1 | grep -v 'textutils 1.12' ) >/dev/null; then md5sum -c << SHAR_EOF >/dev/null 2>&1 \ || $echo 'src/Lib/UserString.py:' 'MD5 check failed' 16ba5d7ab3cefa6d75d8fe270e05957a src/Lib/UserString.py SHAR_EOF else shar_count="`LC_ALL=C wc -c < 'src/Lib/UserString.py'`" test 7077 -eq "$shar_count" || $echo 'src/Lib/UserString.py:' 'original size' '7077,' 'current size' "$shar_count!" fi fi # ============= src/Lib/test/test_userstring.py ============== if test ! -d 'src/Lib/test'; then $echo $echo_n 'x -' 'src/Lib/test: '$echo_c if mkdir 'src/Lib/test'; then $echo 'created'; else $echo 'failed to create'; fi fi if test -f 'src/Lib/test/test_userstring.py' && test "$first_param" != -c; then $echo 'x -' SKIPPING 'src/Lib/test/test_userstring.py' '(file already exists)' else $echo 'x -' extracting 'src/Lib/test/test_userstring.py' '(text)' sed 's/^X//' << 'SHAR_EOF' > 'src/Lib/test/test_userstring.py' && #!/usr/bin/env python import sys, string from test_support import verbose # UserString is a wrapper around the native builtin string type. # UserString instances should behave similar to builtin string objects. # The test cases were in part derived from 'test_string.py'. from UserString import UserString X if __name__ == "__main__": X verbose = 0 X tested_methods = {} X def test(methodname, input, *args): X global tested_methods X tested_methods[methodname] = 1 X if verbose: X print '%s.%s(%s) ' % (input, methodname, args), X u = UserString(input) X objects = [input, u, UserString(u)] X res = [""] * 3 X for i in range(3): X object = objects[i] X try: X f = getattr(object, methodname) X res[i] = apply(f, args) X except: X res[i] = sys.exc_type X if res[0] != res[1]: X if verbose: X print 'no' X print `input`, f, `res[0]`, "<>", `res[1]` X else: X if verbose: X print 'yes' X if res[1] != res[2]: X if verbose: X print 'no' X print `input`, f, `res[1]`, "<>", `res[2]` X else: X if verbose: X print 'yes' X test('capitalize', ' hello ') test('capitalize', 'hello ') X test('center', 'foo', 0) test('center', 'foo', 3) test('center', 'foo', 16) X test('ljust', 'foo', 0) test('ljust', 'foo', 3) test('ljust', 'foo', 16) X test('rjust', 'foo', 0) test('rjust', 'foo', 3) test('rjust', 'foo', 16) X test('count', 'abcabcabc', 'abc') test('count', 'abcabcabc', 'abc', 1) test('count', 'abcabcabc', 'abc', -1) test('count', 'abcabcabc', 'abc', 7) test('count', 'abcabcabc', 'abc', 0, 3) test('count', 'abcabcabc', 'abc', 0, 333) X test('find', 'abcdefghiabc', 'abc') test('find', 'abcdefghiabc', 'abc', 1) test('find', 'abcdefghiabc', 'def', 4) test('rfind', 'abcdefghiabc', 'abc') X test('index', 'abcabcabc', 'abc') test('index', 'abcabcabc', 'abc', 1) test('index', 'abcabcabc', 'abc', -1) test('index', 'abcabcabc', 'abc', 7) test('index', 'abcabcabc', 'abc', 0, 3) test('index', 'abcabcabc', 'abc', 0, 333) X test('rindex', 'abcabcabc', 'abc') test('rindex', 'abcabcabc', 'abc', 1) test('rindex', 'abcabcabc', 'abc', -1) test('rindex', 'abcabcabc', 'abc', 7) test('rindex', 'abcabcabc', 'abc', 0, 3) test('rindex', 'abcabcabc', 'abc', 0, 333) X X test('lower', 'HeLLo') test('lower', 'hello') test('upper', 'HeLLo') test('upper', 'HELLO') X test('title', ' hello ') test('title', 'hello ') test('title', "fOrMaT thIs aS titLe String") test('title', "fOrMaT,thIs-aS*titLe;String") test('title', "getInt") X test('expandtabs', 'abc\rab\tdef\ng\thi') test('expandtabs', 'abc\rab\tdef\ng\thi', 8) test('expandtabs', 'abc\rab\tdef\ng\thi', 4) test('expandtabs', 'abc\r\nab\tdef\ng\thi', 4) X test('islower', 'a') test('islower', 'A') test('islower', '\n') test('islower', 'abc') test('islower', 'aBc') test('islower', 'abc\n') X test('isupper', 'a') test('isupper', 'A') test('isupper', '\n') test('isupper', 'ABC') test('isupper', 'AbC') test('isupper', 'ABC\n') X test('isdigit', ' 0123456789') test('isdigit', '56789') test('isdigit', '567.89') test('isdigit', '0123456789abc') X test('isspace', '') test('isspace', ' ') test('isspace', ' \t') test('isspace', ' \t\f\n') X test('istitle', 'a') test('istitle', 'A') test('istitle', '\n') test('istitle', 'A Titlecased Line') test('istitle', 'A\nTitlecased Line') test('istitle', 'A Titlecased, Line') test('istitle', 'Not a capitalized String') test('istitle', 'Not\ta Titlecase String') test('istitle', 'Not--a Titlecase String') X test('splitlines', "abc\ndef\n\rghi") test('splitlines', "abc\ndef\n\r\nghi") test('splitlines', "abc\ndef\r\nghi") test('splitlines', "abc\ndef\r\nghi\n") test('splitlines', "abc\ndef\r\nghi\n\r") test('splitlines', "\nabc\ndef\r\nghi\n\r") test('splitlines', "\nabc\ndef\r\nghi\n\r") test('splitlines', "\nabc\ndef\r\nghi\n\r") X test('split', 'this is the split function') test('split', 'a|b|c|d', '|') test('split', 'a|b|c|d', '|', 2) test('split', 'a b c d', None, 1) test('split', 'a b c d', None, 2) test('split', 'a b c d', None, 3) test('split', 'a b c d', None, 4) test('split', 'a b c d', None, 0) test('split', 'a b c d', None, 2) test('split', 'a b c d ') X # join now works with any sequence type class Sequence: X def __init__(self): self.seq = 'wxyz' X def __len__(self): return len(self.seq) X def __getitem__(self, i): return self.seq[i] X test('join', '', ('a', 'b', 'c', 'd')) test('join', '', Sequence()) test('join', '', 7) X class BadSeq(Sequence): X def __init__(self): self.seq = [7, 'hello', 123L] X test('join', '', BadSeq()) X test('strip', ' hello ') test('lstrip', ' hello ') test('rstrip', ' hello ') test('strip', 'hello') X test('swapcase', 'HeLLo cOmpUteRs') transtable = string.maketrans("abc", "xyz") test('translate', 'xyzabcdef', transtable, 'def') X transtable = string.maketrans('a', 'A') test('translate', 'abc', transtable) test('translate', 'xyz', transtable) X test('replace', 'one!two!three!', '!', '@', 1) test('replace', 'one!two!three!', '!', '') test('replace', 'one!two!three!', '!', '@', 2) test('replace', 'one!two!three!', '!', '@', 3) test('replace', 'one!two!three!', '!', '@', 4) test('replace', 'one!two!three!', '!', '@', 0) test('replace', 'one!two!three!', '!', '@') test('replace', 'one!two!three!', 'x', '@') test('replace', 'one!two!three!', 'x', '@', 2) X test('startswith', 'hello', 'he') test('startswith', 'hello', 'hello') test('startswith', 'hello', 'hello world') test('startswith', 'hello', '') test('startswith', 'hello', 'ello') test('startswith', 'hello', 'ello', 1) test('startswith', 'hello', 'o', 4) test('startswith', 'hello', 'o', 5) test('startswith', 'hello', '', 5) test('startswith', 'hello', 'lo', 6) test('startswith', 'helloworld', 'lowo', 3) test('startswith', 'helloworld', 'lowo', 3, 7) test('startswith', 'helloworld', 'lowo', 3, 6) X test('endswith', 'hello', 'lo') test('endswith', 'hello', 'he') test('endswith', 'hello', '') test('endswith', 'hello', 'hello world') test('endswith', 'helloworld', 'worl') test('endswith', 'helloworld', 'worl', 3, 9) test('endswith', 'helloworld', 'world', 3, 12) test('endswith', 'helloworld', 'lowo', 1, 7) test('endswith', 'helloworld', 'lowo', 2, 7) test('endswith', 'helloworld', 'lowo', 3, 7) test('endswith', 'helloworld', 'lowo', 4, 7) test('endswith', 'helloworld', 'lowo', 3, 8) test('endswith', 'ab', 'ab', 0, 1) test('endswith', 'ab', 'ab', 0, 0) X # TODO: test cases for: int, long, float, complex, +, * and cmp s = "" for builtin_method in dir(s): X if not tested_methods.has_key(builtin_method): X print "no regression test case for method '"+builtin_method+"'" X SHAR_EOF $shar_touch -am 04030025100 'src/Lib/test/test_userstring.py' && chmod 0775 'src/Lib/test/test_userstring.py' || $echo 'restore of' 'src/Lib/test/test_userstring.py' 'failed' if ( md5sum --help &1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ && ( md5sum --version &1 | grep -v 'textutils 1.12' ) >/dev/null; then md5sum -c << SHAR_EOF >/dev/null 2>&1 \ || $echo 'src/Lib/test/test_userstring.py:' 'MD5 check failed' bbbdf7e85913aa80e38e2469991b3cac src/Lib/test/test_userstring.py SHAR_EOF else shar_count="`LC_ALL=C wc -c < 'src/Lib/test/test_userstring.py'`" test 6599 -eq "$shar_count" || $echo 'src/Lib/test/test_userstring.py:' 'original size' '6599,' 'current size' "$shar_count!" fi fi # ============= src/Lib/test/output/test_userstring ============== if test ! -d 'src/Lib/test/output'; then $echo $echo_n 'x -' 'src/Lib/test/output: '$echo_c if mkdir 'src/Lib/test/output'; then $echo 'created'; else $echo 'failed to create'; fi fi if test -f 'src/Lib/test/output/test_userstring' && test "$first_param" != -c; then $echo 'x -' SKIPPING 'src/Lib/test/output/test_userstring' '(file already exists)' else $echo 'x -' extracting 'src/Lib/test/output/test_userstring' '(text)' sed 's/^X//' << 'SHAR_EOF' > 'src/Lib/test/output/test_userstring' && test_userstring SHAR_EOF $shar_touch -am 04030030100 'src/Lib/test/output/test_userstring' && chmod 0660 'src/Lib/test/output/test_userstring' || $echo 'restore of' 'src/Lib/test/output/test_userstring' 'failed' if ( md5sum --help &1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ && ( md5sum --version &1 | grep -v 'textutils 1.12' ) >/dev/null; then md5sum -c << SHAR_EOF >/dev/null 2>&1 \ || $echo 'src/Lib/test/output/test_userstring:' 'MD5 check failed' 8a16c32581de42c338366cb9f7488e4c src/Lib/test/output/test_userstring SHAR_EOF else shar_count="`LC_ALL=C wc -c < 'src/Lib/test/output/test_userstring'`" test 16 -eq "$shar_count" || $echo 'src/Lib/test/output/test_userstring:' 'original size' '16,' 'current size' "$shar_count!" fi fi $echo $shar_n 'x -' 'lock directory' "\`_sh29194': " $shar_c if rm -fr _sh29194; then $echo 'removed' else $echo 'failed to remove' fi exit 0 From fdrake@acm.org Mon Apr 3 04:55:15 2000 From: fdrake@acm.org (Fred L. Drake, Jr.) Date: Sun, 2 Apr 2000 23:55:15 -0400 (EDT) Subject: [Patches] New lib module: UserString.py and testcase for it In-Reply-To: References: Message-ID: <14568.5667.841020.109795@seahag.cnri.reston.va.us> Peter Funk writes: > Please add the files appended below and commit them into the CVS tree. > (Note: the patch submission guide lines are not very clear about the > mail format for a suite of new module files. I've used good old 'shar'. > Please tell me if I should submit a context diff against null or a > set of mime attachments instead.) Peter, It's in, but I think there's a problem with the anonCVS getting updated from my checkins. I'll look further into that tomorrow. ;( Attachments are better for me, but can deal with shar as well. Just hope I never have to use a non-Unix box for development! ;) Thanks! -Fred -- Fred L. Drake, Jr. Corporation for National Research Initiatives From helsten@inconnect.com Mon Apr 3 07:15:28 2000 From: helsten@inconnect.com (Lance Finn Helsten) Date: Mon, 3 Apr 2000 00:15:28 -0600 Subject: [Patches] netrc module parse bug Message-ID: <200004030615.AAA15438@helsten.dsl.inconnect.com> CourierWhen a .netrc file has = passwords that contain non-alphanumeric characters the netrc.__init__ = throws an exception. To change this in the .netrc would pose security = risks. Changes: 1) Added all 7-bit characters to the wordchars field. 2) Turned off quotes. 3) Turn '#' off and on as a comment character around the top level = get_token, so it is usable in passwords. This assumes that all comments start in column 0. End of line comments = will probably not work. *** netrc.py Fri Feb 4 08:10:33 2000 --- /usr/local/lib/python1.5/netrc.py Sun Apr 2 23:46:31 2000 *************** *** 15,24 **** self.hosts =3D {} self.macros =3D {} lexer =3D shlex.shlex(fp) ! lexer.wordchars =3D lexer.wordchars + '.' while 1: # Look for a machine, default, or macdef top-level keyword toplevel =3D tt =3D lexer.get_token() if tt =3D=3D '' or tt =3D=3D None: break elif tt =3D=3D 'machine': --- 13,25 ---- self.hosts =3D {} self.macros =3D {} lexer =3D shlex.shlex(fp) ! lexer.wordchars =3D lexer.wordchars + = '~!@#$%^&*()-=3D+`[]{}\\|;:,./<<>?\'"' ! lexer.quotes =3D '' while 1: # Look for a machine, default, or macdef top-level keyword + lexer.commenters =3D '#' toplevel =3D tt =3D lexer.get_token() + lexer.commenters =3D '' if tt =3D=3D '' or tt =3D=3D None: break elif tt =3D=3D 'machine': *************** I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. Lance Finn Helsten helsten@inconnect.com helsten@ieee.org helsten@acm.org You cannot free a slave save he do it himself. You cannot enslave a = freeman, the most you can do is kill him. ~Robert A. Heinlien= From m.favas@per.dem.csiro.au Mon Apr 3 08:14:36 2000 From: m.favas@per.dem.csiro.au (Mark Favas) Date: Mon, 03 Apr 2000 15:14:36 +0800 Subject: [Patches] Patches for bug report 258 - mmapmodule.c compile problem Message-ID: <38E844DC.75391280@per.dem.csiro.au> The following pathces fix the compile error and warnings for the CVS version of mmapmodule.c of April 3 on Tru64 Unix 4.0F with the Compaq C compiler. I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. Mark -- Email - m.favas@per.dem.csiro.au Postal - Mark C Favas Phone - +61 8 9333 6268, 041 892 6074 CSIRO Exploration & Mining Fax - +61 8 9333 6121 Private Bag No 5 Wembley, Western Australia 6913 *** mmapmodule.c.orig Mon Apr 3 10:23:19 2000 --- mmapmodule.c Mon Apr 3 14:57:23 2000 *************** *** 118,124 **** char value; char * where = (self->data+self->pos); CHECK_VALID(NULL); ! if ((where >= 0) && (where < (self->data+self->size))) { value = (char) *(where); self->pos += 1; return Py_BuildValue("c", (char) *(where)); --- 118,124 ---- char value; char * where = (self->data+self->pos); CHECK_VALID(NULL); ! if ((where >= (char *) 0) && (where < (self->data+self->size))) { value = (char) *(where); self->pos += 1; return Py_BuildValue("c", (char) *(where)); *************** *** 617,623 **** "mmap slice assignment is wrong size"); return -1; } ! buf = PyString_AsString(v); memcpy(self->data + ilow, buf, ihigh-ilow); return 0; } --- 617,623 ---- "mmap slice assignment is wrong size"); return -1; } ! buf = (unsigned char *) PyString_AsString(v); memcpy(self->data + ilow, buf, ihigh-ilow); return 0; } *************** *** 640,646 **** "mmap assignment must be single-character string"); return -1; } ! buf = PyString_AsString(v); self->data[i] = buf[0]; return 0; } --- 640,646 ---- "mmap assignment must be single-character string"); return -1; } ! buf = (unsigned char *) PyString_AsString(v); self->data[i] = buf[0]; return 0; } From pf@artcom-gmbh.de Mon Apr 3 10:55:41 2000 From: pf@artcom-gmbh.de (Peter Funk) Date: Mon, 3 Apr 2000 11:55:41 +0200 (MEST) Subject: [Patches] [1.6] dictionary objects: new method 'supplement' Message-ID: Dear Python patcher! Please consider to apply the patch appended below and commit into the CVS tree. It applies to: Python 1.6a1 as released on april 1st. --=-- argument: --=--=--=--=--=--=--=--=--=--=-->8--=- This patch adds a new method to dictionary and UserDict objects: '.supplement()' is a "sibling" of '.update()', but it add only those items that are not already there instead of replacing them. This idea has been discussed on python-dev last month. --=-- obligatory disclaimer: -=--=--=--=--=--=-->8--=- I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. --=-- dry signature: =--=--=--=--=--=--=--=--=-->8--=- Regards, Peter -- Peter Funk, Oldenburger Str.86, D-27777 Ganderkesee, Germany, Fax:+49 4222950260 office: +49 421 20419-0 (ArtCom GmbH, Grazer Str.8, D-28359 Bremen) --=-- patch: --=--=--=--=--=--=--=--=--=--=--=-->8--=- *** ../../cvs_01_04_00_orig/dist/src/Objects/dictobject.c Fri Mar 31 11:45:02 2000 --- src/Objects/dictobject.c Mon Apr 3 10:30:11 2000 *************** *** 734,739 **** --- 734,781 ---- } static PyObject * + dict_supplement(mp, args) + register dictobject *mp; + PyObject *args; + { + register int i; + dictobject *other; + dictentry *entry, *oldentry; + if (!PyArg_Parse(args, "O!", &PyDict_Type, &other)) + return NULL; + if (other == mp) + goto done; /* a.supplement(a); nothing to do */ + /* Do one big resize at the start, rather than incrementally + resizing as we insert new items. Expect that there will be + no (or few) overlapping keys. */ + if ((mp->ma_fill + other->ma_used)*3 >= mp->ma_size*2) { + if (dictresize(mp, (mp->ma_used + other->ma_used)*3/2) != 0) + return NULL; + } + for (i = 0; i < other->ma_size; i++) { + entry = &other->ma_table[i]; + if (entry->me_value != NULL) { + oldentry = lookdict(mp, entry->me_key, entry->me_hash); + if (oldentry->me_value == NULL) { + /* TODO: optimize: + 'insertdict' does another call to 'lookdict'. + But for sake of readability and symmetry with + 'dict_update' I didn't tried to avoid this. + At least not now as we go into 1.6 alpha. */ + Py_INCREF(entry->me_key); + Py_INCREF(entry->me_value); + insertdict(mp, entry->me_key, entry->me_hash, + entry->me_value); + } + } + } + done: + Py_INCREF(Py_None); + return Py_None; + } + + + static PyObject * dict_copy(mp, args) register dictobject *mp; PyObject *args; *************** *** 1045,1050 **** --- 1087,1093 ---- {"clear", (PyCFunction)dict_clear}, {"copy", (PyCFunction)dict_copy}, {"get", (PyCFunction)dict_get, METH_VARARGS}, + {"supplement", (PyCFunction)dict_supplement}, {NULL, NULL} /* sentinel */ }; *** ../../cvs_01_04_00_orig/dist/src/Lib/test/test_types.py Wed Feb 23 23:23:17 2000 --- src/Lib/test/test_types.py Mon Apr 3 10:41:53 2000 *************** *** 242,247 **** --- 242,250 ---- d.update({2:20}) d.update({1:1, 2:2, 3:3}) if d != {1:1, 2:2, 3:3}: raise TestFailed, 'dict update' + d.supplement({1:"not", 2:"neither", 4:4}) + if d != {1:1, 2:2, 3:3, 4:4}: raise TestFailed, 'dict supplement' + del d[4] if d.copy() != {1:1, 2:2, 3:3}: raise TestFailed, 'dict copy' if {}.copy() != {}: raise TestFailed, 'empty dict copy' # dict.get() *** ../../cvs_01_04_00_orig/dist/src/Lib/UserDict.py Wed Feb 2 16:10:14 2000 --- src/Lib/UserDict.py Mon Apr 3 10:45:17 2000 *************** *** 32,36 **** --- 32,45 ---- else: for k, v in dict.items(): self.data[k] = v + def supplement(self, dict): + if isinstance(dict, UserDict): + self.data.supplement(dict.data) + elif isinstance(dict, type(self.data)): + self.data.supplement(dict) + else: + for k, v in dict.items(): + if not self.data.has_key(k): + self.data[k] = v def get(self, key, failobj=None): return self.data.get(key, failobj) *** ../../cvs_01_04_00_orig/dist/src/Lib/test/test_userdict.py Fri Mar 26 16:32:02 1999 --- src/Lib/test/test_userdict.py Mon Apr 3 10:50:29 2000 *************** *** 93,101 **** --- 93,109 ---- t.update(u2) assert t == u2 + # Test supplement + + t = UserDict(d1) + t.supplement(u2) + assert t == u2 + # Test get for i in u2.keys(): assert u2.get(i) == u2[i] assert u1.get(i) == d1.get(i) assert u0.get(i) == d0.get(i) + + # TODO: Add a test using dir({}) to test for unimplemented methods From gstein@lyra.org Mon Apr 3 11:12:58 2000 From: gstein@lyra.org (Greg Stein) Date: Mon, 3 Apr 2000 03:12:58 -0700 (PDT) Subject: [Patches] Patches for bug report 258 - mmapmodule.c compile problem In-Reply-To: <38E844DC.75391280@per.dem.csiro.au> Message-ID: On Mon, 3 Apr 2000, Mark Favas wrote: >... > *** mmapmodule.c.orig Mon Apr 3 10:23:19 2000 > --- mmapmodule.c Mon Apr 3 14:57:23 2000 > *************** > *** 118,124 **** > char value; > char * where = (self->data+self->pos); > CHECK_VALID(NULL); > ! if ((where >= 0) && (where < (self->data+self->size))) { > value = (char) *(where); > self->pos += 1; > return Py_BuildValue("c", (char) *(where)); > --- 118,124 ---- > char value; > char * where = (self->data+self->pos); > CHECK_VALID(NULL); > ! if ((where >= (char *) 0) && (where < (self->data+self->size))) > { > value = (char) *(where); > self->pos += 1; > return Py_BuildValue("c", (char) *(where)); Nope... that should be (where >= self->data). The more obvious test would be something like: if (self->pos >= 0 && self->pos < self->size) and throw the error before ever worrying about setting up "where". > *************** > *** 617,623 **** > "mmap slice assignment is wrong size"); > return -1; > } > ! buf = PyString_AsString(v); > memcpy(self->data + ilow, buf, ihigh-ilow); > return 0; > } > --- 617,623 ---- > "mmap slice assignment is wrong size"); > return -1; > } > ! buf = (unsigned char *) PyString_AsString(v); > memcpy(self->data + ilow, buf, ihigh-ilow); > return 0; > } Rather than casting, the definition of "buf" should change to "const char *buf". > *************** > *** 640,646 **** > "mmap assignment must be single-character > string"); > return -1; > } > ! buf = PyString_AsString(v); > self->data[i] = buf[0]; > return 0; > } > --- 640,646 ---- > "mmap assignment must be single-character > string"); > return -1; > } > ! buf = (unsigned char *) PyString_AsString(v); > self->data[i] = buf[0]; > return 0; > } Same here. Cheers, -g -- Greg Stein, http://www.lyra.org/ From gstein@lyra.org Mon Apr 3 11:18:30 2000 From: gstein@lyra.org (Greg Stein) Date: Mon, 3 Apr 2000 03:18:30 -0700 (PDT) Subject: [Patches] [1.6] dictionary objects: new method 'supplement' In-Reply-To: Message-ID: I don't recall the termination of the discussion, but I don't know that consensus was ever reached. Personally, I find this of little value over the similar (not exact) code: def supplement(dict, extra): d = extra.copy() d.update(dict) return d If the dictionary needs to be modified in place, then the loop from your UserDict.supplement would be used. Another view: why keep adding methods to service all possible needs? Cheers, -g On Mon, 3 Apr 2000, Peter Funk wrote: > Dear Python patcher! > > Please consider to apply the patch appended below and commit into the CVS tree. > It applies to: Python 1.6a1 as released on april 1st. > --=-- argument: --=--=--=--=--=--=--=--=--=--=-->8--=- > This patch adds a new method to dictionary and UserDict objects: > '.supplement()' is a "sibling" of '.update()', but it add only > those items that are not already there instead of replacing them. > > This idea has been discussed on python-dev last month. > --=-- obligatory disclaimer: -=--=--=--=--=--=-->8--=- > I confirm that, to the best of my knowledge and belief, this > contribution is free of any claims of third parties under > copyright, patent or other rights or interests ("claims"). To > the extent that I have any such claims, I hereby grant to CNRI a > nonexclusive, irrevocable, royalty-free, worldwide license to > reproduce, distribute, perform and/or display publicly, prepare > derivative versions, and otherwise use this contribution as part > of the Python software and its related documentation, or any > derivative versions thereof, at no cost to CNRI or its licensed > users, and to authorize others to do so. > > I acknowledge that CNRI may, at its sole discretion, decide > whether or not to incorporate this contribution in the Python > software and its related documentation. I further grant CNRI > permission to use my name and other identifying information > provided to CNRI by me for use in connection with the Python > software and its related documentation. > --=-- dry signature: =--=--=--=--=--=--=--=--=-->8--=- > Regards, Peter > -- > Peter Funk, Oldenburger Str.86, D-27777 Ganderkesee, Germany, Fax:+49 4222950260 > office: +49 421 20419-0 (ArtCom GmbH, Grazer Str.8, D-28359 Bremen) > --=-- patch: --=--=--=--=--=--=--=--=--=--=--=-->8--=- > *** ../../cvs_01_04_00_orig/dist/src/Objects/dictobject.c Fri Mar 31 11:45:02 2000 > --- src/Objects/dictobject.c Mon Apr 3 10:30:11 2000 > *************** > *** 734,739 **** > --- 734,781 ---- > } > > static PyObject * > + dict_supplement(mp, args) > + register dictobject *mp; > + PyObject *args; > + { > + register int i; > + dictobject *other; > + dictentry *entry, *oldentry; > + if (!PyArg_Parse(args, "O!", &PyDict_Type, &other)) > + return NULL; > + if (other == mp) > + goto done; /* a.supplement(a); nothing to do */ > + /* Do one big resize at the start, rather than incrementally > + resizing as we insert new items. Expect that there will be > + no (or few) overlapping keys. */ > + if ((mp->ma_fill + other->ma_used)*3 >= mp->ma_size*2) { > + if (dictresize(mp, (mp->ma_used + other->ma_used)*3/2) != 0) > + return NULL; > + } > + for (i = 0; i < other->ma_size; i++) { > + entry = &other->ma_table[i]; > + if (entry->me_value != NULL) { > + oldentry = lookdict(mp, entry->me_key, entry->me_hash); > + if (oldentry->me_value == NULL) { > + /* TODO: optimize: > + 'insertdict' does another call to 'lookdict'. > + But for sake of readability and symmetry with > + 'dict_update' I didn't tried to avoid this. > + At least not now as we go into 1.6 alpha. */ > + Py_INCREF(entry->me_key); > + Py_INCREF(entry->me_value); > + insertdict(mp, entry->me_key, entry->me_hash, > + entry->me_value); > + } > + } > + } > + done: > + Py_INCREF(Py_None); > + return Py_None; > + } > + > + > + static PyObject * > dict_copy(mp, args) > register dictobject *mp; > PyObject *args; > *************** > *** 1045,1050 **** > --- 1087,1093 ---- > {"clear", (PyCFunction)dict_clear}, > {"copy", (PyCFunction)dict_copy}, > {"get", (PyCFunction)dict_get, METH_VARARGS}, > + {"supplement", (PyCFunction)dict_supplement}, > {NULL, NULL} /* sentinel */ > }; > > *** ../../cvs_01_04_00_orig/dist/src/Lib/test/test_types.py Wed Feb 23 23:23:17 2000 > --- src/Lib/test/test_types.py Mon Apr 3 10:41:53 2000 > *************** > *** 242,247 **** > --- 242,250 ---- > d.update({2:20}) > d.update({1:1, 2:2, 3:3}) > if d != {1:1, 2:2, 3:3}: raise TestFailed, 'dict update' > + d.supplement({1:"not", 2:"neither", 4:4}) > + if d != {1:1, 2:2, 3:3, 4:4}: raise TestFailed, 'dict supplement' > + del d[4] > if d.copy() != {1:1, 2:2, 3:3}: raise TestFailed, 'dict copy' > if {}.copy() != {}: raise TestFailed, 'empty dict copy' > # dict.get() > *** ../../cvs_01_04_00_orig/dist/src/Lib/UserDict.py Wed Feb 2 16:10:14 2000 > --- src/Lib/UserDict.py Mon Apr 3 10:45:17 2000 > *************** > *** 32,36 **** > --- 32,45 ---- > else: > for k, v in dict.items(): > self.data[k] = v > + def supplement(self, dict): > + if isinstance(dict, UserDict): > + self.data.supplement(dict.data) > + elif isinstance(dict, type(self.data)): > + self.data.supplement(dict) > + else: > + for k, v in dict.items(): > + if not self.data.has_key(k): > + self.data[k] = v > def get(self, key, failobj=None): > return self.data.get(key, failobj) > *** ../../cvs_01_04_00_orig/dist/src/Lib/test/test_userdict.py Fri Mar 26 16:32:02 1999 > --- src/Lib/test/test_userdict.py Mon Apr 3 10:50:29 2000 > *************** > *** 93,101 **** > --- 93,109 ---- > t.update(u2) > assert t == u2 > > + # Test supplement > + > + t = UserDict(d1) > + t.supplement(u2) > + assert t == u2 > + > # Test get > > for i in u2.keys(): > assert u2.get(i) == u2[i] > assert u1.get(i) == d1.get(i) > assert u0.get(i) == d0.get(i) > + > + # TODO: Add a test using dir({}) to test for unimplemented methods > > _______________________________________________ > Patches mailing list > Patches@python.org > http://www.python.org/mailman/listinfo/patches > -- Greg Stein, http://www.lyra.org/ From mal@lemburg.com Mon Apr 3 13:59:18 2000 From: mal@lemburg.com (M.-A. Lemburg) Date: Mon, 03 Apr 2000 14:59:18 +0200 Subject: [Patches] Unicode Patch Set 2000-04-03 Message-ID: <38E895A5.98FC0A4B@lemburg.com> This is a multi-part message in MIME format. --------------F97906822AA778CDBFA10B52 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit The attached patch set adds the following new features: New Unicode support for int(), float(), complex() and long(). - new APIs PyInt_FromUnicode() and PyLong_FromUnicode() - added support for Unicode to PyFloat_FromString() - new encoding API PyUnicode_EncodeDecimal() which converts Unicode to a decimal char* string (used in the above new APIs) - shortcuts for calls like int() and float() - tests for all of the above Better testing support for the standard codecs. Misc minor enhancements, such as an alias dbcs for the mbcs codec. -- Marc-Andre Lemburg ______________________________________________________________________ Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ --------------F97906822AA778CDBFA10B52 Content-Type: text/plain; charset=us-ascii; name="Unicode-Implementation-2000-04-03.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="Unicode-Implementation-2000-04-03.patch" diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Include/Python.h Python+Unicode/Include/Python.h --- CVS-Python/Include/Python.h Sat Mar 11 10:52:34 2000 +++ Python+Unicode/Include/Python.h Mon Apr 3 13:18:05 2000 @@ -72,6 +72,7 @@ #include "pydebug.h" +#include "unicodeobject.h" #include "intobject.h" #include "longobject.h" #include "floatobject.h" @@ -92,7 +93,6 @@ #include "cobject.h" #include "traceback.h" #include "sliceobject.h" -#include "unicodeobject.h" #include "codecs.h" #include "pyerrors.h" diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Include/intobject.h Python+Unicode/Include/intobject.h --- CVS-Python/Include/intobject.h Tue Mar 7 18:58:16 2000 +++ Python+Unicode/Include/intobject.h Mon Apr 3 12:54:35 2000 @@ -60,6 +60,7 @@ #define PyInt_Check(op) ((op)->ob_type == &PyInt_Type) extern DL_IMPORT(PyObject *) PyInt_FromString Py_PROTO((char*, char**, int)); +extern DL_IMPORT(PyObject *) PyInt_FromUnicode Py_PROTO((Py_UNICODE*, int, int)); extern DL_IMPORT(PyObject *) PyInt_FromLong Py_PROTO((long)); extern DL_IMPORT(long) PyInt_AsLong Py_PROTO((PyObject *)); extern DL_IMPORT(long) PyInt_GetMax Py_PROTO((void)); diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Include/longobject.h Python+Unicode/Include/longobject.h --- CVS-Python/Include/longobject.h Thu Jan 14 11:24:51 1999 +++ Python+Unicode/Include/longobject.h Mon Apr 3 13:00:50 2000 @@ -82,6 +82,7 @@ #endif /* HAVE_LONG_LONG */ DL_IMPORT(PyObject *) PyLong_FromString Py_PROTO((char *, char **, int)); +DL_IMPORT(PyObject *) PyLong_FromUnicode Py_PROTO((Py_UNICODE*, int, int)); #ifdef __cplusplus } diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Include/unicodeobject.h Python+Unicode/Include/unicodeobject.h --- CVS-Python/Include/unicodeobject.h Wed Mar 29 11:50:05 2000 +++ Python+Unicode/Include/unicodeobject.h Mon Apr 3 14:17:10 2000 @@ -358,7 +358,7 @@ /* --- UTF-16 Codecs ------------------------------------------------------ */ -/* Decodes length bytes from a UTF-16 encoded buffer string and return +/* Decodes length bytes from a UTF-16 encoded buffer string and returns the corresponding Unicode object. errors (if non-NULL) defines the error handling. It defaults @@ -397,7 +397,7 @@ ); /* Returns a Python string object holding the UTF-16 encoded value of - the Unicode data in s. + the Unicode data. If byteorder is not 0, output is written according to the following byte order: @@ -586,6 +586,37 @@ ); #endif /* MS_WIN32 */ + +/* --- Decimal Encoder ---------------------------------------------------- */ + +/* Takes a Unicode string holding a decimal value and writes it into + an output buffer using standard ASCII digit codes. + + The output buffer has to provide at least length+1 bytes of storage + area. The output string is 0-terminated. + + The encoder converts whitespace to ' ', decimal characters to their + corresponding ASCII digit and all other Latin-1 characters as-is. + Characters outside the Latin-1 range (Unicode ordinals 0-256) are + treated as errors. + + Error handling is defined by the errors argument: + + NULL or "strict": raise a ValueError + "ignore": ignore the wrong characters (these are not copied to the + output buffer) + "replace": replaces illegal characters with '?' + + Returns 0 on success, -1 on failure. + +*/ + +extern DL_IMPORT(int) PyUnicode_EncodeDecimal( + Py_UNICODE *s, /* Unicode buffer */ + int length, /* Number of Py_UNICODE chars to encode */ + char *output, /* Output buffer; must have size >= length */ + const char *errors /* error handling */ + ); /* --- Methods & Slots ---------------------------------------------------- diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Lib/encodings/__init__.py Python+Unicode/Lib/encodings/__init__.py --- CVS-Python/Lib/encodings/__init__.py Thu Mar 23 23:58:42 2000 +++ Python+Unicode/Lib/encodings/__init__.py Mon Apr 3 13:41:40 2000 @@ -4,8 +4,8 @@ directory. Codec modules must have names corresponding to standard lower-case - encoding names. Hyphens are automatically converted to - underscores, e.g. 'utf-8' is looked up as module utf_8. + encoding names with hyphens mapped to underscores, e.g. 'utf-8' is + implemented by the module 'utf_8.py'. Each codec module must export the following interface: @@ -40,7 +40,7 @@ return entry # Import the module - modname = string.replace(encoding,'-','_') + modname = string.replace(encoding, '-', '_') modname = aliases.aliases.get(modname,modname) try: mod = __import__(modname,globals(),locals(),'*') diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Lib/encodings/aliases.py Python+Unicode/Lib/encodings/aliases.py --- CVS-Python/Lib/encodings/aliases.py Mon Apr 3 13:45:48 2000 +++ Python+Unicode/Lib/encodings/aliases.py Sat Apr 1 20:14:36 2000 @@ -54,4 +54,7 @@ 'macroman': 'mac_roman', 'macturkish': 'mac_turkish', + # MBCS + 'dbcs': 'mbcs', + } diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Lib/test/output/test_unicode Python+Unicode/Lib/test/output/test_unicode --- CVS-Python/Lib/test/output/test_unicode Wed Mar 29 11:50:15 2000 +++ Python+Unicode/Lib/test/output/test_unicode Mon Apr 3 14:46:51 2000 @@ -3,3 +3,4 @@ Testing Unicode contains method... done. Testing Unicode formatting strings... done. Testing builtin codecs... done. +Testing standard mapping codecs... 0-127... 128-255... done. diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Lib/test/test_b1.py Python+Unicode/Lib/test/test_b1.py --- CVS-Python/Lib/test/test_b1.py Fri Mar 26 15:58:20 1999 +++ Python+Unicode/Lib/test/test_b1.py Mon Apr 3 13:35:19 2000 @@ -95,6 +95,7 @@ if complex(0j, 3.14) <> 3.14j: raise TestFailed, 'complex(0j, 3.14)' if complex(0.0, 3.14) <> 3.14j: raise TestFailed, 'complex(0.0, 3.14)' if complex(" 3.14+J ") <> 3.14+1j: raise TestFailed, 'complex(" 3.14+J )"' +if complex(u" 3.14+J ") <> 3.14+1j: raise TestFailed, 'complex(u" 3.14+J )"' class Z: def __complex__(self): return 3.14j z = Z() @@ -208,6 +209,9 @@ if float(314) <> 314.0: raise TestFailed, 'float(314)' if float(314L) <> 314.0: raise TestFailed, 'float(314L)' if float(" 3.14 ") <> 3.14: raise TestFailed, 'float(" 3.14 ")' +if float(u" 3.14 ") <> 3.14: raise TestFailed, 'float(u" 3.14 ")' +if float(u" \u0663.\u0661\u0664 ") <> 3.14: + raise TestFailed, 'float(u" \u0663.\u0661\u0664 ")' print 'getattr' import sys @@ -270,6 +274,19 @@ ('', ValueError), (' ', ValueError), (' \t\t ', ValueError), + (u'0', 0), + (u'1', 1), + (u'9', 9), + (u'10', 10), + (u'99', 99), + (u'100', 100), + (u'314', 314), + (u' 314', 314), + (u'\u0663\u0661\u0664 ', 314), + (u' \t\t 314 \t\t ', 314), + (u'', ValueError), + (u' ', ValueError), + (u' \t\t ', ValueError), ] for s, v in L: for sign in "", "+", "-": @@ -353,6 +370,8 @@ LL = [ ('1' + '0'*20, 10L**20), ('1' + '0'*100, 10L**100), + (u'1' + u'0'*20, 10L**20), + (u'1' + u'0'*100, 10L**100), ] for s, v in L + LL: for sign in "", "+", "-": diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Lib/test/test_unicode.py Python+Unicode/Lib/test/test_unicode.py --- CVS-Python/Lib/test/test_unicode.py Wed Mar 29 11:50:14 2000 +++ Python+Unicode/Lib/test/test_unicode.py Sat Apr 1 00:05:35 2000 @@ -270,11 +270,88 @@ assert unicode(u.encode(encoding),encoding) == u u = u''.join(map(unichr, range(256))) -for encoding in ('latin-1',): +for encoding in ( + 'latin-1', + ): + try: assert unicode(u.encode(encoding),encoding) == u + except AssertionError: + print '*** codec "%s" failed round-trip' % encoding + except ValueError,why: + print '*** codec for "%s" failed: %s' % (encoding, why) u = u''.join(map(unichr, range(128))) -for encoding in ('ascii',): +for encoding in ( + 'ascii', + ): + try: assert unicode(u.encode(encoding),encoding) == u + except AssertionError: + print '*** codec "%s" failed round-trip' % encoding + except ValueError,why: + print '*** codec for "%s" failed: %s' % (encoding, why) + +print 'done.' + +print 'Testing standard mapping codecs...', + +print '0-127...', +s = ''.join(map(chr, range(128))) +for encoding in ( + 'cp037', 'cp1026', + 'cp437', 'cp500', 'cp737', 'cp775', 'cp850', + 'cp852', 'cp855', 'cp860', 'cp861', 'cp862', + 'cp863', 'cp865', 'cp866', + 'iso8859_10', 'iso8859_13', 'iso8859_14', 'iso8859_15', + 'iso8859_2', 'iso8859_3', 'iso8859_4', 'iso8859_5', 'iso8859_6', + 'iso8859_7', 'iso8859_9', 'koi8_r', 'latin_1', + 'mac_cyrillic', 'mac_latin2', + + 'cp1250', 'cp1251', 'cp1252', 'cp1253', 'cp1254', 'cp1255', + 'cp1256', 'cp1257', 'cp1258', + 'cp856', 'cp857', 'cp864', 'cp869', 'cp874', + + 'mac_greek', 'mac_iceland','mac_roman', 'mac_turkish', + 'cp1006', 'cp875', 'iso8859_8', + + ### These have undefined mappings: + #'cp424', + + ): + try: + assert unicode(s,encoding).encode(encoding) == s + except AssertionError: + print '*** codec "%s" failed round-trip' % encoding + except ValueError,why: + print '*** codec for "%s" failed: %s' % (encoding, why) + +print '128-255...', +s = ''.join(map(chr, range(128,256))) +for encoding in ( + 'cp037', 'cp1026', + 'cp437', 'cp500', 'cp737', 'cp775', 'cp850', + 'cp852', 'cp855', 'cp860', 'cp861', 'cp862', + 'cp863', 'cp865', 'cp866', + 'iso8859_10', 'iso8859_13', 'iso8859_14', 'iso8859_15', + 'iso8859_2', 'iso8859_3', 'iso8859_4', 'iso8859_5', 'iso8859_6', + 'iso8859_7', 'iso8859_9', 'koi8_r', 'latin_1', + 'mac_cyrillic', 'mac_latin2', + + ### These have undefined mappings: + #'cp1250', 'cp1251', 'cp1252', 'cp1253', 'cp1254', 'cp1255', + #'cp1256', 'cp1257', 'cp1258', + #'cp424', 'cp856', 'cp857', 'cp864', 'cp869', 'cp874', + #'mac_greek', 'mac_iceland','mac_roman', 'mac_turkish', + + ### These fail the round-trip: + #'cp1006', 'cp875', 'iso8859_8', + + ): + try: + assert unicode(s,encoding).encode(encoding) == s + except AssertionError: + print '*** codec "%s" failed round-trip' % encoding + except ValueError,why: + print '*** codec for "%s" failed: %s' % (encoding, why) print 'done.' diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Misc/unicode.txt Python+Unicode/Misc/unicode.txt --- CVS-Python/Misc/unicode.txt Wed Mar 29 11:50:15 2000 +++ Python+Unicode/Misc/unicode.txt Mon Apr 3 14:46:51 2000 @@ -1,5 +1,5 @@ ============================================================================= - Python Unicode Integration Proposal Version: 1.2 + Python Unicode Integration Proposal Version: 1.3 ----------------------------------------------------------------------------- @@ -203,8 +203,9 @@ codecs.register(search_function) Search functions are expected to take one argument, the encoding name -in all lower case letters, and return a tuple of functions (encoder, -decoder, stream_reader, stream_writer) taking the following arguments: +in all lower case letters and with hyphens and spaces converted to +underscores, and return a tuple of functions (encoder, decoder, +stream_reader, stream_writer) taking the following arguments: encoder and decoder: These must be functions or methods which have the same Only in CVS-Python/Objects: .#stringobject.c.2.59 diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Objects/abstract.c Python+Unicode/Objects/abstract.c --- CVS-Python/Objects/abstract.c Sat Mar 11 10:55:08 2000 +++ Python+Unicode/Objects/abstract.c Mon Apr 3 14:40:06 2000 @@ -736,8 +736,16 @@ if (o == NULL) return null_error(); + if (PyInt_Check(o)) { + Py_INCREF(o); + return o; + } if (PyString_Check(o)) return PyInt_FromString(PyString_AS_STRING(o), NULL, 10); + if (PyUnicode_Check(o)) + return PyInt_FromUnicode(PyUnicode_AS_UNICODE(o), + PyUnicode_GET_SIZE(o), + 10); m = o->ob_type->tp_as_number; if (m && m->nb_int) return m->nb_int(o); @@ -814,6 +822,10 @@ if (o == NULL) return null_error(); + if (PyLong_Check(o)) { + Py_INCREF(o); + return o; + } if (PyString_Check(o)) /* need to do extra error checking that PyLong_FromString() * doesn't do. In particular long('9.5') must raise an @@ -821,6 +833,11 @@ */ return long_from_string(PyString_AS_STRING(o), PyString_GET_SIZE(o)); + if (PyUnicode_Check(o)) + /* The above check is done in PyLong_FromUnicode(). */ + return PyLong_FromUnicode(PyUnicode_AS_UNICODE(o), + PyUnicode_GET_SIZE(o), + 10); m = o->ob_type->tp_as_number; if (m && m->nb_long) return m->nb_long(o); @@ -838,6 +855,10 @@ if (o == NULL) return null_error(); + if (PyFloat_Check(o)) { + Py_INCREF(o); + return o; + } if (!PyString_Check(o)) { m = o->ob_type->tp_as_number; if (m && m->nb_float) diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Objects/floatobject.c Python+Unicode/Objects/floatobject.c --- CVS-Python/Objects/floatobject.c Sat Mar 11 10:55:08 2000 +++ Python+Unicode/Objects/floatobject.c Mon Apr 3 14:42:03 2000 @@ -163,6 +163,22 @@ if (PyString_Check(v)) { s = PyString_AS_STRING(v); len = PyString_GET_SIZE(v); + } + else if (PyUnicode_Check(v)) { + char s_buffer[256]; + + if (PyUnicode_GET_SIZE(v) >= sizeof(s_buffer)) { + PyErr_SetString(PyExc_ValueError, + "float() literal too large to convert"); + return NULL; + } + if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v), + PyUnicode_GET_SIZE(v), + s_buffer, + NULL)) + return NULL; + s = s_buffer; + len = strlen(s); } else if (PyObject_AsCharBuffer(v, &s, &len)) { PyErr_SetString(PyExc_TypeError, diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Objects/intobject.c Python+Unicode/Objects/intobject.c --- CVS-Python/Objects/intobject.c Sat Mar 11 10:55:08 2000 +++ Python+Unicode/Objects/intobject.c Mon Apr 3 14:42:35 2000 @@ -259,6 +259,24 @@ if (pend) *pend = end; return PyInt_FromLong(x); +} + +PyObject * +PyInt_FromUnicode(s, length, base) + Py_UNICODE *s; + int length; + int base; +{ + char buffer[256]; + + if (length >= sizeof(buffer)) { + PyErr_SetString(PyExc_ValueError, + "int() literal too large to convert"); + return NULL; + } + if (PyUnicode_EncodeDecimal(s, length, buffer, NULL)) + return NULL; + return PyInt_FromString(buffer, NULL, base); } /* Methods */ diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Objects/longobject.c Python+Unicode/Objects/longobject.c --- CVS-Python/Objects/longobject.c Wed Jan 19 18:01:30 2000 +++ Python+Unicode/Objects/longobject.c Mon Apr 3 14:43:08 2000 @@ -783,6 +783,57 @@ if (pend) *pend = str; return (PyObject *) z; +} + +PyObject * +PyLong_FromUnicode(u, length, base) + Py_UNICODE *u; + int length; + int base; +{ + char s_buffer[256]; + char *s; + const char *start; + char *end; + PyObject *x; + char buffer[256]; /* For errors */ + + /* Convert to decimal string */ + if (length >= sizeof(s_buffer)) { + PyErr_SetString(PyExc_ValueError, + "long() literal too large to convert"); + return NULL; + } + if (PyUnicode_EncodeDecimal(u, length, s_buffer, NULL)) + return NULL; + s = s_buffer; + + /* Convert to long object and apply the same error handling + as is done for PyInt_FromString(). */ + start = s; + while (*s && isspace(Py_CHARMASK(*s))) + s++; + x = PyLong_FromString((char*)s, &end, base); + if (x == NULL) { + if (PyErr_ExceptionMatches(PyExc_ValueError)) + goto bad; + return NULL; + } + while (*end && isspace(Py_CHARMASK(*end))) + end++; + if (*end != '\0') { + bad: + sprintf(buffer, "invalid literal for long(): %.200s", s); + PyErr_SetString(PyExc_ValueError, buffer); + Py_XDECREF(x); + return NULL; + } + else if (end != start + length) { + PyErr_SetString(PyExc_ValueError, + "null byte in argument for long()"); + return NULL; + } + return x; } static PyLongObject *x_divrem Only in CVS-Python/Objects: stringobject.c.orig diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Objects/unicodeobject.c Python+Unicode/Objects/unicodeobject.c --- CVS-Python/Objects/unicodeobject.c Mon Apr 3 13:46:02 2000 +++ Python+Unicode/Objects/unicodeobject.c Mon Apr 3 14:43:52 2000 @@ -1923,6 +1923,60 @@ return NULL; } +/* --- Decimal Encoder ---------------------------------------------------- */ + +int PyUnicode_EncodeDecimal(Py_UNICODE *s, + int length, + char *output, + const char *errors) +{ + Py_UNICODE *p, *end; + + if (output == NULL) { + PyErr_BadArgument(); + return -1; + } + + p = s; + end = s + length; + while (p < end) { + register Py_UNICODE ch = *p++; + int decimal; + + if (Py_UNICODE_ISSPACE(ch)) { + *output++ = ' '; + continue; + } + decimal = Py_UNICODE_TODECIMAL(ch); + if (decimal >= 0) { + *output++ = '0' + decimal; + continue; + } + if (ch < 256) { + *output++ = ch; + continue; + } + /* All other characters are considered invalid */ + if (errors == NULL || strcmp(errors, "strict") == 0) { + PyErr_SetString(PyExc_ValueError, + "invalid numeric string"); + goto onError; + } + else if (strcmp(errors, "ignore") == 0) + continue; + else if (strcmp(errors, "replace") == 0) { + *output++ = '?'; + continue; + } + } + /* 0-terminate the output string */ + *output++ = '\0'; + return 0; + + onError: + return -1; +} + /* --- Helpers ------------------------------------------------------------ */ static diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Python/bltinmodule.c Python+Unicode/Python/bltinmodule.c --- CVS-Python/Python/bltinmodule.c Sat Mar 11 10:55:20 2000 +++ Python+Unicode/Python/bltinmodule.c Mon Apr 3 14:41:16 2000 @@ -449,17 +449,44 @@ PyObject *v; { extern double strtod Py_PROTO((const char *, char **)); - char *s, *start, *end; + const char *s, *start; + char *end; double x=0.0, y=0.0, z; int got_re=0, got_im=0, done=0; int digit_or_dot; int sw_error=0; int sign; char buffer[256]; /* For errors */ + int len; - start = s = PyString_AS_STRING(v); + if (PyString_Check(v)) { + s = PyString_AS_STRING(v); + len = PyString_GET_SIZE(v); + } + else if (PyUnicode_Check(v)) { + char s_buffer[256]; + + if (PyUnicode_GET_SIZE(v) >= sizeof(s_buffer)) { + PyErr_SetString(PyExc_ValueError, + "complex() literal too large to convert"); + return NULL; + } + if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v), + PyUnicode_GET_SIZE(v), + s_buffer, + NULL)) + return NULL; + s = s_buffer; + len = strlen(s); + } + else if (PyObject_AsCharBuffer(v, &s, &len)) { + PyErr_SetString(PyExc_TypeError, + "complex() needs a string first argument"); + return NULL; + } /* position on first nonblank */ + start = s; while (*s && isspace(Py_CHARMASK(*s))) s++; if (s[0] == '\0') { @@ -475,7 +502,7 @@ switch (*s) { case '\0': - if (s-start != PyString_GET_SIZE(v)) { + if (s-start != len) { PyErr_SetString( PyExc_ValueError, "null byte in argument for complex()"); @@ -584,7 +611,7 @@ i = NULL; if (!PyArg_ParseTuple(args, "O|O:complex", &r, &i)) return NULL; - if (PyString_Check(r)) + if (PyString_Check(r) || PyUnicode_Check(r)) return complex_from_string(r); if ((nbr = r->ob_type->tp_as_number) == NULL || nbr->nb_float == NULL || @@ -1289,12 +1316,17 @@ return NULL; if (base == -909) return PyNumber_Int(v); - else if (!PyString_Check(v)) { + else if (PyString_Check(v)) + return PyInt_FromString(PyString_AS_STRING(v), NULL, base); + else if (PyUnicode_Check(v)) + return PyInt_FromUnicode(PyUnicode_AS_UNICODE(v), + PyUnicode_GET_SIZE(v), + base); + else { PyErr_SetString(PyExc_TypeError, "can't convert non-string with explicit base"); return NULL; } - return PyInt_FromString(PyString_AS_STRING(v), NULL, base); } static char int_doc[] = diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Python/codecs.c Python+Unicode/Python/codecs.c --- CVS-Python/Python/codecs.c Mon Apr 3 13:46:03 2000 +++ Python+Unicode/Python/codecs.c Sat Apr 1 19:57:52 2000 @@ -84,8 +84,11 @@ return -1; } +/* Convert a string to a normalized Python string: all characters are + converted to lower case, spaces are replaced with underscores. */ + static -PyObject *lowercasestring(const char *string) +PyObject *normalizestring(const char *string) { register int i; int len = strlen(string); @@ -96,8 +99,14 @@ if (v == NULL) return NULL; p = PyString_AS_STRING(v); - for (i = 0; i < len; i++) - p[i] = tolower(string[i]); + for (i = 0; i < len; i++) { + register char ch = string[i]; + if (ch == ' ') + ch = '-'; + else + ch = tolower(ch); + p[i] = ch; + } return v; } @@ -132,8 +141,10 @@ goto onError; } - /* Convert the encoding to a lower-cased Python string */ - v = lowercasestring(encoding); + /* Convert the encoding to a normalized Python string: all + characters are converted to lower case, spaces and hypens are + replaced with underscores. */ + v = normalizestring(encoding); if (v == NULL) goto onError; PyString_InternInPlace(&v); --------------F97906822AA778CDBFA10B52-- From bwarsaw@cnri.reston.va.us Mon Apr 3 14:01:28 2000 From: bwarsaw@cnri.reston.va.us (Barry A. Warsaw) Date: Mon, 3 Apr 2000 09:01:28 -0400 (EDT) Subject: [Patches] New lib module: UserString.py and testcase for it References: <14568.5667.841020.109795@seahag.cnri.reston.va.us> Message-ID: <14568.38440.757591.172014@anthem.cnri.reston.va.us> >>>>> "Fred" == Fred L Drake, Jr writes: Fred> Peter, It's in, but I think there's a problem with the Fred> anonCVS getting updated from my checkins. I'll look further Fred> into that tomorrow. ;( Attachments are better for me, but Fred> can deal with shar as well. Just hope I never have to use a Fred> non-Unix box for development! ;) Thanks! I just re-ran the sync script so those changes have been pushed out to cvs.python.org -Barry From mal@lemburg.com Mon Apr 3 15:46:28 2000 From: mal@lemburg.com (M.-A. Lemburg) Date: Mon, 03 Apr 2000 16:46:28 +0200 Subject: [Patches] Unicode Patch Set 2000-04-03 References: <38E895A5.98FC0A4B@lemburg.com> Message-ID: <38E8AEC4.CE1E63BB@lemburg.com> This is a multi-part message in MIME format. --------------751C647C75D9C69DDEBDDF5E Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit While adding the string.ato?() patches I found that I had forgotten to fix the long() builtin to also accept Unicode. The attached patch set now includes long() Unicode support too. I've also added some test cases which verify this (the original test cases didn't check the base argument which caused the tests to pass). -- Marc-Andre Lemburg ______________________________________________________________________ Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ --------------751C647C75D9C69DDEBDDF5E Content-Type: text/plain; charset=us-ascii; name="Unicode-Implementation-2000-04-03.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="Unicode-Implementation-2000-04-03.patch" diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Include/Python.h Python+Unicode/Include/Python.h --- CVS-Python/Include/Python.h Sat Mar 11 10:52:34 2000 +++ Python+Unicode/Include/Python.h Mon Apr 3 13:18:05 2000 @@ -72,6 +72,7 @@ #include "pydebug.h" +#include "unicodeobject.h" #include "intobject.h" #include "longobject.h" #include "floatobject.h" @@ -92,7 +93,6 @@ #include "cobject.h" #include "traceback.h" #include "sliceobject.h" -#include "unicodeobject.h" #include "codecs.h" #include "pyerrors.h" diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Include/intobject.h Python+Unicode/Include/intobject.h --- CVS-Python/Include/intobject.h Tue Mar 7 18:58:16 2000 +++ Python+Unicode/Include/intobject.h Mon Apr 3 12:54:35 2000 @@ -60,6 +60,7 @@ #define PyInt_Check(op) ((op)->ob_type == &PyInt_Type) extern DL_IMPORT(PyObject *) PyInt_FromString Py_PROTO((char*, char**, int)); +extern DL_IMPORT(PyObject *) PyInt_FromUnicode Py_PROTO((Py_UNICODE*, int, int)); extern DL_IMPORT(PyObject *) PyInt_FromLong Py_PROTO((long)); extern DL_IMPORT(long) PyInt_AsLong Py_PROTO((PyObject *)); extern DL_IMPORT(long) PyInt_GetMax Py_PROTO((void)); diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Include/longobject.h Python+Unicode/Include/longobject.h --- CVS-Python/Include/longobject.h Thu Jan 14 11:24:51 1999 +++ Python+Unicode/Include/longobject.h Mon Apr 3 13:00:50 2000 @@ -82,6 +82,7 @@ #endif /* HAVE_LONG_LONG */ DL_IMPORT(PyObject *) PyLong_FromString Py_PROTO((char *, char **, int)); +DL_IMPORT(PyObject *) PyLong_FromUnicode Py_PROTO((Py_UNICODE*, int, int)); #ifdef __cplusplus } diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Include/unicodeobject.h Python+Unicode/Include/unicodeobject.h --- CVS-Python/Include/unicodeobject.h Wed Mar 29 11:50:05 2000 +++ Python+Unicode/Include/unicodeobject.h Mon Apr 3 14:47:33 2000 @@ -358,7 +358,7 @@ /* --- UTF-16 Codecs ------------------------------------------------------ */ -/* Decodes length bytes from a UTF-16 encoded buffer string and return +/* Decodes length bytes from a UTF-16 encoded buffer string and returns the corresponding Unicode object. errors (if non-NULL) defines the error handling. It defaults @@ -397,7 +397,7 @@ ); /* Returns a Python string object holding the UTF-16 encoded value of - the Unicode data in s. + the Unicode data. If byteorder is not 0, output is written according to the following byte order: @@ -586,6 +586,37 @@ ); #endif /* MS_WIN32 */ + +/* --- Decimal Encoder ---------------------------------------------------- */ + +/* Takes a Unicode string holding a decimal value and writes it into + an output buffer using standard ASCII digit codes. + + The output buffer has to provide at least length+1 bytes of storage + area. The output string is 0-terminated. + + The encoder converts whitespace to ' ', decimal characters to their + corresponding ASCII digit and all other Latin-1 characters as-is. + Characters outside the Latin-1 range (Unicode ordinals 0-256) are + treated as errors. + + Error handling is defined by the errors argument: + + NULL or "strict": raise a ValueError + "ignore": ignore the wrong characters (these are not copied to the + output buffer) + "replace": replaces illegal characters with '?' + + Returns 0 on success, -1 on failure. + +*/ + +extern DL_IMPORT(int) PyUnicode_EncodeDecimal( + Py_UNICODE *s, /* Unicode buffer */ + int length, /* Number of Py_UNICODE chars to encode */ + char *output, /* Output buffer; must have size >= length */ + const char *errors /* error handling */ + ); /* --- Methods & Slots ---------------------------------------------------- diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Lib/encodings/__init__.py Python+Unicode/Lib/encodings/__init__.py --- CVS-Python/Lib/encodings/__init__.py Thu Mar 23 23:58:42 2000 +++ Python+Unicode/Lib/encodings/__init__.py Mon Apr 3 13:41:40 2000 @@ -4,8 +4,8 @@ directory. Codec modules must have names corresponding to standard lower-case - encoding names. Hyphens are automatically converted to - underscores, e.g. 'utf-8' is looked up as module utf_8. + encoding names with hyphens mapped to underscores, e.g. 'utf-8' is + implemented by the module 'utf_8.py'. Each codec module must export the following interface: @@ -40,7 +40,7 @@ return entry # Import the module - modname = string.replace(encoding,'-','_') + modname = string.replace(encoding, '-', '_') modname = aliases.aliases.get(modname,modname) try: mod = __import__(modname,globals(),locals(),'*') diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Lib/encodings/aliases.py Python+Unicode/Lib/encodings/aliases.py --- CVS-Python/Lib/encodings/aliases.py Mon Apr 3 13:45:48 2000 +++ Python+Unicode/Lib/encodings/aliases.py Sat Apr 1 20:14:36 2000 @@ -54,4 +54,7 @@ 'macroman': 'mac_roman', 'macturkish': 'mac_turkish', + # MBCS + 'dbcs': 'mbcs', + } diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Lib/string.py Python+Unicode/Lib/string.py --- CVS-Python/Lib/string.py Sat Mar 11 10:52:36 2000 +++ Python+Unicode/Lib/string.py Mon Apr 3 16:09:58 2000 @@ -196,14 +196,11 @@ Return the floating point number represented by the string s. """ - if type(s) == _StringType: return _float(s) - else: - raise TypeError('argument 1: expected string, %s found' % - type(s).__name__) + # Convert string to integer -def atoi(*args): +def atoi(s , base=10): """atoi(s [,base]) -> int Return the integer represented by the string s in the given @@ -214,23 +211,11 @@ accepted. """ - try: - s = args[0] - except IndexError: - raise TypeError('function requires at least 1 argument: %d given' % - len(args)) - # Don't catch type error resulting from too many arguments to int(). The - # error message isn't compatible but the error type is, and this function - # is complicated enough already. - if type(s) == _StringType: - return _apply(_int, args) - else: - raise TypeError('argument 1: expected string, %s found' % - type(s).__name__) + return _int(s, base) # Convert string to long integer -def atol(*args): +def atol(s, base=10): """atol(s [,base]) -> long Return the long integer represented by the string s in the @@ -242,19 +227,7 @@ unless base is 0. """ - try: - s = args[0] - except IndexError: - raise TypeError('function requires at least 1 argument: %d given' % - len(args)) - # Don't catch type error resulting from too many arguments to long(). The - # error message isn't compatible but the error type is, and this function - # is complicated enough already. - if type(s) == _StringType: - return _apply(_long, args) - else: - raise TypeError('argument 1: expected string, %s found' % - type(s).__name__) + return _long(s, base) # Left-justify a string diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Lib/test/output/test_unicode Python+Unicode/Lib/test/output/test_unicode --- CVS-Python/Lib/test/output/test_unicode Wed Mar 29 11:50:15 2000 +++ Python+Unicode/Lib/test/output/test_unicode Mon Apr 3 16:23:26 2000 @@ -3,3 +3,4 @@ Testing Unicode contains method... done. Testing Unicode formatting strings... done. Testing builtin codecs... done. +Testing standard mapping codecs... 0-127... 128-255... done. diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Lib/test/test_b1.py Python+Unicode/Lib/test/test_b1.py --- CVS-Python/Lib/test/test_b1.py Fri Mar 26 15:58:20 1999 +++ Python+Unicode/Lib/test/test_b1.py Mon Apr 3 16:21:34 2000 @@ -95,6 +95,7 @@ if complex(0j, 3.14) <> 3.14j: raise TestFailed, 'complex(0j, 3.14)' if complex(0.0, 3.14) <> 3.14j: raise TestFailed, 'complex(0.0, 3.14)' if complex(" 3.14+J ") <> 3.14+1j: raise TestFailed, 'complex(" 3.14+J )"' +if complex(u" 3.14+J ") <> 3.14+1j: raise TestFailed, 'complex(u" 3.14+J )"' class Z: def __complex__(self): return 3.14j z = Z() @@ -208,6 +209,9 @@ if float(314) <> 314.0: raise TestFailed, 'float(314)' if float(314L) <> 314.0: raise TestFailed, 'float(314L)' if float(" 3.14 ") <> 3.14: raise TestFailed, 'float(" 3.14 ")' +if float(u" 3.14 ") <> 3.14: raise TestFailed, 'float(u" 3.14 ")' +if float(u" \u0663.\u0661\u0664 ") <> 3.14: + raise TestFailed, 'float(u" \u0663.\u0661\u0664 ")' print 'getattr' import sys @@ -254,6 +258,9 @@ if int(-3.9) <> -3: raise TestFailed, 'int(-3.9)' if int(3.5) <> 3: raise TestFailed, 'int(3.5)' if int(-3.5) <> -3: raise TestFailed, 'int(-3.5)' +# Different base: +if int("10",16) <> 16L: raise TestFailed, 'int("10",16)' +if int(u"10",16) <> 16L: raise TestFailed, 'int(u"10",16)' # Test conversion fron strings and various anomalies L = [ ('0', 0), @@ -270,6 +277,19 @@ ('', ValueError), (' ', ValueError), (' \t\t ', ValueError), + (u'0', 0), + (u'1', 1), + (u'9', 9), + (u'10', 10), + (u'99', 99), + (u'100', 100), + (u'314', 314), + (u' 314', 314), + (u'\u0663\u0661\u0664 ', 314), + (u' \t\t 314 \t\t ', 314), + (u'', ValueError), + (u' ', ValueError), + (u' \t\t ', ValueError), ] for s, v in L: for sign in "", "+", "-": @@ -349,10 +369,17 @@ if long(-3.9) <> -3L: raise TestFailed, 'long(-3.9)' if long(3.5) <> 3L: raise TestFailed, 'long(3.5)' if long(-3.5) <> -3L: raise TestFailed, 'long(-3.5)' +if long("-3") <> -3L: raise TestFailed, 'long("-3")' +if long(u"-3") <> -3L: raise TestFailed, 'long(u"-3")' +# Different base: +if long("10",16) <> 16L: raise TestFailed, 'long("10",16)' +if long(u"10",16) <> 16L: raise TestFailed, 'long(u"10",16)' # Check conversions from string (same test set as for int(), and then some) LL = [ ('1' + '0'*20, 10L**20), ('1' + '0'*100, 10L**100), + (u'1' + u'0'*20, 10L**20), + (u'1' + u'0'*100, 10L**100), ] for s, v in L + LL: for sign in "", "+", "-": @@ -363,11 +390,11 @@ vv = -v try: if long(ss) != long(vv): - raise TestFailed, "int(%s)" % `ss` + raise TestFailed, "long(%s)" % `ss` except v: pass except ValueError, e: - raise TestFailed, "int(%s) raised ValueError: %s" % (`ss`, e) + raise TestFailed, "long(%s) raised ValueError: %s" % (`ss`, e) print 'map' if map(None, 'hello world') <> ['h','e','l','l','o',' ','w','o','r','l','d']: diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Lib/test/test_unicode.py Python+Unicode/Lib/test/test_unicode.py --- CVS-Python/Lib/test/test_unicode.py Wed Mar 29 11:50:14 2000 +++ Python+Unicode/Lib/test/test_unicode.py Sat Apr 1 00:05:35 2000 @@ -270,11 +270,88 @@ assert unicode(u.encode(encoding),encoding) == u u = u''.join(map(unichr, range(256))) -for encoding in ('latin-1',): +for encoding in ( + 'latin-1', + ): + try: assert unicode(u.encode(encoding),encoding) == u + except AssertionError: + print '*** codec "%s" failed round-trip' % encoding + except ValueError,why: + print '*** codec for "%s" failed: %s' % (encoding, why) u = u''.join(map(unichr, range(128))) -for encoding in ('ascii',): +for encoding in ( + 'ascii', + ): + try: assert unicode(u.encode(encoding),encoding) == u + except AssertionError: + print '*** codec "%s" failed round-trip' % encoding + except ValueError,why: + print '*** codec for "%s" failed: %s' % (encoding, why) + +print 'done.' + +print 'Testing standard mapping codecs...', + +print '0-127...', +s = ''.join(map(chr, range(128))) +for encoding in ( + 'cp037', 'cp1026', + 'cp437', 'cp500', 'cp737', 'cp775', 'cp850', + 'cp852', 'cp855', 'cp860', 'cp861', 'cp862', + 'cp863', 'cp865', 'cp866', + 'iso8859_10', 'iso8859_13', 'iso8859_14', 'iso8859_15', + 'iso8859_2', 'iso8859_3', 'iso8859_4', 'iso8859_5', 'iso8859_6', + 'iso8859_7', 'iso8859_9', 'koi8_r', 'latin_1', + 'mac_cyrillic', 'mac_latin2', + + 'cp1250', 'cp1251', 'cp1252', 'cp1253', 'cp1254', 'cp1255', + 'cp1256', 'cp1257', 'cp1258', + 'cp856', 'cp857', 'cp864', 'cp869', 'cp874', + + 'mac_greek', 'mac_iceland','mac_roman', 'mac_turkish', + 'cp1006', 'cp875', 'iso8859_8', + + ### These have undefined mappings: + #'cp424', + + ): + try: + assert unicode(s,encoding).encode(encoding) == s + except AssertionError: + print '*** codec "%s" failed round-trip' % encoding + except ValueError,why: + print '*** codec for "%s" failed: %s' % (encoding, why) + +print '128-255...', +s = ''.join(map(chr, range(128,256))) +for encoding in ( + 'cp037', 'cp1026', + 'cp437', 'cp500', 'cp737', 'cp775', 'cp850', + 'cp852', 'cp855', 'cp860', 'cp861', 'cp862', + 'cp863', 'cp865', 'cp866', + 'iso8859_10', 'iso8859_13', 'iso8859_14', 'iso8859_15', + 'iso8859_2', 'iso8859_3', 'iso8859_4', 'iso8859_5', 'iso8859_6', + 'iso8859_7', 'iso8859_9', 'koi8_r', 'latin_1', + 'mac_cyrillic', 'mac_latin2', + + ### These have undefined mappings: + #'cp1250', 'cp1251', 'cp1252', 'cp1253', 'cp1254', 'cp1255', + #'cp1256', 'cp1257', 'cp1258', + #'cp424', 'cp856', 'cp857', 'cp864', 'cp869', 'cp874', + #'mac_greek', 'mac_iceland','mac_roman', 'mac_turkish', + + ### These fail the round-trip: + #'cp1006', 'cp875', 'iso8859_8', + + ): + try: + assert unicode(s,encoding).encode(encoding) == s + except AssertionError: + print '*** codec "%s" failed round-trip' % encoding + except ValueError,why: + print '*** codec for "%s" failed: %s' % (encoding, why) print 'done.' diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Misc/unicode.txt Python+Unicode/Misc/unicode.txt --- CVS-Python/Misc/unicode.txt Wed Mar 29 11:50:15 2000 +++ Python+Unicode/Misc/unicode.txt Mon Apr 3 16:23:25 2000 @@ -1,5 +1,5 @@ ============================================================================= - Python Unicode Integration Proposal Version: 1.2 + Python Unicode Integration Proposal Version: 1.3 ----------------------------------------------------------------------------- @@ -203,8 +203,9 @@ codecs.register(search_function) Search functions are expected to take one argument, the encoding name -in all lower case letters, and return a tuple of functions (encoder, -decoder, stream_reader, stream_writer) taking the following arguments: +in all lower case letters and with hyphens and spaces converted to +underscores, and return a tuple of functions (encoder, decoder, +stream_reader, stream_writer) taking the following arguments: encoder and decoder: These must be functions or methods which have the same Only in CVS-Python/Objects: .#stringobject.c.2.59 diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Objects/abstract.c Python+Unicode/Objects/abstract.c --- CVS-Python/Objects/abstract.c Sat Mar 11 10:55:08 2000 +++ Python+Unicode/Objects/abstract.c Mon Apr 3 14:40:06 2000 @@ -736,8 +736,16 @@ if (o == NULL) return null_error(); + if (PyInt_Check(o)) { + Py_INCREF(o); + return o; + } if (PyString_Check(o)) return PyInt_FromString(PyString_AS_STRING(o), NULL, 10); + if (PyUnicode_Check(o)) + return PyInt_FromUnicode(PyUnicode_AS_UNICODE(o), + PyUnicode_GET_SIZE(o), + 10); m = o->ob_type->tp_as_number; if (m && m->nb_int) return m->nb_int(o); @@ -814,6 +822,10 @@ if (o == NULL) return null_error(); + if (PyLong_Check(o)) { + Py_INCREF(o); + return o; + } if (PyString_Check(o)) /* need to do extra error checking that PyLong_FromString() * doesn't do. In particular long('9.5') must raise an @@ -821,6 +833,11 @@ */ return long_from_string(PyString_AS_STRING(o), PyString_GET_SIZE(o)); + if (PyUnicode_Check(o)) + /* The above check is done in PyLong_FromUnicode(). */ + return PyLong_FromUnicode(PyUnicode_AS_UNICODE(o), + PyUnicode_GET_SIZE(o), + 10); m = o->ob_type->tp_as_number; if (m && m->nb_long) return m->nb_long(o); @@ -838,6 +855,10 @@ if (o == NULL) return null_error(); + if (PyFloat_Check(o)) { + Py_INCREF(o); + return o; + } if (!PyString_Check(o)) { m = o->ob_type->tp_as_number; if (m && m->nb_float) diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Objects/floatobject.c Python+Unicode/Objects/floatobject.c --- CVS-Python/Objects/floatobject.c Sat Mar 11 10:55:08 2000 +++ Python+Unicode/Objects/floatobject.c Mon Apr 3 14:42:03 2000 @@ -163,6 +163,22 @@ if (PyString_Check(v)) { s = PyString_AS_STRING(v); len = PyString_GET_SIZE(v); + } + else if (PyUnicode_Check(v)) { + char s_buffer[256]; + + if (PyUnicode_GET_SIZE(v) >= sizeof(s_buffer)) { + PyErr_SetString(PyExc_ValueError, + "float() literal too large to convert"); + return NULL; + } + if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v), + PyUnicode_GET_SIZE(v), + s_buffer, + NULL)) + return NULL; + s = s_buffer; + len = strlen(s); } else if (PyObject_AsCharBuffer(v, &s, &len)) { PyErr_SetString(PyExc_TypeError, diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Objects/intobject.c Python+Unicode/Objects/intobject.c --- CVS-Python/Objects/intobject.c Sat Mar 11 10:55:08 2000 +++ Python+Unicode/Objects/intobject.c Mon Apr 3 14:42:35 2000 @@ -259,6 +259,24 @@ if (pend) *pend = end; return PyInt_FromLong(x); +} + +PyObject * +PyInt_FromUnicode(s, length, base) + Py_UNICODE *s; + int length; + int base; +{ + char buffer[256]; + + if (length >= sizeof(buffer)) { + PyErr_SetString(PyExc_ValueError, + "int() literal too large to convert"); + return NULL; + } + if (PyUnicode_EncodeDecimal(s, length, buffer, NULL)) + return NULL; + return PyInt_FromString(buffer, NULL, base); } /* Methods */ diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Objects/longobject.c Python+Unicode/Objects/longobject.c --- CVS-Python/Objects/longobject.c Wed Jan 19 18:01:30 2000 +++ Python+Unicode/Objects/longobject.c Mon Apr 3 14:43:08 2000 @@ -783,6 +783,57 @@ if (pend) *pend = str; return (PyObject *) z; +} + +PyObject * +PyLong_FromUnicode(u, length, base) + Py_UNICODE *u; + int length; + int base; +{ + char s_buffer[256]; + char *s; + const char *start; + char *end; + PyObject *x; + char buffer[256]; /* For errors */ + + /* Convert to decimal string */ + if (length >= sizeof(s_buffer)) { + PyErr_SetString(PyExc_ValueError, + "long() literal too large to convert"); + return NULL; + } + if (PyUnicode_EncodeDecimal(u, length, s_buffer, NULL)) + return NULL; + s = s_buffer; + + /* Convert to long object and apply the same error handling + as is done for PyInt_FromString(). */ + start = s; + while (*s && isspace(Py_CHARMASK(*s))) + s++; + x = PyLong_FromString((char*)s, &end, base); + if (x == NULL) { + if (PyErr_ExceptionMatches(PyExc_ValueError)) + goto bad; + return NULL; + } + while (*end && isspace(Py_CHARMASK(*end))) + end++; + if (*end != '\0') { + bad: + sprintf(buffer, "invalid literal for long(): %.200s", s); + PyErr_SetString(PyExc_ValueError, buffer); + Py_XDECREF(x); + return NULL; + } + else if (end != start + length) { + PyErr_SetString(PyExc_ValueError, + "null byte in argument for long()"); + return NULL; + } + return x; } static PyLongObject *x_divrem Only in CVS-Python/Objects: stringobject.c.orig diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Objects/unicodeobject.c Python+Unicode/Objects/unicodeobject.c --- CVS-Python/Objects/unicodeobject.c Mon Apr 3 13:46:02 2000 +++ Python+Unicode/Objects/unicodeobject.c Mon Apr 3 14:43:52 2000 @@ -1923,6 +1923,60 @@ return NULL; } +/* --- Decimal Encoder ---------------------------------------------------- */ + +int PyUnicode_EncodeDecimal(Py_UNICODE *s, + int length, + char *output, + const char *errors) +{ + Py_UNICODE *p, *end; + + if (output == NULL) { + PyErr_BadArgument(); + return -1; + } + + p = s; + end = s + length; + while (p < end) { + register Py_UNICODE ch = *p++; + int decimal; + + if (Py_UNICODE_ISSPACE(ch)) { + *output++ = ' '; + continue; + } + decimal = Py_UNICODE_TODECIMAL(ch); + if (decimal >= 0) { + *output++ = '0' + decimal; + continue; + } + if (ch < 256) { + *output++ = ch; + continue; + } + /* All other characters are considered invalid */ + if (errors == NULL || strcmp(errors, "strict") == 0) { + PyErr_SetString(PyExc_ValueError, + "invalid numeric string"); + goto onError; + } + else if (strcmp(errors, "ignore") == 0) + continue; + else if (strcmp(errors, "replace") == 0) { + *output++ = '?'; + continue; + } + } + /* 0-terminate the output string */ + *output++ = '\0'; + return 0; + + onError: + return -1; +} + /* --- Helpers ------------------------------------------------------------ */ static diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Python/bltinmodule.c Python+Unicode/Python/bltinmodule.c --- CVS-Python/Python/bltinmodule.c Sat Mar 11 10:55:20 2000 +++ Python+Unicode/Python/bltinmodule.c Mon Apr 3 16:14:02 2000 @@ -449,17 +449,44 @@ PyObject *v; { extern double strtod Py_PROTO((const char *, char **)); - char *s, *start, *end; + const char *s, *start; + char *end; double x=0.0, y=0.0, z; int got_re=0, got_im=0, done=0; int digit_or_dot; int sw_error=0; int sign; char buffer[256]; /* For errors */ + int len; - start = s = PyString_AS_STRING(v); + if (PyString_Check(v)) { + s = PyString_AS_STRING(v); + len = PyString_GET_SIZE(v); + } + else if (PyUnicode_Check(v)) { + char s_buffer[256]; + + if (PyUnicode_GET_SIZE(v) >= sizeof(s_buffer)) { + PyErr_SetString(PyExc_ValueError, + "complex() literal too large to convert"); + return NULL; + } + if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v), + PyUnicode_GET_SIZE(v), + s_buffer, + NULL)) + return NULL; + s = s_buffer; + len = strlen(s); + } + else if (PyObject_AsCharBuffer(v, &s, &len)) { + PyErr_SetString(PyExc_TypeError, + "complex() needs a string first argument"); + return NULL; + } /* position on first nonblank */ + start = s; while (*s && isspace(Py_CHARMASK(*s))) s++; if (s[0] == '\0') { @@ -475,7 +502,7 @@ switch (*s) { case '\0': - if (s-start != PyString_GET_SIZE(v)) { + if (s-start != len) { PyErr_SetString( PyExc_ValueError, "null byte in argument for complex()"); @@ -584,7 +611,7 @@ i = NULL; if (!PyArg_ParseTuple(args, "O|O:complex", &r, &i)) return NULL; - if (PyString_Check(r)) + if (PyString_Check(r) || PyUnicode_Check(r)) return complex_from_string(r); if ((nbr = r->ob_type->tp_as_number) == NULL || nbr->nb_float == NULL || @@ -1289,12 +1316,17 @@ return NULL; if (base == -909) return PyNumber_Int(v); - else if (!PyString_Check(v)) { + else if (PyString_Check(v)) + return PyInt_FromString(PyString_AS_STRING(v), NULL, base); + else if (PyUnicode_Check(v)) + return PyInt_FromUnicode(PyUnicode_AS_UNICODE(v), + PyUnicode_GET_SIZE(v), + base); + else { PyErr_SetString(PyExc_TypeError, "can't convert non-string with explicit base"); return NULL; } - return PyInt_FromString(PyString_AS_STRING(v), NULL, base); } static char int_doc[] = @@ -1319,12 +1351,17 @@ return NULL; if (base == -909) return PyNumber_Long(v); - else if (!PyString_Check(v)) { + else if (PyString_Check(v)) + return PyLong_FromString(PyString_AS_STRING(v), NULL, base); + else if (PyUnicode_Check(v)) + return PyLong_FromUnicode(PyUnicode_AS_UNICODE(v), + PyUnicode_GET_SIZE(v), + base); + else { PyErr_SetString(PyExc_TypeError, "can't convert non-string with explicit base"); return NULL; } - return PyLong_FromString(PyString_AS_STRING(v), NULL, base); } static char long_doc[] = diff -u -b -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x Demo -x CVS -x Doc CVS-Python/Python/codecs.c Python+Unicode/Python/codecs.c --- CVS-Python/Python/codecs.c Mon Apr 3 13:46:03 2000 +++ Python+Unicode/Python/codecs.c Sat Apr 1 19:57:52 2000 @@ -84,8 +84,11 @@ return -1; } +/* Convert a string to a normalized Python string: all characters are + converted to lower case, spaces are replaced with underscores. */ + static -PyObject *lowercasestring(const char *string) +PyObject *normalizestring(const char *string) { register int i; int len = strlen(string); @@ -96,8 +99,14 @@ if (v == NULL) return NULL; p = PyString_AS_STRING(v); - for (i = 0; i < len; i++) - p[i] = tolower(string[i]); + for (i = 0; i < len; i++) { + register char ch = string[i]; + if (ch == ' ') + ch = '-'; + else + ch = tolower(ch); + p[i] = ch; + } return v; } @@ -132,8 +141,10 @@ goto onError; } - /* Convert the encoding to a lower-cased Python string */ - v = lowercasestring(encoding); + /* Convert the encoding to a normalized Python string: all + characters are converted to lower case, spaces and hypens are + replaced with underscores. */ + v = normalizestring(encoding); if (v == NULL) goto onError; PyString_InternInPlace(&v); --------------751C647C75D9C69DDEBDDF5E-- From jeremy@cnri.reston.va.us Mon Apr 3 17:36:24 2000 From: jeremy@cnri.reston.va.us (Jeremy Hylton) Date: Mon, 3 Apr 2000 12:36:24 -0400 (EDT) Subject: [Patches] [1.6] dictionary objects: new method 'supplement' In-Reply-To: References: Message-ID: <14568.51336.811523.937351@bitdiddle.cnri.reston.va.us> I agree with Greg. Jeremy From bwarsaw@cnri.reston.va.us Mon Apr 3 18:20:19 2000 From: bwarsaw@cnri.reston.va.us (Barry A. Warsaw) Date: Mon, 3 Apr 2000 13:20:19 -0400 (EDT) Subject: [Python-Dev] Re: [Patches] [1.6] dictionary objects: new method 'supplement' References: <14568.51336.811523.937351@bitdiddle.cnri.reston.va.us> Message-ID: <14568.53971.777162.624760@anthem.cnri.reston.va.us> -0 on dict.supplement(), not the least because I'll always missspell it :) -Barry From Mark.Favas@per.dem.csiro.au Tue Apr 4 04:07:13 2000 From: Mark.Favas@per.dem.csiro.au (Favas, Mark (EM, Floreat)) Date: Tue, 4 Apr 2000 11:07:13 +0800 Subject: [Patches] RE: Revised Patches for bug report 258 - mmapmodule.c compile pro blem Message-ID: <1508AAEAF1D9D111B65300A0C944CCF11632BF@mailhost.per.its.CSIRO.AU> This message is in MIME format. Since your mail reader does not understand this format, some or all of this message may not be legible. ------_=_NextPart_000_01BF9DE2.DFE78026 Content-Type: text/plain; charset="windows-1252" OK - attached are revised patches based on the comments below. Compiles without error/warning and passes test_mmap... Thanks, Greg. Cheers, Mark -----Original Message----- From: Greg Stein [mailto:gstein@lyra.org] Sent: Monday, 3 April 2000 6:13 PM To: Mark Favas Cc: patches@python.org Subject: Re: [Patches] Patches for bug report 258 - mmapmodule.c compile problem On Mon, 3 Apr 2000, Mark Favas wrote: >... > *** mmapmodule.c.orig Mon Apr 3 10:23:19 2000 > --- mmapmodule.c Mon Apr 3 14:57:23 2000 > *************** > *** 118,124 **** > char value; > char * where = (self->data+self->pos); > CHECK_VALID(NULL); > ! if ((where >= 0) && (where < (self->data+self->size))) { > value = (char) *(where); > self->pos += 1; > return Py_BuildValue("c", (char) *(where)); > --- 118,124 ---- > char value; > char * where = (self->data+self->pos); > CHECK_VALID(NULL); > ! if ((where >= (char *) 0) && (where < (self->data+self->size))) > { > value = (char) *(where); > self->pos += 1; > return Py_BuildValue("c", (char) *(where)); Nope... that should be (where >= self->data). The more obvious test would be something like: if (self->pos >= 0 && self->pos < self->size) and throw the error before ever worrying about setting up "where". > *************** > *** 617,623 **** > "mmap slice assignment is wrong size"); > return -1; > } > ! buf = PyString_AsString(v); > memcpy(self->data + ilow, buf, ihigh-ilow); > return 0; > } > --- 617,623 ---- > "mmap slice assignment is wrong size"); > return -1; > } > ! buf = (unsigned char *) PyString_AsString(v); > memcpy(self->data + ilow, buf, ihigh-ilow); > return 0; > } Rather than casting, the definition of "buf" should change to "const char *buf". > *************** > *** 640,646 **** > "mmap assignment must be single-character > string"); > return -1; > } > ! buf = PyString_AsString(v); > self->data[i] = buf[0]; > return 0; > } > --- 640,646 ---- > "mmap assignment must be single-character > string"); > return -1; > } > ! buf = (unsigned char *) PyString_AsString(v); > self->data[i] = buf[0]; > return 0; > } Same here. Cheers, -g -- Greg Stein, http://www.lyra.org/ ------_=_NextPart_000_01BF9DE2.DFE78026 Content-Type: application/octet-stream; name="mmap-patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="mmap-patch" *** mmapmodule.c.orig Mon Apr 3 10:23:19 2000=0A= --- mmapmodule.c Tue Apr 4 10:58:26 2000=0A= ***************=0A= *** 116,124 ****=0A= PyObject * args)=0A= {=0A= char value;=0A= ! char * where =3D (self->data+self->pos);=0A= CHECK_VALID(NULL);=0A= ! if ((where >=3D 0) && (where < (self->data+self->size))) {=0A= value =3D (char) *(where);=0A= self->pos +=3D 1;=0A= return Py_BuildValue("c", (char) *(where));=0A= --- 116,125 ----=0A= PyObject * args)=0A= {=0A= char value;=0A= ! char * where;=0A= CHECK_VALID(NULL);=0A= ! if (self->pos >=3D 0 && self->pos < self->size) {=0A= ! where =3D self->data + self->pos;=0A= value =3D (char) *(where);=0A= self->pos +=3D 1;=0A= return Py_BuildValue("c", (char) *(where));=0A= ***************=0A= *** 593,599 ****=0A= int ilow, ihigh;=0A= PyObject *v;=0A= {=0A= ! unsigned char *buf;=0A= =0A= CHECK_VALID(-1);=0A= if (ilow < 0)=0A= --- 594,600 ----=0A= int ilow, ihigh;=0A= PyObject *v;=0A= {=0A= ! const char *buf;=0A= =0A= CHECK_VALID(-1);=0A= if (ilow < 0)=0A= ***************=0A= *** 628,634 ****=0A= int i;=0A= PyObject *v;=0A= {=0A= ! unsigned char *buf;=0A= =0A= CHECK_VALID(-1);=0A= if (i < 0 || i >=3D self->size) {=0A= --- 629,635 ----=0A= int i;=0A= PyObject *v;=0A= {=0A= ! const char *buf;=0A= =0A= CHECK_VALID(-1);=0A= if (i < 0 || i >=3D self->size) {=0A= ------_=_NextPart_000_01BF9DE2.DFE78026-- From gansevle@cs.utwente.nl Tue Apr 4 15:51:07 2000 From: gansevle@cs.utwente.nl (Fred Gansevles) Date: Tue, 04 Apr 2000 16:51:07 +0200 Subject: [Patches] (no subject) Message-ID: <200004041451.QAA07735@localhost.localdomain> This patch solves 2 problems of the os module. 1) Bug ID #50 (case-mismatch wiht "environ.get(..,..)" and "del environ[..]") 2) os.environ.update (dict) doesn't propagate changes to the 'real' environment (i.e doesn't call putenv) This patches also has minor changes specific for 1.6a The string module isn't used anymore, instead the strings own methods are used. ---------------------------------------------------------------- I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. FAQ about legal I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. ---------------------------------------------------------------- Index: os.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/os.py,v retrieving revision 1.30 diff -c -r1.30 os.py *** os.py 2000/02/04 15:39:30 1.30 --- os.py 2000/04/04 14:34:35 *************** *** 220,227 **** envpath = env['PATH'] else: envpath = defpath ! import string ! PATH = string.splitfields(envpath, pathsep) if not _notfound: import tempfile # Exec a file that is guaranteed not to exist --- 220,226 ---- envpath = env['PATH'] else: envpath = defpath ! PATH = envpath.split (pathsep) if not _notfound: import tempfile # Exec a file that is guaranteed not to exist *************** *** 248,269 **** if name in ('os2', 'nt', 'dos'): # Where Env Var Names Must Be UPPERCASE # But we store them as upper case - import string class _Environ(UserDict.UserDict): def __init__(self, environ): UserDict.UserDict.__init__(self) data = self.data - upper = string.upper for k, v in environ.items(): ! data[upper(k)] = v def __setitem__(self, key, item): putenv(key, item) ! key = string.upper(key) ! self.data[key] = item def __getitem__(self, key): ! return self.data[string.upper(key)] def has_key(self, key): ! return self.data.has_key(string.upper(key)) else: # Where Env Var Names Can Be Mixed Case class _Environ(UserDict.UserDict): --- 247,272 ---- if name in ('os2', 'nt', 'dos'): # Where Env Var Names Must Be UPPERCASE # But we store them as upper case class _Environ(UserDict.UserDict): def __init__(self, environ): UserDict.UserDict.__init__(self) data = self.data for k, v in environ.items(): ! data[k.upper()] = v def __setitem__(self, key, item): putenv(key, item) ! self.data[key.upper()] = item def __getitem__(self, key): ! return self.data[key.upper()] ! def __delitem__(self, key): ! del self.data[key.upper()] def has_key(self, key): ! return self.data.has_key(key.upper()) ! def get(self, key, failobj=None): ! return self.data.get(key.upper(), failobj) ! def update(self, dict): ! for k, v in dict.items(): ! self[k] = v else: # Where Env Var Names Can Be Mixed Case class _Environ(UserDict.UserDict): *************** *** 273,278 **** --- 276,284 ---- def __setitem__(self, key, item): putenv(key, item) self.data[key] = item + def update(self, dict): + for k, v in dict.items(): + self[k] = v environ = _Environ(environ) From hniksic@iskon.hr Tue Apr 4 19:11:32 2000 From: hniksic@iskon.hr (Hrvoje Niksic) Date: 04 Apr 2000 20:11:32 +0200 Subject: [Patches] Fix for readline() method of mmap objects Message-ID: I'm glad that mmapmodule.c made it into Python 1.6. Some time ago I've found a bug in it, and it's still there. The bug is in mmap_read_line_method(), and its loop that searches for newlines. After the loop reaches EOF, eol is incremented and points after the end of the memory. This results in readline() method sometimes picking up and returning a byte after the end of the string. This is usually a bogus \0, but it could cause SIGSEGV if it's after the end of the page). The patch fixes the problem. Also, it uses memchr() for finding a character, which is in fact the "strnchr" the comment is asking for. memchr() is already used in Python sources, so there should be no portability problems. *** Modules/mmapmodule.c.old Tue Apr 4 15:57:07 2000 --- Modules/mmapmodule.c Tue Apr 4 15:57:40 2000 *************** *** 132,151 **** mmap_read_line_method (mmap_object * self, PyObject * args) { ! char * start; char * eof = self->data+self->size; char * eol; PyObject * result; CHECK_VALID(NULL); - start = self->data+self->pos; ! /* strchr was a bad idea here - there's no way to range ! check it. there is no 'strnchr' */ ! for (eol = start; (eol < eof) && (*eol != '\n') ; eol++) ! { /* do nothing */ } ! ! result = Py_BuildValue("s#", start, (long) (++eol - start)); self->pos += (eol - start); return (result); } --- 132,151 ---- mmap_read_line_method (mmap_object * self, PyObject * args) { ! char * start = self->data+self->pos; char * eof = self->data+self->size; char * eol; PyObject * result; CHECK_VALID(NULL); ! eol = memchr(start, '\n', self->size - self->pos); ! if (!eol) ! eol = eof; ! else ! ++eol; /* we're interested in the position after the ! newline. */ ! result = PyString_FromStringAndSize(start, (long) (eol - start)); self->pos += (eol - start); return (result); } I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. From guido@python.org Tue Apr 4 22:43:07 2000 From: guido@python.org (Guido van Rossum) Date: Tue, 04 Apr 2000 17:43:07 -0400 Subject: [Patches] Unicode Patch Set 2000-04-03 In-Reply-To: Your message of "Mon, 03 Apr 2000 16:46:28 +0200." <38E8AEC4.CE1E63BB@lemburg.com> References: <38E895A5.98FC0A4B@lemburg.com> <38E8AEC4.CE1E63BB@lemburg.com> Message-ID: <200004042143.RAA14149@eric.cnri.reston.va.us> Your patch set introduced a syntax error in string.py, because a line ("return _float(s)" in atof()) had changed only in indentation, and "diff -b" doesn't flag that as a difference. A similar thing happened in test_unicode.py, where two asserts weren't indented. I wonder if there are other places where this might have happened without introducing a syntax error... I've also found another problem (which may have existed before???): in test.test_string.py, string.atol(' 1x ',) is supposed to raise ValueError, but actually returns 1L. I'll hold off on checkin in these changes... --Guido van Rossum (home page: http://www.python.org/~guido/) From mal@lemburg.com Tue Apr 4 23:10:17 2000 From: mal@lemburg.com (M.-A. Lemburg) Date: Wed, 05 Apr 2000 00:10:17 +0200 Subject: [Patches] Unicode Patch Set 2000-04-03 References: <38E895A5.98FC0A4B@lemburg.com> <38E8AEC4.CE1E63BB@lemburg.com> <200004042143.RAA14149@eric.cnri.reston.va.us> Message-ID: <38EA6849.F3EA5F24@lemburg.com> Guido van Rossum wrote: > > Your patch set introduced a syntax error in string.py, because a line > ("return _float(s)" in atof()) had changed only in indentation, and > "diff -b" doesn't flag that as a difference. A similar thing happened > in test_unicode.py, where two asserts weren't indented. Hmm, you're right. I'll drop the "-b" and resend the patch along with the compare updates. > I wonder if there are other places where this might have happened > without introducing a syntax error... > > I've also found another problem (which may have existed before???): > in test.test_string.py, string.atol(' 1x ',) is supposed to raise > ValueError, but actually returns 1L. > > I'll hold off on checkin in these changes... Ouch, I only checked test_builtin, not test_string when I added the new Unicode support to int() et al. The different semantics in string.atol() are due to the change I did to the string.py ato?() APIs. I asked on python-dev about this and noone objected, so I simply tried the change. While doing so I found a rather strange semantic difference in the string->long conversion: Quote from python-dev: """ One thing I noticed, which needs some discussion: There are two separate APIs which convert long string literals to long objects: PyNumber_Long() and PyLong_FromString(). The first applies the same error checking as does the PyInt_FromString() API, while the latter does not apply this check... Question is: shouldn't the check for truncated data ("9.5" -> 9L) be moved into PyLong_FromString() ? """ This is the origin of long(' 1x ') causing an exception, while long(' 1x ',10) masks the error. IMHO, these two should be synchronised to int()'s behaviour which is to raise errors in both cases. Since I changed string.atol to use long() directly rather than trying to emulate the old error string, the different behaviour now shines through :-) Should I leave the string.py patch out of the set until there has been some more discussion on python-dev ? -- Marc-Andre Lemburg ______________________________________________________________________ Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ From guido@python.org Tue Apr 4 23:07:34 2000 From: guido@python.org (Guido van Rossum) Date: Tue, 04 Apr 2000 18:07:34 -0400 Subject: [Patches] Unicode Patch Set 2000-04-03 In-Reply-To: Your message of "Wed, 05 Apr 2000 00:10:17 +0200." <38EA6849.F3EA5F24@lemburg.com> References: <38E895A5.98FC0A4B@lemburg.com> <38E8AEC4.CE1E63BB@lemburg.com> <200004042143.RAA14149@eric.cnri.reston.va.us> <38EA6849.F3EA5F24@lemburg.com> Message-ID: <200004042207.SAA14508@eric.cnri.reston.va.us> > The different semantics in string.atol() are due to the change > I did to the string.py ato?() APIs. I asked on python-dev about > this and noone objected, so I simply tried the change. While > doing so I found a rather strange semantic difference in the > string->long conversion: > > Quote from python-dev: > """ > One thing I noticed, which needs some discussion: > > There are two separate APIs which convert long string literals > to long objects: PyNumber_Long() and PyLong_FromString(). > The first applies the same error checking as does the > PyInt_FromString() API, while the latter does not apply > this check... > > Question is: shouldn't the check for truncated > data ("9.5" -> 9L) be moved into PyLong_FromString() ? > """ > > This is the origin of long(' 1x ') causing an exception, > while long(' 1x ',10) masks the error. IMHO, these two > should be synchronised to int()'s behaviour which is to > raise errors in both cases. > > Since I changed string.atol to use long() directly rather > than trying to emulate the old error string, the different > behaviour now shines through :-) > > Should I leave the string.py patch out of the set until > there has been some more discussion on python-dev ? I was too busy to follow this, but I think that the error should be raised in all cases -- no further discussion needed. --Guido van Rossum (home page: http://www.python.org/~guido/) From mal@lemburg.com Tue Apr 4 23:23:18 2000 From: mal@lemburg.com (M.-A. Lemburg) Date: Wed, 05 Apr 2000 00:23:18 +0200 Subject: [Patches] string.atol() [Unicode Patch Set 2000-04-03] References: <38E895A5.98FC0A4B@lemburg.com> <38E8AEC4.CE1E63BB@lemburg.com> <200004042143.RAA14149@eric.cnri.reston.va.us> <38EA6849.F3EA5F24@lemburg.com> Message-ID: <38EA6B56.B6C6557D@lemburg.com> "M.-A. Lemburg" wrote: > > Guido van Rossum wrote: > > > > I've also found another problem (which may have existed before???): > > in test.test_string.py, string.atol(' 1x ',) is supposed to raise > > ValueError, but actually returns 1L. > > > > I'll hold off on checkin in these changes... > > Ouch, I only checked test_builtin, not test_string when I > added the new Unicode support to int() et al. > > The different semantics in string.atol() are due to the change > I did to the string.py ato?() APIs. I asked on python-dev about > this and noone objected, so I simply tried the change. While > doing so I found a rather strange semantic difference in the > string->long conversion: > > Should I leave the string.py patch out of the set until > there has been some more discussion on python-dev ? BTW, to get the regr. test to pass and string.atol() work exactly like before, you only have to change the default base to the magic number -909. -- Marc-Andre Lemburg ______________________________________________________________________ Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ From mal@lemburg.com Wed Apr 5 01:53:10 2000 From: mal@lemburg.com (M.-A. Lemburg) Date: Wed, 05 Apr 2000 02:53:10 +0200 Subject: [Patches] Unicode Patch Set 2000-04-05 Message-ID: <38EA8E76.66359797@lemburg.com> This is a multi-part message in MIME format. --------------962125C15898CA694E9D8F57 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit After not having much luck with the last patch set, here's a new one which hopefully fixes all the problems with the other two versions. Here's what's in the bag: New Unicode support for int(), float(), complex() and long(). - new APIs PyInt_FromUnicode() and PyLong_FromUnicode() - added support for Unicode to PyFloat_FromString() - new encoding API PyUnicode_EncodeDecimal() which converts Unicode to a decimal char* string (used in the above new APIs) - shortcuts for calls like int() and float() - tests for all of the above Unicode compares and contains checks: - comparing Unicode and non-string types now works; TypeErrors are masked, all other errors such as ValueError during Unicode coercion are passed through (note that PyUnicode_Compare does not implement the masking -- PyObject_Compare does this) - contains now works for non-string types too; TypeErrors are masked and 0 returned; all other errors are passed through Better testing support for the standard codecs. Misc minor enhancements, such as an alias dbcs for the mbcs codec. Changes: - PyLong_FromString() now applies the same error checks as does PyInt_FromString(): trailing garbage is reported as error and not longer silently ignored. The only characters which may be trailing the digits are 'L' and 'l' -- these are still silently ignored. - string.ato?() now directly interface to int(), long() and float(). The error strings are now a little different, but the type still remains the same. These functions are now ready to get declared obsolete ;-) - PyNumber_Int() now also does a check for embedded NULL chars in the input string; PyNumber_Long() already did this (and still does) -- Some minor things I noticed while compiling the CVS Version on Linux2/glibc2 using -Wall which may or may not need tweaking: fileobject.c: In function `file_seek': fileobject.c:285: warning: implicit declaration of function `fseeko' ceval.c: In function `eval_code2': ceval.c:355: warning: `opcode' might be used uninitialized in this function ceval.c:356: warning: `oparg' might be used uninitialized in this function ./pypcre.c: In function `compile_branch': ./pypcre.c:1222: warning: `c' might be used uninitialized in this function ./pypcre.c: In function `pcre_exec': ./pypcre.c:4524: warning: variable `start_bits' might be clobbered by `longjmp' or `vfork' ./pypcre.c:4525: warning: variable `start_match' might be clobbered by `longjmp' or `vfork' ./posixmodule.c:504: warning: `posix_strint' defined but not used ./readline.c: In function `call_readline': ./readline.c:386: warning: implicit declaration of function `sigrelse' ./timemodule.c:413: warning: `/*' within comment ./timemodule.c: In function `time_strptime': ./timemodule.c:428: warning: implicit declaration of function `strptime' ./timemodule.c:428: warning: assignment makes pointer from integer without a cast ./mmapmodule.c: In function `new_mmap_object': ./mmapmodule.c:699: warning: unused variable `namelen' ./mmapmodule.c:698: warning: unused variable `filename' -- Marc-Andre Lemburg ______________________________________________________________________ Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ --------------962125C15898CA694E9D8F57 Content-Type: text/plain; charset=us-ascii; name="Unicode-Implementation-2000-04-05.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="Unicode-Implementation-2000-04-05.patch" diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.py CVS-Python/Include/Python.h Python+Unicode/Include/Python.h --- CVS-Python/Include/Python.h Sat Mar 11 10:52:34 2000 +++ Python+Unicode/Include/Python.h Mon Apr 3 13:18:05 2000 @@ -72,6 +72,7 @@ #include "pydebug.h" +#include "unicodeobject.h" #include "intobject.h" #include "longobject.h" #include "floatobject.h" @@ -92,7 +93,6 @@ #include "cobject.h" #include "traceback.h" #include "sliceobject.h" -#include "unicodeobject.h" #include "codecs.h" #include "pyerrors.h" diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.py CVS-Python/Include/intobject.h Python+Unicode/Include/intobject.h --- CVS-Python/Include/intobject.h Tue Mar 7 18:58:16 2000 +++ Python+Unicode/Include/intobject.h Mon Apr 3 12:54:35 2000 @@ -60,6 +60,7 @@ #define PyInt_Check(op) ((op)->ob_type == &PyInt_Type) extern DL_IMPORT(PyObject *) PyInt_FromString Py_PROTO((char*, char**, int)); +extern DL_IMPORT(PyObject *) PyInt_FromUnicode Py_PROTO((Py_UNICODE*, int, int)); extern DL_IMPORT(PyObject *) PyInt_FromLong Py_PROTO((long)); extern DL_IMPORT(long) PyInt_AsLong Py_PROTO((PyObject *)); extern DL_IMPORT(long) PyInt_GetMax Py_PROTO((void)); diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.py CVS-Python/Include/longobject.h Python+Unicode/Include/longobject.h --- CVS-Python/Include/longobject.h Thu Jan 14 11:24:51 1999 +++ Python+Unicode/Include/longobject.h Mon Apr 3 13:00:50 2000 @@ -82,6 +82,7 @@ #endif /* HAVE_LONG_LONG */ DL_IMPORT(PyObject *) PyLong_FromString Py_PROTO((char *, char **, int)); +DL_IMPORT(PyObject *) PyLong_FromUnicode Py_PROTO((Py_UNICODE*, int, int)); #ifdef __cplusplus } diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.py CVS-Python/Include/unicodeobject.h Python+Unicode/Include/unicodeobject.h --- CVS-Python/Include/unicodeobject.h Wed Mar 29 11:50:05 2000 +++ Python+Unicode/Include/unicodeobject.h Wed Apr 5 00:56:31 2000 @@ -358,7 +358,7 @@ /* --- UTF-16 Codecs ------------------------------------------------------ */ -/* Decodes length bytes from a UTF-16 encoded buffer string and return +/* Decodes length bytes from a UTF-16 encoded buffer string and returns the corresponding Unicode object. errors (if non-NULL) defines the error handling. It defaults @@ -397,7 +397,7 @@ ); /* Returns a Python string object holding the UTF-16 encoded value of - the Unicode data in s. + the Unicode data. If byteorder is not 0, output is written according to the following byte order: @@ -586,6 +586,37 @@ ); #endif /* MS_WIN32 */ + +/* --- Decimal Encoder ---------------------------------------------------- */ + +/* Takes a Unicode string holding a decimal value and writes it into + an output buffer using standard ASCII digit codes. + + The output buffer has to provide at least length+1 bytes of storage + area. The output string is 0-terminated. + + The encoder converts whitespace to ' ', decimal characters to their + corresponding ASCII digit and all other Latin-1 characters except + \0 as-is. Characters outside this range (Unicode ordinals 1-256) + are treated as errors. This includes embedded NULL bytes. + + Error handling is defined by the errors argument: + + NULL or "strict": raise a ValueError + "ignore": ignore the wrong characters (these are not copied to the + output buffer) + "replace": replaces illegal characters with '?' + + Returns 0 on success, -1 on failure. + +*/ + +extern DL_IMPORT(int) PyUnicode_EncodeDecimal( + Py_UNICODE *s, /* Unicode buffer */ + int length, /* Number of Py_UNICODE chars to encode */ + char *output, /* Output buffer; must have size >= length */ + const char *errors /* error handling */ + ); /* --- Methods & Slots ---------------------------------------------------- diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.py CVS-Python/Lib/test/output/test_unicode Python+Unicode/Lib/test/output/test_unicode --- CVS-Python/Lib/test/output/test_unicode Wed Mar 29 11:50:15 2000 +++ Python+Unicode/Lib/test/output/test_unicode Wed Apr 5 02:40:54 2000 @@ -3,3 +3,4 @@ Testing Unicode contains method... done. Testing Unicode formatting strings... done. Testing builtin codecs... done. +Testing standard mapping codecs... 0-127... 128-255... done. diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.py CVS-Python/Objects/abstract.c Python+Unicode/Objects/abstract.c --- CVS-Python/Objects/abstract.c Sat Mar 11 10:55:08 2000 +++ Python+Unicode/Objects/abstract.c Wed Apr 5 00:54:48 2000 @@ -726,6 +726,27 @@ return type_error("bad operand type for abs()"); } +/* Add a check for embedded NULL-bytes in the argument. */ +static PyObject * +int_from_string(s, len) + const char *s; + int len; +{ + char *end; + PyObject *x; + + x = PyInt_FromString((char*)s, &end, 10); + if (x == NULL) + return NULL; + if (end != s + len) { + PyErr_SetString(PyExc_ValueError, + "null byte in argument for int()"); + Py_DECREF(x); + return NULL; + } + return x; +} + PyObject * PyNumber_Int(o) PyObject *o; @@ -736,69 +757,42 @@ if (o == NULL) return null_error(); + if (PyInt_Check(o)) { + Py_INCREF(o); + return o; + } if (PyString_Check(o)) - return PyInt_FromString(PyString_AS_STRING(o), NULL, 10); + return int_from_string(PyString_AS_STRING(o), + PyString_GET_SIZE(o)); + if (PyUnicode_Check(o)) + return PyInt_FromUnicode(PyUnicode_AS_UNICODE(o), + PyUnicode_GET_SIZE(o), + 10); m = o->ob_type->tp_as_number; if (m && m->nb_int) return m->nb_int(o); if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len)) - return PyInt_FromString((char*)buffer, NULL, 10); + return int_from_string((char*)buffer, buffer_len); return type_error("object can't be converted to int"); } -/* There are two C API functions for converting a string to a long, - * PyNumber_Long() and PyLong_FromString(). Both are used in builtin_long, - * reachable from Python with the built-in function long(). - * - * The difference is this: PyNumber_Long will raise an exception when the - * string cannot be converted to a long. The most common situation is - * where a float string is passed in; this raises a ValueError. - * PyLong_FromString does not raise an exception; it silently truncates the - * float to an integer. - * - * You can see the different behavior from Python with the following: - * - * long('9.5') - * => ValueError: invalid literal for long(): 9.5 - * - * long('9.5', 10) - * => 9L - * - * The first example ends up calling PyNumber_Long(), while the second one - * calls PyLong_FromString(). - */ +/* Add a check for embedded NULL-bytes in the argument. */ static PyObject * long_from_string(s, len) const char *s; int len; { - const char *start; char *end; PyObject *x; - char buffer[256]; /* For errors */ - start = s; - while (*s && isspace(Py_CHARMASK(*s))) - s++; x = PyLong_FromString((char*)s, &end, 10); - if (x == NULL) { - if (PyErr_ExceptionMatches(PyExc_ValueError)) - goto bad; + if (x == NULL) return NULL; - } - while (*end && isspace(Py_CHARMASK(*end))) - end++; - if (*end != '\0') { - bad: - sprintf(buffer, "invalid literal for long(): %.200s", s); - PyErr_SetString(PyExc_ValueError, buffer); - Py_XDECREF(x); - return NULL; - } - else if (end != start + len) { + if (end != s + len) { PyErr_SetString(PyExc_ValueError, "null byte in argument for long()"); + Py_DECREF(x); return NULL; } return x; @@ -814,6 +808,10 @@ if (o == NULL) return null_error(); + if (PyLong_Check(o)) { + Py_INCREF(o); + return o; + } if (PyString_Check(o)) /* need to do extra error checking that PyLong_FromString() * doesn't do. In particular long('9.5') must raise an @@ -821,6 +819,11 @@ */ return long_from_string(PyString_AS_STRING(o), PyString_GET_SIZE(o)); + if (PyUnicode_Check(o)) + /* The above check is done in PyLong_FromUnicode(). */ + return PyLong_FromUnicode(PyUnicode_AS_UNICODE(o), + PyUnicode_GET_SIZE(o), + 10); m = o->ob_type->tp_as_number; if (m && m->nb_long) return m->nb_long(o); @@ -838,6 +841,10 @@ if (o == NULL) return null_error(); + if (PyFloat_Check(o)) { + Py_INCREF(o); + return o; + } if (!PyString_Check(o)) { m = o->ob_type->tp_as_number; if (m && m->nb_float) diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.py CVS-Python/Objects/floatobject.c Python+Unicode/Objects/floatobject.c --- CVS-Python/Objects/floatobject.c Sat Mar 11 10:55:08 2000 +++ Python+Unicode/Objects/floatobject.c Mon Apr 3 14:42:03 2000 @@ -163,6 +163,22 @@ if (PyString_Check(v)) { s = PyString_AS_STRING(v); len = PyString_GET_SIZE(v); + } + else if (PyUnicode_Check(v)) { + char s_buffer[256]; + + if (PyUnicode_GET_SIZE(v) >= sizeof(s_buffer)) { + PyErr_SetString(PyExc_ValueError, + "float() literal too large to convert"); + return NULL; + } + if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v), + PyUnicode_GET_SIZE(v), + s_buffer, + NULL)) + return NULL; + s = s_buffer; + len = strlen(s); } else if (PyObject_AsCharBuffer(v, &s, &len)) { PyErr_SetString(PyExc_TypeError, diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.py CVS-Python/Objects/intobject.c Python+Unicode/Objects/intobject.c --- CVS-Python/Objects/intobject.c Sat Mar 11 10:55:08 2000 +++ Python+Unicode/Objects/intobject.c Mon Apr 3 14:42:35 2000 @@ -259,6 +259,24 @@ if (pend) *pend = end; return PyInt_FromLong(x); +} + +PyObject * +PyInt_FromUnicode(s, length, base) + Py_UNICODE *s; + int length; + int base; +{ + char buffer[256]; + + if (length >= sizeof(buffer)) { + PyErr_SetString(PyExc_ValueError, + "int() literal too large to convert"); + return NULL; + } + if (PyUnicode_EncodeDecimal(s, length, buffer, NULL)) + return NULL; + return PyInt_FromString(buffer, NULL, base); } /* Methods */ diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.py CVS-Python/Objects/longobject.c Python+Unicode/Objects/longobject.c --- CVS-Python/Objects/longobject.c Wed Jan 19 18:01:30 2000 +++ Python+Unicode/Objects/longobject.c Wed Apr 5 01:15:23 2000 @@ -724,7 +724,7 @@ int base; { int sign = 1; - char *start; + char *start, *orig_str = str; PyLongObject *z; if ((base != 0 && base < 2) || base > 36) { @@ -772,17 +772,44 @@ } if (z == NULL) return NULL; - if (str == start) { - PyErr_SetString(PyExc_ValueError, - "no digits in long int constant"); - Py_DECREF(z); - return NULL; - } + if (str == start) + goto onError; if (sign < 0 && z != NULL && z->ob_size != 0) z->ob_size = -(z->ob_size); + if (*str == 'L' || *str == 'l') + str++; + while (*str && isspace(Py_CHARMASK(*str))) + str++; + if (*str != '\0') + goto onError; if (pend) *pend = str; return (PyObject *) z; + + onError: + PyErr_Format(PyExc_ValueError, + "invalid literal for long(): %.200s", orig_str); + Py_XDECREF(z); + return NULL; +} + +PyObject * +PyLong_FromUnicode(u, length, base) + Py_UNICODE *u; + int length; + int base; +{ + char buffer[256]; + + if (length >= sizeof(buffer)) { + PyErr_SetString(PyExc_ValueError, + "long() literal too large to convert"); + return NULL; + } + if (PyUnicode_EncodeDecimal(u, length, buffer, NULL)) + return NULL; + + return PyLong_FromString(buffer, NULL, base); } static PyLongObject *x_divrem diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.py CVS-Python/Objects/object.c Python+Unicode/Objects/object.c --- CVS-Python/Objects/object.c Tue Mar 28 09:19:17 2000 +++ Python+Unicode/Objects/object.c Mon Apr 3 23:17:04 2000 @@ -347,8 +347,21 @@ return cmp; } } - else if (PyUnicode_Check(v) || PyUnicode_Check(w)) - return PyUnicode_Compare(v, w); + else if (PyUnicode_Check(v) || PyUnicode_Check(w)) { + int result = PyUnicode_Compare(v, w); + if (result == -1 && PyErr_Occurred() && + PyErr_ExceptionMatches(PyExc_TypeError)) + /* TypeErrors are ignored: if Unicode coercion + fails due to one of the arguments not + having the right type, we continue as + defined by the coercion protocol (see + above). Luckily, decoding errors are + reported as ValueErrors and are not masked + by this technique. */ + PyErr_Clear(); + else + return result; + } else if (vtp->tp_as_number != NULL) vname = ""; else if (wtp->tp_as_number != NULL) diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.py CVS-Python/Objects/unicodeobject.c Python+Unicode/Objects/unicodeobject.c --- CVS-Python/Objects/unicodeobject.c Mon Apr 3 13:46:02 2000 +++ Python+Unicode/Objects/unicodeobject.c Wed Apr 5 01:08:15 2000 @@ -329,8 +329,14 @@ s = PyString_AS_STRING(obj); len = PyString_GET_SIZE(obj); } - else if (PyObject_AsCharBuffer(obj, &s, &len)) + else if (PyObject_AsCharBuffer(obj, &s, &len)) { + /* Overwrite the error message with something more useful in + case of a TypeError. */ + if (PyErr_ExceptionMatches(PyExc_TypeError)) + PyErr_SetString(PyExc_TypeError, + "coercing to Unicode: need string or charbuffer"); return NULL; + } if (len == 0) { Py_INCREF(unicode_empty); return (PyObject *)unicode_empty; @@ -1923,6 +1929,60 @@ return NULL; } +/* --- Decimal Encoder ---------------------------------------------------- */ + +int PyUnicode_EncodeDecimal(Py_UNICODE *s, + int length, + char *output, + const char *errors) +{ + Py_UNICODE *p, *end; + + if (output == NULL) { + PyErr_BadArgument(); + return -1; + } + + p = s; + end = s + length; + while (p < end) { + register Py_UNICODE ch = *p++; + int decimal; + + if (Py_UNICODE_ISSPACE(ch)) { + *output++ = ' '; + continue; + } + decimal = Py_UNICODE_TODECIMAL(ch); + if (decimal >= 0) { + *output++ = '0' + decimal; + continue; + } + if (0 < ch < 256) { + *output++ = ch; + continue; + } + /* All other characters are considered invalid */ + if (errors == NULL || strcmp(errors, "strict") == 0) { + PyErr_SetString(PyExc_ValueError, + "invalid decimal Unicode string"); + goto onError; + } + else if (strcmp(errors, "ignore") == 0) + continue; + else if (strcmp(errors, "replace") == 0) { + *output++ = '?'; + continue; + } + } + /* 0-terminate the output string */ + *output++ = '\0'; + return 0; + + onError: + return -1; +} + /* --- Helpers ------------------------------------------------------------ */ static @@ -2810,13 +2870,26 @@ register const Py_UNICODE *p, *e; register Py_UNICODE ch; - /* Coerce the two arguments */ + /* Coerce the two arguments; if coercion fails with a TypeError + this is not seen as error, but instead interpreted as not + having the containment property. */ u = (PyUnicodeObject *)PyUnicode_FromObject(container); - if (u == NULL) + if (u == NULL) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_Clear(); + return 0; + } goto onError; + } v = (PyUnicodeObject *)PyUnicode_FromObject(element); - if (v == NULL) + if (v == NULL) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_Clear(); + Py_DECREF(u); + return 0; + } goto onError; + } /* Check v in u */ if (PyUnicode_GET_SIZE(v) != 1) { diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.py CVS-Python/Python/bltinmodule.c Python+Unicode/Python/bltinmodule.c --- CVS-Python/Python/bltinmodule.c Sat Mar 11 10:55:20 2000 +++ Python+Unicode/Python/bltinmodule.c Mon Apr 3 16:14:02 2000 @@ -449,17 +449,44 @@ PyObject *v; { extern double strtod Py_PROTO((const char *, char **)); - char *s, *start, *end; + const char *s, *start; + char *end; double x=0.0, y=0.0, z; int got_re=0, got_im=0, done=0; int digit_or_dot; int sw_error=0; int sign; char buffer[256]; /* For errors */ + int len; - start = s = PyString_AS_STRING(v); + if (PyString_Check(v)) { + s = PyString_AS_STRING(v); + len = PyString_GET_SIZE(v); + } + else if (PyUnicode_Check(v)) { + char s_buffer[256]; + + if (PyUnicode_GET_SIZE(v) >= sizeof(s_buffer)) { + PyErr_SetString(PyExc_ValueError, + "complex() literal too large to convert"); + return NULL; + } + if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v), + PyUnicode_GET_SIZE(v), + s_buffer, + NULL)) + return NULL; + s = s_buffer; + len = strlen(s); + } + else if (PyObject_AsCharBuffer(v, &s, &len)) { + PyErr_SetString(PyExc_TypeError, + "complex() needs a string first argument"); + return NULL; + } /* position on first nonblank */ + start = s; while (*s && isspace(Py_CHARMASK(*s))) s++; if (s[0] == '\0') { @@ -475,7 +502,7 @@ switch (*s) { case '\0': - if (s-start != PyString_GET_SIZE(v)) { + if (s-start != len) { PyErr_SetString( PyExc_ValueError, "null byte in argument for complex()"); @@ -584,7 +611,7 @@ i = NULL; if (!PyArg_ParseTuple(args, "O|O:complex", &r, &i)) return NULL; - if (PyString_Check(r)) + if (PyString_Check(r) || PyUnicode_Check(r)) return complex_from_string(r); if ((nbr = r->ob_type->tp_as_number) == NULL || nbr->nb_float == NULL || @@ -1289,12 +1316,17 @@ return NULL; if (base == -909) return PyNumber_Int(v); - else if (!PyString_Check(v)) { + else if (PyString_Check(v)) + return PyInt_FromString(PyString_AS_STRING(v), NULL, base); + else if (PyUnicode_Check(v)) + return PyInt_FromUnicode(PyUnicode_AS_UNICODE(v), + PyUnicode_GET_SIZE(v), + base); + else { PyErr_SetString(PyExc_TypeError, "can't convert non-string with explicit base"); return NULL; } - return PyInt_FromString(PyString_AS_STRING(v), NULL, base); } static char int_doc[] = @@ -1319,12 +1351,17 @@ return NULL; if (base == -909) return PyNumber_Long(v); - else if (!PyString_Check(v)) { + else if (PyString_Check(v)) + return PyLong_FromString(PyString_AS_STRING(v), NULL, base); + else if (PyUnicode_Check(v)) + return PyLong_FromUnicode(PyUnicode_AS_UNICODE(v), + PyUnicode_GET_SIZE(v), + base); + else { PyErr_SetString(PyExc_TypeError, "can't convert non-string with explicit base"); return NULL; } - return PyLong_FromString(PyString_AS_STRING(v), NULL, base); } static char long_doc[] = diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.py CVS-Python/Python/codecs.c Python+Unicode/Python/codecs.c --- CVS-Python/Python/codecs.c Mon Apr 3 13:46:03 2000 +++ Python+Unicode/Python/codecs.c Sat Apr 1 19:57:52 2000 @@ -84,8 +84,11 @@ return -1; } +/* Convert a string to a normalized Python string: all characters are + converted to lower case, spaces are replaced with underscores. */ + static -PyObject *lowercasestring(const char *string) +PyObject *normalizestring(const char *string) { register int i; int len = strlen(string); @@ -96,8 +99,14 @@ if (v == NULL) return NULL; p = PyString_AS_STRING(v); - for (i = 0; i < len; i++) - p[i] = tolower(string[i]); + for (i = 0; i < len; i++) { + register char ch = string[i]; + if (ch == ' ') + ch = '-'; + else + ch = tolower(ch); + p[i] = ch; + } return v; } @@ -132,8 +141,10 @@ goto onError; } - /* Convert the encoding to a lower-cased Python string */ - v = lowercasestring(encoding); + /* Convert the encoding to a normalized Python string: all + characters are converted to lower case, spaces and hypens are + replaced with underscores. */ + v = normalizestring(encoding); if (v == NULL) goto onError; PyString_InternInPlace(&v); diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.c -x *.h -x *.in -x output CVS-Python/Lib/encodings/__init__.py Python+Unicode/Lib/encodings/__init__.py --- CVS-Python/Lib/encodings/__init__.py Thu Mar 23 23:58:42 2000 +++ Python+Unicode/Lib/encodings/__init__.py Mon Apr 3 13:41:40 2000 @@ -4,8 +4,8 @@ directory. Codec modules must have names corresponding to standard lower-case - encoding names. Hyphens are automatically converted to - underscores, e.g. 'utf-8' is looked up as module utf_8. + encoding names with hyphens mapped to underscores, e.g. 'utf-8' is + implemented by the module 'utf_8.py'. Each codec module must export the following interface: @@ -40,7 +40,7 @@ return entry # Import the module - modname = string.replace(encoding,'-','_') + modname = string.replace(encoding, '-', '_') modname = aliases.aliases.get(modname,modname) try: mod = __import__(modname,globals(),locals(),'*') diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.c -x *.h -x *.in -x output CVS-Python/Lib/encodings/aliases.py Python+Unicode/Lib/encodings/aliases.py --- CVS-Python/Lib/encodings/aliases.py Mon Apr 3 13:45:48 2000 +++ Python+Unicode/Lib/encodings/aliases.py Sat Apr 1 20:14:36 2000 @@ -54,4 +54,7 @@ 'macroman': 'mac_roman', 'macturkish': 'mac_turkish', + # MBCS + 'dbcs': 'mbcs', + } diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.c -x *.h -x *.in -x output CVS-Python/Lib/string.py Python+Unicode/Lib/string.py --- CVS-Python/Lib/string.py Sat Mar 11 10:52:36 2000 +++ Python+Unicode/Lib/string.py Wed Apr 5 00:24:43 2000 @@ -196,14 +196,11 @@ Return the floating point number represented by the string s. """ - if type(s) == _StringType: - return _float(s) - else: - raise TypeError('argument 1: expected string, %s found' % - type(s).__name__) + return _float(s) + # Convert string to integer -def atoi(*args): +def atoi(s , base=10): """atoi(s [,base]) -> int Return the integer represented by the string s in the given @@ -214,23 +211,11 @@ accepted. """ - try: - s = args[0] - except IndexError: - raise TypeError('function requires at least 1 argument: %d given' % - len(args)) - # Don't catch type error resulting from too many arguments to int(). The - # error message isn't compatible but the error type is, and this function - # is complicated enough already. - if type(s) == _StringType: - return _apply(_int, args) - else: - raise TypeError('argument 1: expected string, %s found' % - type(s).__name__) + return _int(s, base) # Convert string to long integer -def atol(*args): +def atol(s, base=10): """atol(s [,base]) -> long Return the long integer represented by the string s in the @@ -242,19 +227,7 @@ unless base is 0. """ - try: - s = args[0] - except IndexError: - raise TypeError('function requires at least 1 argument: %d given' % - len(args)) - # Don't catch type error resulting from too many arguments to long(). The - # error message isn't compatible but the error type is, and this function - # is complicated enough already. - if type(s) == _StringType: - return _apply(_long, args) - else: - raise TypeError('argument 1: expected string, %s found' % - type(s).__name__) + return _long(s, base) # Left-justify a string diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.c -x *.h -x *.in -x output CVS-Python/Lib/test/test_b1.py Python+Unicode/Lib/test/test_b1.py --- CVS-Python/Lib/test/test_b1.py Fri Mar 26 15:58:20 1999 +++ Python+Unicode/Lib/test/test_b1.py Wed Apr 5 01:11:33 2000 @@ -95,6 +95,7 @@ if complex(0j, 3.14) <> 3.14j: raise TestFailed, 'complex(0j, 3.14)' if complex(0.0, 3.14) <> 3.14j: raise TestFailed, 'complex(0.0, 3.14)' if complex(" 3.14+J ") <> 3.14+1j: raise TestFailed, 'complex(" 3.14+J )"' +if complex(u" 3.14+J ") <> 3.14+1j: raise TestFailed, 'complex(u" 3.14+J )"' class Z: def __complex__(self): return 3.14j z = Z() @@ -208,6 +209,9 @@ if float(314) <> 314.0: raise TestFailed, 'float(314)' if float(314L) <> 314.0: raise TestFailed, 'float(314L)' if float(" 3.14 ") <> 3.14: raise TestFailed, 'float(" 3.14 ")' +if float(u" 3.14 ") <> 3.14: raise TestFailed, 'float(u" 3.14 ")' +if float(u" \u0663.\u0661\u0664 ") <> 3.14: + raise TestFailed, 'float(u" \u0663.\u0661\u0664 ")' print 'getattr' import sys @@ -254,6 +258,9 @@ if int(-3.9) <> -3: raise TestFailed, 'int(-3.9)' if int(3.5) <> 3: raise TestFailed, 'int(3.5)' if int(-3.5) <> -3: raise TestFailed, 'int(-3.5)' +# Different base: +if int("10",16) <> 16L: raise TestFailed, 'int("10",16)' +if int(u"10",16) <> 16L: raise TestFailed, 'int(u"10",16)' # Test conversion fron strings and various anomalies L = [ ('0', 0), @@ -267,9 +274,28 @@ ('314 ', 314), (' \t\t 314 \t\t ', 314), (`sys.maxint`, sys.maxint), + (' 1x', ValueError), + (' 1 ', 1), + (' 1\02 ', ValueError), ('', ValueError), (' ', ValueError), (' \t\t ', ValueError), + (u'0', 0), + (u'1', 1), + (u'9', 9), + (u'10', 10), + (u'99', 99), + (u'100', 100), + (u'314', 314), + (u' 314', 314), + (u'\u0663\u0661\u0664 ', 314), + (u' \t\t 314 \t\t ', 314), + (u' 1x', ValueError), + (u' 1 ', 1), + (u' 1\02 ', ValueError), + (u'', ValueError), + (u' ', ValueError), + (u' \t\t ', ValueError), ] for s, v in L: for sign in "", "+", "-": @@ -349,10 +375,17 @@ if long(-3.9) <> -3L: raise TestFailed, 'long(-3.9)' if long(3.5) <> 3L: raise TestFailed, 'long(3.5)' if long(-3.5) <> -3L: raise TestFailed, 'long(-3.5)' +if long("-3") <> -3L: raise TestFailed, 'long("-3")' +if long(u"-3") <> -3L: raise TestFailed, 'long(u"-3")' +# Different base: +if long("10",16) <> 16L: raise TestFailed, 'long("10",16)' +if long(u"10",16) <> 16L: raise TestFailed, 'long(u"10",16)' # Check conversions from string (same test set as for int(), and then some) LL = [ ('1' + '0'*20, 10L**20), ('1' + '0'*100, 10L**100), + (u'1' + u'0'*20, 10L**20), + (u'1' + u'0'*100, 10L**100), ] for s, v in L + LL: for sign in "", "+", "-": @@ -363,11 +396,11 @@ vv = -v try: if long(ss) != long(vv): - raise TestFailed, "int(%s)" % `ss` + raise TestFailed, "long(%s)" % `ss` except v: pass except ValueError, e: - raise TestFailed, "int(%s) raised ValueError: %s" % (`ss`, e) + raise TestFailed, "long(%s) raised ValueError: %s" % (`ss`, e) print 'map' if map(None, 'hello world') <> ['h','e','l','l','o',' ','w','o','r','l','d']: diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.c -x *.h -x *.in -x output CVS-Python/Lib/test/test_unicode.py Python+Unicode/Lib/test/test_unicode.py --- CVS-Python/Lib/test/test_unicode.py Wed Mar 29 11:50:14 2000 +++ Python+Unicode/Lib/test/test_unicode.py Mon Apr 3 23:06:27 2000 @@ -221,15 +221,23 @@ # Contains: print 'Testing Unicode contains method...', -assert ('a' in 'abdb') == 1 -assert ('a' in 'bdab') == 1 -assert ('a' in 'bdaba') == 1 -assert ('a' in 'bdba') == 1 +assert ('a' in u'abdb') == 1 +assert ('a' in u'bdab') == 1 +assert ('a' in u'bdaba') == 1 +assert ('a' in u'bdba') == 1 assert ('a' in u'bdba') == 1 assert (u'a' in u'bdba') == 1 assert (u'a' in u'bdb') == 0 assert (u'a' in 'bdb') == 0 assert (u'a' in 'bdba') == 1 +assert (u'a' in ('a',1,None)) == 1 +assert (u'a' in (1,None,'a')) == 1 +assert (u'a' in (1,None,u'a')) == 1 +assert ('a' in ('a',1,None)) == 1 +assert ('a' in (1,None,'a')) == 1 +assert ('a' in (1,None,u'a')) == 1 +assert ('a' in ('x',1,u'y')) == 0 +assert ('a' in ('x',1,None)) == 0 print 'done.' # Formatting: @@ -270,11 +278,88 @@ assert unicode(u.encode(encoding),encoding) == u u = u''.join(map(unichr, range(256))) -for encoding in ('latin-1',): - assert unicode(u.encode(encoding),encoding) == u +for encoding in ( + 'latin-1', + ): + try: + assert unicode(u.encode(encoding),encoding) == u + except AssertionError: + print '*** codec "%s" failed round-trip' % encoding + except ValueError,why: + print '*** codec for "%s" failed: %s' % (encoding, why) u = u''.join(map(unichr, range(128))) -for encoding in ('ascii',): - assert unicode(u.encode(encoding),encoding) == u +for encoding in ( + 'ascii', + ): + try: + assert unicode(u.encode(encoding),encoding) == u + except AssertionError: + print '*** codec "%s" failed round-trip' % encoding + except ValueError,why: + print '*** codec for "%s" failed: %s' % (encoding, why) + +print 'done.' + +print 'Testing standard mapping codecs...', + +print '0-127...', +s = ''.join(map(chr, range(128))) +for encoding in ( + 'cp037', 'cp1026', + 'cp437', 'cp500', 'cp737', 'cp775', 'cp850', + 'cp852', 'cp855', 'cp860', 'cp861', 'cp862', + 'cp863', 'cp865', 'cp866', + 'iso8859_10', 'iso8859_13', 'iso8859_14', 'iso8859_15', + 'iso8859_2', 'iso8859_3', 'iso8859_4', 'iso8859_5', 'iso8859_6', + 'iso8859_7', 'iso8859_9', 'koi8_r', 'latin_1', + 'mac_cyrillic', 'mac_latin2', + + 'cp1250', 'cp1251', 'cp1252', 'cp1253', 'cp1254', 'cp1255', + 'cp1256', 'cp1257', 'cp1258', + 'cp856', 'cp857', 'cp864', 'cp869', 'cp874', + + 'mac_greek', 'mac_iceland','mac_roman', 'mac_turkish', + 'cp1006', 'cp875', 'iso8859_8', + + ### These have undefined mappings: + #'cp424', + + ): + try: + assert unicode(s,encoding).encode(encoding) == s + except AssertionError: + print '*** codec "%s" failed round-trip' % encoding + except ValueError,why: + print '*** codec for "%s" failed: %s' % (encoding, why) + +print '128-255...', +s = ''.join(map(chr, range(128,256))) +for encoding in ( + 'cp037', 'cp1026', + 'cp437', 'cp500', 'cp737', 'cp775', 'cp850', + 'cp852', 'cp855', 'cp860', 'cp861', 'cp862', + 'cp863', 'cp865', 'cp866', + 'iso8859_10', 'iso8859_13', 'iso8859_14', 'iso8859_15', + 'iso8859_2', 'iso8859_3', 'iso8859_4', 'iso8859_5', 'iso8859_6', + 'iso8859_7', 'iso8859_9', 'koi8_r', 'latin_1', + 'mac_cyrillic', 'mac_latin2', + + ### These have undefined mappings: + #'cp1250', 'cp1251', 'cp1252', 'cp1253', 'cp1254', 'cp1255', + #'cp1256', 'cp1257', 'cp1258', + #'cp424', 'cp856', 'cp857', 'cp864', 'cp869', 'cp874', + #'mac_greek', 'mac_iceland','mac_roman', 'mac_turkish', + + ### These fail the round-trip: + #'cp1006', 'cp875', 'iso8859_8', + + ): + try: + assert unicode(s,encoding).encode(encoding) == s + except AssertionError: + print '*** codec "%s" failed round-trip' % encoding + except ValueError,why: + print '*** codec for "%s" failed: %s' % (encoding, why) print 'done.' Only in CVS-Python/Lib/test: test_userstring.py --------------962125C15898CA694E9D8F57-- From guido@python.org Wed Apr 5 02:20:24 2000 From: guido@python.org (Guido van Rossum) Date: Tue, 04 Apr 2000 21:20:24 -0400 Subject: [Patches] Unicode Patch Set 2000-04-05 In-Reply-To: Your message of "Wed, 05 Apr 2000 02:53:10 +0200." <38EA8E76.66359797@lemburg.com> References: <38EA8E76.66359797@lemburg.com> Message-ID: <200004050120.VAA15817@eric.cnri.reston.va.us> Much better, except: > - contains now works for non-string types too; TypeErrors are > masked and 0 returned; all other errors are passed through This breaks a test in test_contains.py: (None in 'abc') should raise an TypeError, but doesn't. I noticed that any non-string left argument is now okay. This is not according to spec... --Guido van Rossum (home page: http://www.python.org/~guido/) From nascheme@enme.ucalgary.ca Wed Apr 5 09:50:38 2000 From: nascheme@enme.ucalgary.ca (Neil Schemenauer) Date: Wed, 5 Apr 2000 02:50:38 -0600 Subject: [Patches] portable garbage collection for Python Message-ID: <20000405025037.B16978@acs.ucalgary.ca> I have a new version of my garbage collection patch available. If you have time please test it out and send me comments. The patch against the current CVS version of Python is available from: http://www.enme.ucalgary.ca/~nascheme/python/gc-cycle.diff I will give some more details on my approach tomorrow after I get some rest. :) Neil -- Real programmers don't make mistrakes From mal@lemburg.com Wed Apr 5 10:50:21 2000 From: mal@lemburg.com (M.-A. Lemburg) Date: Wed, 05 Apr 2000 11:50:21 +0200 Subject: [Patches] Unicode Patch Set 2000-04-05 References: <38EA8E76.66359797@lemburg.com> <200004050120.VAA15817@eric.cnri.reston.va.us> Message-ID: <38EB0C5D.72253EE6@lemburg.com> This is a multi-part message in MIME format. --------------ADCA470C18D9DED714E274DB Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Guido van Rossum wrote: > > Much better, except: > > > - contains now works for non-string types too; TypeErrors are > > masked and 0 returned; all other errors are passed through > > This breaks a test in test_contains.py: (None in 'abc') should raise > an TypeError, but doesn't. I noticed that any non-string left > argument is now okay. This is not according to spec... Looks like I've gone a step too far there... (and test_contains.py seem to have a bug too). I've changed back to reporting all errors in PyUnicode_Contains() and added a few more test cases to test_contains.py (plus corrected the join() NameError). -- Marc-Andre Lemburg ______________________________________________________________________ Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ --------------ADCA470C18D9DED714E274DB Content-Type: text/plain; charset=us-ascii; name="Unicode-Implementation-2000-04-05.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="Unicode-Implementation-2000-04-05.patch" diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.py CVS-Python/Include/Python.h Python+Unicode/Include/Python.h --- CVS-Python/Include/Python.h Sat Mar 11 10:52:34 2000 +++ Python+Unicode/Include/Python.h Wed Apr 5 02:44:28 2000 @@ -72,6 +72,7 @@ #include "pydebug.h" +#include "unicodeobject.h" #include "intobject.h" #include "longobject.h" #include "floatobject.h" @@ -92,7 +93,6 @@ #include "cobject.h" #include "traceback.h" #include "sliceobject.h" -#include "unicodeobject.h" #include "codecs.h" #include "pyerrors.h" diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.py CVS-Python/Include/intobject.h Python+Unicode/Include/intobject.h --- CVS-Python/Include/intobject.h Tue Mar 7 18:58:16 2000 +++ Python+Unicode/Include/intobject.h Wed Apr 5 02:44:28 2000 @@ -60,6 +60,7 @@ #define PyInt_Check(op) ((op)->ob_type == &PyInt_Type) extern DL_IMPORT(PyObject *) PyInt_FromString Py_PROTO((char*, char**, int)); +extern DL_IMPORT(PyObject *) PyInt_FromUnicode Py_PROTO((Py_UNICODE*, int, int)); extern DL_IMPORT(PyObject *) PyInt_FromLong Py_PROTO((long)); extern DL_IMPORT(long) PyInt_AsLong Py_PROTO((PyObject *)); extern DL_IMPORT(long) PyInt_GetMax Py_PROTO((void)); diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.py CVS-Python/Include/longobject.h Python+Unicode/Include/longobject.h --- CVS-Python/Include/longobject.h Thu Jan 14 11:24:51 1999 +++ Python+Unicode/Include/longobject.h Wed Apr 5 02:44:28 2000 @@ -82,6 +82,7 @@ #endif /* HAVE_LONG_LONG */ DL_IMPORT(PyObject *) PyLong_FromString Py_PROTO((char *, char **, int)); +DL_IMPORT(PyObject *) PyLong_FromUnicode Py_PROTO((Py_UNICODE*, int, int)); #ifdef __cplusplus } diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.py CVS-Python/Include/unicodeobject.h Python+Unicode/Include/unicodeobject.h --- CVS-Python/Include/unicodeobject.h Wed Mar 29 11:50:05 2000 +++ Python+Unicode/Include/unicodeobject.h Wed Apr 5 02:44:28 2000 @@ -358,7 +358,7 @@ /* --- UTF-16 Codecs ------------------------------------------------------ */ -/* Decodes length bytes from a UTF-16 encoded buffer string and return +/* Decodes length bytes from a UTF-16 encoded buffer string and returns the corresponding Unicode object. errors (if non-NULL) defines the error handling. It defaults @@ -397,7 +397,7 @@ ); /* Returns a Python string object holding the UTF-16 encoded value of - the Unicode data in s. + the Unicode data. If byteorder is not 0, output is written according to the following byte order: @@ -586,6 +586,37 @@ ); #endif /* MS_WIN32 */ + +/* --- Decimal Encoder ---------------------------------------------------- */ + +/* Takes a Unicode string holding a decimal value and writes it into + an output buffer using standard ASCII digit codes. + + The output buffer has to provide at least length+1 bytes of storage + area. The output string is 0-terminated. + + The encoder converts whitespace to ' ', decimal characters to their + corresponding ASCII digit and all other Latin-1 characters except + \0 as-is. Characters outside this range (Unicode ordinals 1-256) + are treated as errors. This includes embedded NULL bytes. + + Error handling is defined by the errors argument: + + NULL or "strict": raise a ValueError + "ignore": ignore the wrong characters (these are not copied to the + output buffer) + "replace": replaces illegal characters with '?' + + Returns 0 on success, -1 on failure. + +*/ + +extern DL_IMPORT(int) PyUnicode_EncodeDecimal( + Py_UNICODE *s, /* Unicode buffer */ + int length, /* Number of Py_UNICODE chars to encode */ + char *output, /* Output buffer; must have size >= length */ + const char *errors /* error handling */ + ); /* --- Methods & Slots ---------------------------------------------------- diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.py CVS-Python/Lib/test/output/test_unicode Python+Unicode/Lib/test/output/test_unicode --- CVS-Python/Lib/test/output/test_unicode Wed Mar 29 11:50:15 2000 +++ Python+Unicode/Lib/test/output/test_unicode Wed Apr 5 11:25:24 2000 @@ -3,3 +3,4 @@ Testing Unicode contains method... done. Testing Unicode formatting strings... done. Testing builtin codecs... done. +Testing standard mapping codecs... 0-127... 128-255... done. diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.py CVS-Python/Objects/abstract.c Python+Unicode/Objects/abstract.c --- CVS-Python/Objects/abstract.c Sat Mar 11 10:55:08 2000 +++ Python+Unicode/Objects/abstract.c Wed Apr 5 02:44:28 2000 @@ -726,6 +726,27 @@ return type_error("bad operand type for abs()"); } +/* Add a check for embedded NULL-bytes in the argument. */ +static PyObject * +int_from_string(s, len) + const char *s; + int len; +{ + char *end; + PyObject *x; + + x = PyInt_FromString((char*)s, &end, 10); + if (x == NULL) + return NULL; + if (end != s + len) { + PyErr_SetString(PyExc_ValueError, + "null byte in argument for int()"); + Py_DECREF(x); + return NULL; + } + return x; +} + PyObject * PyNumber_Int(o) PyObject *o; @@ -736,69 +757,42 @@ if (o == NULL) return null_error(); + if (PyInt_Check(o)) { + Py_INCREF(o); + return o; + } if (PyString_Check(o)) - return PyInt_FromString(PyString_AS_STRING(o), NULL, 10); + return int_from_string(PyString_AS_STRING(o), + PyString_GET_SIZE(o)); + if (PyUnicode_Check(o)) + return PyInt_FromUnicode(PyUnicode_AS_UNICODE(o), + PyUnicode_GET_SIZE(o), + 10); m = o->ob_type->tp_as_number; if (m && m->nb_int) return m->nb_int(o); if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len)) - return PyInt_FromString((char*)buffer, NULL, 10); + return int_from_string((char*)buffer, buffer_len); return type_error("object can't be converted to int"); } -/* There are two C API functions for converting a string to a long, - * PyNumber_Long() and PyLong_FromString(). Both are used in builtin_long, - * reachable from Python with the built-in function long(). - * - * The difference is this: PyNumber_Long will raise an exception when the - * string cannot be converted to a long. The most common situation is - * where a float string is passed in; this raises a ValueError. - * PyLong_FromString does not raise an exception; it silently truncates the - * float to an integer. - * - * You can see the different behavior from Python with the following: - * - * long('9.5') - * => ValueError: invalid literal for long(): 9.5 - * - * long('9.5', 10) - * => 9L - * - * The first example ends up calling PyNumber_Long(), while the second one - * calls PyLong_FromString(). - */ +/* Add a check for embedded NULL-bytes in the argument. */ static PyObject * long_from_string(s, len) const char *s; int len; { - const char *start; char *end; PyObject *x; - char buffer[256]; /* For errors */ - start = s; - while (*s && isspace(Py_CHARMASK(*s))) - s++; x = PyLong_FromString((char*)s, &end, 10); - if (x == NULL) { - if (PyErr_ExceptionMatches(PyExc_ValueError)) - goto bad; + if (x == NULL) return NULL; - } - while (*end && isspace(Py_CHARMASK(*end))) - end++; - if (*end != '\0') { - bad: - sprintf(buffer, "invalid literal for long(): %.200s", s); - PyErr_SetString(PyExc_ValueError, buffer); - Py_XDECREF(x); - return NULL; - } - else if (end != start + len) { + if (end != s + len) { PyErr_SetString(PyExc_ValueError, "null byte in argument for long()"); + Py_DECREF(x); return NULL; } return x; @@ -814,6 +808,10 @@ if (o == NULL) return null_error(); + if (PyLong_Check(o)) { + Py_INCREF(o); + return o; + } if (PyString_Check(o)) /* need to do extra error checking that PyLong_FromString() * doesn't do. In particular long('9.5') must raise an @@ -821,6 +819,11 @@ */ return long_from_string(PyString_AS_STRING(o), PyString_GET_SIZE(o)); + if (PyUnicode_Check(o)) + /* The above check is done in PyLong_FromUnicode(). */ + return PyLong_FromUnicode(PyUnicode_AS_UNICODE(o), + PyUnicode_GET_SIZE(o), + 10); m = o->ob_type->tp_as_number; if (m && m->nb_long) return m->nb_long(o); @@ -838,6 +841,10 @@ if (o == NULL) return null_error(); + if (PyFloat_Check(o)) { + Py_INCREF(o); + return o; + } if (!PyString_Check(o)) { m = o->ob_type->tp_as_number; if (m && m->nb_float) diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.py CVS-Python/Objects/floatobject.c Python+Unicode/Objects/floatobject.c --- CVS-Python/Objects/floatobject.c Sat Mar 11 10:55:08 2000 +++ Python+Unicode/Objects/floatobject.c Wed Apr 5 02:44:28 2000 @@ -164,6 +164,22 @@ s = PyString_AS_STRING(v); len = PyString_GET_SIZE(v); } + else if (PyUnicode_Check(v)) { + char s_buffer[256]; + + if (PyUnicode_GET_SIZE(v) >= sizeof(s_buffer)) { + PyErr_SetString(PyExc_ValueError, + "float() literal too large to convert"); + return NULL; + } + if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v), + PyUnicode_GET_SIZE(v), + s_buffer, + NULL)) + return NULL; + s = s_buffer; + len = strlen(s); + } else if (PyObject_AsCharBuffer(v, &s, &len)) { PyErr_SetString(PyExc_TypeError, "float() needs a string argument"); diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.py CVS-Python/Objects/intobject.c Python+Unicode/Objects/intobject.c --- CVS-Python/Objects/intobject.c Sat Mar 11 10:55:08 2000 +++ Python+Unicode/Objects/intobject.c Wed Apr 5 02:44:28 2000 @@ -261,6 +261,24 @@ return PyInt_FromLong(x); } +PyObject * +PyInt_FromUnicode(s, length, base) + Py_UNICODE *s; + int length; + int base; +{ + char buffer[256]; + + if (length >= sizeof(buffer)) { + PyErr_SetString(PyExc_ValueError, + "int() literal too large to convert"); + return NULL; + } + if (PyUnicode_EncodeDecimal(s, length, buffer, NULL)) + return NULL; + return PyInt_FromString(buffer, NULL, base); +} + /* Methods */ /* ARGSUSED */ diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.py CVS-Python/Objects/longobject.c Python+Unicode/Objects/longobject.c --- CVS-Python/Objects/longobject.c Wed Jan 19 18:01:30 2000 +++ Python+Unicode/Objects/longobject.c Wed Apr 5 02:44:28 2000 @@ -724,7 +724,7 @@ int base; { int sign = 1; - char *start; + char *start, *orig_str = str; PyLongObject *z; if ((base != 0 && base < 2) || base > 36) { @@ -772,17 +772,44 @@ } if (z == NULL) return NULL; - if (str == start) { - PyErr_SetString(PyExc_ValueError, - "no digits in long int constant"); - Py_DECREF(z); - return NULL; - } + if (str == start) + goto onError; if (sign < 0 && z != NULL && z->ob_size != 0) z->ob_size = -(z->ob_size); + if (*str == 'L' || *str == 'l') + str++; + while (*str && isspace(Py_CHARMASK(*str))) + str++; + if (*str != '\0') + goto onError; if (pend) *pend = str; return (PyObject *) z; + + onError: + PyErr_Format(PyExc_ValueError, + "invalid literal for long(): %.200s", orig_str); + Py_XDECREF(z); + return NULL; +} + +PyObject * +PyLong_FromUnicode(u, length, base) + Py_UNICODE *u; + int length; + int base; +{ + char buffer[256]; + + if (length >= sizeof(buffer)) { + PyErr_SetString(PyExc_ValueError, + "long() literal too large to convert"); + return NULL; + } + if (PyUnicode_EncodeDecimal(u, length, buffer, NULL)) + return NULL; + + return PyLong_FromString(buffer, NULL, base); } static PyLongObject *x_divrem diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.py CVS-Python/Objects/object.c Python+Unicode/Objects/object.c --- CVS-Python/Objects/object.c Tue Mar 28 09:19:17 2000 +++ Python+Unicode/Objects/object.c Wed Apr 5 02:44:28 2000 @@ -347,8 +347,21 @@ return cmp; } } - else if (PyUnicode_Check(v) || PyUnicode_Check(w)) - return PyUnicode_Compare(v, w); + else if (PyUnicode_Check(v) || PyUnicode_Check(w)) { + int result = PyUnicode_Compare(v, w); + if (result == -1 && PyErr_Occurred() && + PyErr_ExceptionMatches(PyExc_TypeError)) + /* TypeErrors are ignored: if Unicode coercion + fails due to one of the arguments not + having the right type, we continue as + defined by the coercion protocol (see + above). Luckily, decoding errors are + reported as ValueErrors and are not masked + by this technique. */ + PyErr_Clear(); + else + return result; + } else if (vtp->tp_as_number != NULL) vname = ""; else if (wtp->tp_as_number != NULL) diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.py CVS-Python/Objects/unicodeobject.c Python+Unicode/Objects/unicodeobject.c --- CVS-Python/Objects/unicodeobject.c Mon Apr 3 13:46:02 2000 +++ Python+Unicode/Objects/unicodeobject.c Wed Apr 5 11:18:57 2000 @@ -329,8 +329,14 @@ s = PyString_AS_STRING(obj); len = PyString_GET_SIZE(obj); } - else if (PyObject_AsCharBuffer(obj, &s, &len)) + else if (PyObject_AsCharBuffer(obj, &s, &len)) { + /* Overwrite the error message with something more useful in + case of a TypeError. */ + if (PyErr_ExceptionMatches(PyExc_TypeError)) + PyErr_SetString(PyExc_TypeError, + "coercing to Unicode: need string or charbuffer"); return NULL; + } if (len == 0) { Py_INCREF(unicode_empty); return (PyObject *)unicode_empty; @@ -1923,6 +1929,60 @@ return NULL; } +/* --- Decimal Encoder ---------------------------------------------------- */ + +int PyUnicode_EncodeDecimal(Py_UNICODE *s, + int length, + char *output, + const char *errors) +{ + Py_UNICODE *p, *end; + + if (output == NULL) { + PyErr_BadArgument(); + return -1; + } + + p = s; + end = s + length; + while (p < end) { + register Py_UNICODE ch = *p++; + int decimal; + + if (Py_UNICODE_ISSPACE(ch)) { + *output++ = ' '; + continue; + } + decimal = Py_UNICODE_TODECIMAL(ch); + if (decimal >= 0) { + *output++ = '0' + decimal; + continue; + } + if (0 < ch < 256) { + *output++ = ch; + continue; + } + /* All other characters are considered invalid */ + if (errors == NULL || strcmp(errors, "strict") == 0) { + PyErr_SetString(PyExc_ValueError, + "invalid decimal Unicode string"); + goto onError; + } + else if (strcmp(errors, "ignore") == 0) + continue; + else if (strcmp(errors, "replace") == 0) { + *output++ = '?'; + continue; + } + } + /* 0-terminate the output string */ + *output++ = '\0'; + return 0; + + onError: + return -1; +} + /* --- Helpers ------------------------------------------------------------ */ static @@ -2811,12 +2871,14 @@ register Py_UNICODE ch; /* Coerce the two arguments */ - u = (PyUnicodeObject *)PyUnicode_FromObject(container); - if (u == NULL) - goto onError; v = (PyUnicodeObject *)PyUnicode_FromObject(element); if (v == NULL) goto onError; + u = (PyUnicodeObject *)PyUnicode_FromObject(container); + if (u == NULL) { + Py_DECREF(v); + goto onError; + } /* Check v in u */ if (PyUnicode_GET_SIZE(v) != 1) { diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.py CVS-Python/Python/bltinmodule.c Python+Unicode/Python/bltinmodule.c --- CVS-Python/Python/bltinmodule.c Sat Mar 11 10:55:20 2000 +++ Python+Unicode/Python/bltinmodule.c Wed Apr 5 02:44:28 2000 @@ -449,17 +449,44 @@ PyObject *v; { extern double strtod Py_PROTO((const char *, char **)); - char *s, *start, *end; + const char *s, *start; + char *end; double x=0.0, y=0.0, z; int got_re=0, got_im=0, done=0; int digit_or_dot; int sw_error=0; int sign; char buffer[256]; /* For errors */ + int len; - start = s = PyString_AS_STRING(v); + if (PyString_Check(v)) { + s = PyString_AS_STRING(v); + len = PyString_GET_SIZE(v); + } + else if (PyUnicode_Check(v)) { + char s_buffer[256]; + + if (PyUnicode_GET_SIZE(v) >= sizeof(s_buffer)) { + PyErr_SetString(PyExc_ValueError, + "complex() literal too large to convert"); + return NULL; + } + if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v), + PyUnicode_GET_SIZE(v), + s_buffer, + NULL)) + return NULL; + s = s_buffer; + len = strlen(s); + } + else if (PyObject_AsCharBuffer(v, &s, &len)) { + PyErr_SetString(PyExc_TypeError, + "complex() needs a string first argument"); + return NULL; + } /* position on first nonblank */ + start = s; while (*s && isspace(Py_CHARMASK(*s))) s++; if (s[0] == '\0') { @@ -475,7 +502,7 @@ switch (*s) { case '\0': - if (s-start != PyString_GET_SIZE(v)) { + if (s-start != len) { PyErr_SetString( PyExc_ValueError, "null byte in argument for complex()"); @@ -584,7 +611,7 @@ i = NULL; if (!PyArg_ParseTuple(args, "O|O:complex", &r, &i)) return NULL; - if (PyString_Check(r)) + if (PyString_Check(r) || PyUnicode_Check(r)) return complex_from_string(r); if ((nbr = r->ob_type->tp_as_number) == NULL || nbr->nb_float == NULL || @@ -1289,12 +1316,17 @@ return NULL; if (base == -909) return PyNumber_Int(v); - else if (!PyString_Check(v)) { + else if (PyString_Check(v)) + return PyInt_FromString(PyString_AS_STRING(v), NULL, base); + else if (PyUnicode_Check(v)) + return PyInt_FromUnicode(PyUnicode_AS_UNICODE(v), + PyUnicode_GET_SIZE(v), + base); + else { PyErr_SetString(PyExc_TypeError, "can't convert non-string with explicit base"); return NULL; } - return PyInt_FromString(PyString_AS_STRING(v), NULL, base); } static char int_doc[] = @@ -1319,12 +1351,17 @@ return NULL; if (base == -909) return PyNumber_Long(v); - else if (!PyString_Check(v)) { + else if (PyString_Check(v)) + return PyLong_FromString(PyString_AS_STRING(v), NULL, base); + else if (PyUnicode_Check(v)) + return PyLong_FromUnicode(PyUnicode_AS_UNICODE(v), + PyUnicode_GET_SIZE(v), + base); + else { PyErr_SetString(PyExc_TypeError, "can't convert non-string with explicit base"); return NULL; } - return PyLong_FromString(PyString_AS_STRING(v), NULL, base); } static char long_doc[] = diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.py CVS-Python/Python/codecs.c Python+Unicode/Python/codecs.c --- CVS-Python/Python/codecs.c Mon Apr 3 13:46:03 2000 +++ Python+Unicode/Python/codecs.c Wed Apr 5 02:44:28 2000 @@ -84,8 +84,11 @@ return -1; } +/* Convert a string to a normalized Python string: all characters are + converted to lower case, spaces are replaced with underscores. */ + static -PyObject *lowercasestring(const char *string) +PyObject *normalizestring(const char *string) { register int i; int len = strlen(string); @@ -96,8 +99,14 @@ if (v == NULL) return NULL; p = PyString_AS_STRING(v); - for (i = 0; i < len; i++) - p[i] = tolower(string[i]); + for (i = 0; i < len; i++) { + register char ch = string[i]; + if (ch == ' ') + ch = '-'; + else + ch = tolower(ch); + p[i] = ch; + } return v; } @@ -132,8 +141,10 @@ goto onError; } - /* Convert the encoding to a lower-cased Python string */ - v = lowercasestring(encoding); + /* Convert the encoding to a normalized Python string: all + characters are converted to lower case, spaces and hypens are + replaced with underscores. */ + v = normalizestring(encoding); if (v == NULL) goto onError; PyString_InternInPlace(&v); Binary files CVS-Python/foo and Python+Unicode/foo differ diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.c -x *.h -x *.in -x output CVS-Python/Lib/encodings/__init__.py Python+Unicode/Lib/encodings/__init__.py --- CVS-Python/Lib/encodings/__init__.py Thu Mar 23 23:58:42 2000 +++ Python+Unicode/Lib/encodings/__init__.py Wed Apr 5 02:44:28 2000 @@ -4,8 +4,8 @@ directory. Codec modules must have names corresponding to standard lower-case - encoding names. Hyphens are automatically converted to - underscores, e.g. 'utf-8' is looked up as module utf_8. + encoding names with hyphens mapped to underscores, e.g. 'utf-8' is + implemented by the module 'utf_8.py'. Each codec module must export the following interface: @@ -40,7 +40,7 @@ return entry # Import the module - modname = string.replace(encoding,'-','_') + modname = string.replace(encoding, '-', '_') modname = aliases.aliases.get(modname,modname) try: mod = __import__(modname,globals(),locals(),'*') diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.c -x *.h -x *.in -x output CVS-Python/Lib/encodings/aliases.py Python+Unicode/Lib/encodings/aliases.py --- CVS-Python/Lib/encodings/aliases.py Mon Apr 3 13:45:48 2000 +++ Python+Unicode/Lib/encodings/aliases.py Wed Apr 5 02:44:28 2000 @@ -54,4 +54,7 @@ 'macroman': 'mac_roman', 'macturkish': 'mac_turkish', + # MBCS + 'dbcs': 'mbcs', + } diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.c -x *.h -x *.in -x output CVS-Python/Lib/string.py Python+Unicode/Lib/string.py --- CVS-Python/Lib/string.py Sat Mar 11 10:52:36 2000 +++ Python+Unicode/Lib/string.py Wed Apr 5 02:44:28 2000 @@ -196,14 +196,11 @@ Return the floating point number represented by the string s. """ - if type(s) == _StringType: - return _float(s) - else: - raise TypeError('argument 1: expected string, %s found' % - type(s).__name__) + return _float(s) + # Convert string to integer -def atoi(*args): +def atoi(s , base=10): """atoi(s [,base]) -> int Return the integer represented by the string s in the given @@ -214,23 +211,11 @@ accepted. """ - try: - s = args[0] - except IndexError: - raise TypeError('function requires at least 1 argument: %d given' % - len(args)) - # Don't catch type error resulting from too many arguments to int(). The - # error message isn't compatible but the error type is, and this function - # is complicated enough already. - if type(s) == _StringType: - return _apply(_int, args) - else: - raise TypeError('argument 1: expected string, %s found' % - type(s).__name__) + return _int(s, base) # Convert string to long integer -def atol(*args): +def atol(s, base=10): """atol(s [,base]) -> long Return the long integer represented by the string s in the @@ -242,19 +227,7 @@ unless base is 0. """ - try: - s = args[0] - except IndexError: - raise TypeError('function requires at least 1 argument: %d given' % - len(args)) - # Don't catch type error resulting from too many arguments to long(). The - # error message isn't compatible but the error type is, and this function - # is complicated enough already. - if type(s) == _StringType: - return _apply(_long, args) - else: - raise TypeError('argument 1: expected string, %s found' % - type(s).__name__) + return _long(s, base) # Left-justify a string diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.c -x *.h -x *.in -x output CVS-Python/Lib/test/test_b1.py Python+Unicode/Lib/test/test_b1.py --- CVS-Python/Lib/test/test_b1.py Fri Mar 26 15:58:20 1999 +++ Python+Unicode/Lib/test/test_b1.py Wed Apr 5 02:44:28 2000 @@ -95,6 +95,7 @@ if complex(0j, 3.14) <> 3.14j: raise TestFailed, 'complex(0j, 3.14)' if complex(0.0, 3.14) <> 3.14j: raise TestFailed, 'complex(0.0, 3.14)' if complex(" 3.14+J ") <> 3.14+1j: raise TestFailed, 'complex(" 3.14+J )"' +if complex(u" 3.14+J ") <> 3.14+1j: raise TestFailed, 'complex(u" 3.14+J )"' class Z: def __complex__(self): return 3.14j z = Z() @@ -208,6 +209,9 @@ if float(314) <> 314.0: raise TestFailed, 'float(314)' if float(314L) <> 314.0: raise TestFailed, 'float(314L)' if float(" 3.14 ") <> 3.14: raise TestFailed, 'float(" 3.14 ")' +if float(u" 3.14 ") <> 3.14: raise TestFailed, 'float(u" 3.14 ")' +if float(u" \u0663.\u0661\u0664 ") <> 3.14: + raise TestFailed, 'float(u" \u0663.\u0661\u0664 ")' print 'getattr' import sys @@ -254,6 +258,9 @@ if int(-3.9) <> -3: raise TestFailed, 'int(-3.9)' if int(3.5) <> 3: raise TestFailed, 'int(3.5)' if int(-3.5) <> -3: raise TestFailed, 'int(-3.5)' +# Different base: +if int("10",16) <> 16L: raise TestFailed, 'int("10",16)' +if int(u"10",16) <> 16L: raise TestFailed, 'int(u"10",16)' # Test conversion fron strings and various anomalies L = [ ('0', 0), @@ -267,9 +274,28 @@ ('314 ', 314), (' \t\t 314 \t\t ', 314), (`sys.maxint`, sys.maxint), + (' 1x', ValueError), + (' 1 ', 1), + (' 1\02 ', ValueError), ('', ValueError), (' ', ValueError), (' \t\t ', ValueError), + (u'0', 0), + (u'1', 1), + (u'9', 9), + (u'10', 10), + (u'99', 99), + (u'100', 100), + (u'314', 314), + (u' 314', 314), + (u'\u0663\u0661\u0664 ', 314), + (u' \t\t 314 \t\t ', 314), + (u' 1x', ValueError), + (u' 1 ', 1), + (u' 1\02 ', ValueError), + (u'', ValueError), + (u' ', ValueError), + (u' \t\t ', ValueError), ] for s, v in L: for sign in "", "+", "-": @@ -349,10 +375,17 @@ if long(-3.9) <> -3L: raise TestFailed, 'long(-3.9)' if long(3.5) <> 3L: raise TestFailed, 'long(3.5)' if long(-3.5) <> -3L: raise TestFailed, 'long(-3.5)' +if long("-3") <> -3L: raise TestFailed, 'long("-3")' +if long(u"-3") <> -3L: raise TestFailed, 'long(u"-3")' +# Different base: +if long("10",16) <> 16L: raise TestFailed, 'long("10",16)' +if long(u"10",16) <> 16L: raise TestFailed, 'long(u"10",16)' # Check conversions from string (same test set as for int(), and then some) LL = [ ('1' + '0'*20, 10L**20), ('1' + '0'*100, 10L**100), + (u'1' + u'0'*20, 10L**20), + (u'1' + u'0'*100, 10L**100), ] for s, v in L + LL: for sign in "", "+", "-": @@ -363,11 +396,11 @@ vv = -v try: if long(ss) != long(vv): - raise TestFailed, "int(%s)" % `ss` + raise TestFailed, "long(%s)" % `ss` except v: pass except ValueError, e: - raise TestFailed, "int(%s) raised ValueError: %s" % (`ss`, e) + raise TestFailed, "long(%s) raised ValueError: %s" % (`ss`, e) print 'map' if map(None, 'hello world') <> ['h','e','l','l','o',' ','w','o','r','l','d']: diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.c -x *.h -x *.in -x output CVS-Python/Lib/test/test_contains.py Python+Unicode/Lib/test/test_contains.py --- CVS-Python/Lib/test/test_contains.py Tue Mar 7 16:52:01 2000 +++ Python+Unicode/Lib/test/test_contains.py Wed Apr 5 11:23:44 2000 @@ -17,7 +17,7 @@ def check(ok, *args): if not ok: - raise TestFailed, join(map(str, args), " ") + raise TestFailed, " ".join(map(str, args)) a = base_set(1) b = set(1) @@ -60,5 +60,62 @@ try: None in 'abc' check(0, "None in 'abc' did not raise error") +except TypeError: + pass + +# Test char in Unicode + +check('c' in u'abc', "'c' not in u'abc'") +check('d' not in u'abc', "'d' in u'abc'") + +try: + '' in u'abc' + check(0, "'' in u'abc' did not raise error") +except TypeError: + pass + +try: + 'ab' in u'abc' + check(0, "'ab' in u'abc' did not raise error") +except TypeError: + pass + +try: + None in u'abc' + check(0, "None in u'abc' did not raise error") +except TypeError: + pass + +# Test Unicode char in Unicode + +check(u'c' in u'abc', "u'c' not in u'abc'") +check(u'd' not in u'abc', "u'd' in u'abc'") + +try: + u'' in u'abc' + check(0, "u'' in u'abc' did not raise error") +except TypeError: + pass + +try: + u'ab' in u'abc' + check(0, "u'ab' in u'abc' did not raise error") +except TypeError: + pass + +# Test Unicode char in string + +check(u'c' in 'abc', "u'c' not in 'abc'") +check(u'd' not in 'abc', "u'd' in 'abc'") + +try: + u'' in 'abc' + check(0, "u'' in 'abc' did not raise error") +except TypeError: + pass + +try: + u'ab' in 'abc' + check(0, "u'ab' in 'abc' did not raise error") except TypeError: pass diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x *.c -x *.h -x *.in -x output CVS-Python/Lib/test/test_unicode.py Python+Unicode/Lib/test/test_unicode.py --- CVS-Python/Lib/test/test_unicode.py Wed Mar 29 11:50:14 2000 +++ Python+Unicode/Lib/test/test_unicode.py Wed Apr 5 02:44:28 2000 @@ -221,15 +221,23 @@ # Contains: print 'Testing Unicode contains method...', -assert ('a' in 'abdb') == 1 -assert ('a' in 'bdab') == 1 -assert ('a' in 'bdaba') == 1 -assert ('a' in 'bdba') == 1 +assert ('a' in u'abdb') == 1 +assert ('a' in u'bdab') == 1 +assert ('a' in u'bdaba') == 1 +assert ('a' in u'bdba') == 1 assert ('a' in u'bdba') == 1 assert (u'a' in u'bdba') == 1 assert (u'a' in u'bdb') == 0 assert (u'a' in 'bdb') == 0 assert (u'a' in 'bdba') == 1 +assert (u'a' in ('a',1,None)) == 1 +assert (u'a' in (1,None,'a')) == 1 +assert (u'a' in (1,None,u'a')) == 1 +assert ('a' in ('a',1,None)) == 1 +assert ('a' in (1,None,'a')) == 1 +assert ('a' in (1,None,u'a')) == 1 +assert ('a' in ('x',1,u'y')) == 0 +assert ('a' in ('x',1,None)) == 0 print 'done.' # Formatting: @@ -270,11 +278,88 @@ assert unicode(u.encode(encoding),encoding) == u u = u''.join(map(unichr, range(256))) -for encoding in ('latin-1',): - assert unicode(u.encode(encoding),encoding) == u +for encoding in ( + 'latin-1', + ): + try: + assert unicode(u.encode(encoding),encoding) == u + except AssertionError: + print '*** codec "%s" failed round-trip' % encoding + except ValueError,why: + print '*** codec for "%s" failed: %s' % (encoding, why) u = u''.join(map(unichr, range(128))) -for encoding in ('ascii',): - assert unicode(u.encode(encoding),encoding) == u +for encoding in ( + 'ascii', + ): + try: + assert unicode(u.encode(encoding),encoding) == u + except AssertionError: + print '*** codec "%s" failed round-trip' % encoding + except ValueError,why: + print '*** codec for "%s" failed: %s' % (encoding, why) + +print 'done.' + +print 'Testing standard mapping codecs...', + +print '0-127...', +s = ''.join(map(chr, range(128))) +for encoding in ( + 'cp037', 'cp1026', + 'cp437', 'cp500', 'cp737', 'cp775', 'cp850', + 'cp852', 'cp855', 'cp860', 'cp861', 'cp862', + 'cp863', 'cp865', 'cp866', + 'iso8859_10', 'iso8859_13', 'iso8859_14', 'iso8859_15', + 'iso8859_2', 'iso8859_3', 'iso8859_4', 'iso8859_5', 'iso8859_6', + 'iso8859_7', 'iso8859_9', 'koi8_r', 'latin_1', + 'mac_cyrillic', 'mac_latin2', + + 'cp1250', 'cp1251', 'cp1252', 'cp1253', 'cp1254', 'cp1255', + 'cp1256', 'cp1257', 'cp1258', + 'cp856', 'cp857', 'cp864', 'cp869', 'cp874', + + 'mac_greek', 'mac_iceland','mac_roman', 'mac_turkish', + 'cp1006', 'cp875', 'iso8859_8', + + ### These have undefined mappings: + #'cp424', + + ): + try: + assert unicode(s,encoding).encode(encoding) == s + except AssertionError: + print '*** codec "%s" failed round-trip' % encoding + except ValueError,why: + print '*** codec for "%s" failed: %s' % (encoding, why) + +print '128-255...', +s = ''.join(map(chr, range(128,256))) +for encoding in ( + 'cp037', 'cp1026', + 'cp437', 'cp500', 'cp737', 'cp775', 'cp850', + 'cp852', 'cp855', 'cp860', 'cp861', 'cp862', + 'cp863', 'cp865', 'cp866', + 'iso8859_10', 'iso8859_13', 'iso8859_14', 'iso8859_15', + 'iso8859_2', 'iso8859_3', 'iso8859_4', 'iso8859_5', 'iso8859_6', + 'iso8859_7', 'iso8859_9', 'koi8_r', 'latin_1', + 'mac_cyrillic', 'mac_latin2', + + ### These have undefined mappings: + #'cp1250', 'cp1251', 'cp1252', 'cp1253', 'cp1254', 'cp1255', + #'cp1256', 'cp1257', 'cp1258', + #'cp424', 'cp856', 'cp857', 'cp864', 'cp869', 'cp874', + #'mac_greek', 'mac_iceland','mac_roman', 'mac_turkish', + + ### These fail the round-trip: + #'cp1006', 'cp875', 'iso8859_8', + + ): + try: + assert unicode(s,encoding).encode(encoding) == s + except AssertionError: + print '*** codec "%s" failed round-trip' % encoding + except ValueError,why: + print '*** codec for "%s" failed: %s' % (encoding, why) print 'done.' Binary files CVS-Python/foo and Python+Unicode/foo differ --------------ADCA470C18D9DED714E274DB-- From mhammond@skippinet.com.au Wed Apr 5 14:54:50 2000 From: mhammond@skippinet.com.au (Mark Hammond) Date: Wed, 5 Apr 2000 23:54:50 +1000 Subject: [Patches] Patch for mmap module on Win9x Message-ID: This patch fixes the mmap module on Windows 9x. Also updates the mmap test to remove the test file. Release info: I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. Mark. diff -c -3 -r2.3 mmapmodule.c *** mmapmodule.c 2000/03/31 15:04:26 2.3 --- mmapmodule.c 2000/04/05 13:49:44 *************** *** 752,763 **** PyErr_SetFromErrno(mmap_module_error); return NULL; } ! // ! // fh = OpenFile (filename, &file_info, OF_READWRITE); ! // if (fh == HFILE_ERROR) { ! // PyErr_SetFromWindowsErr(GetLastError()); ! // return NULL; ! // } } m_obj = PyObject_NEW (mmap_object, &mmap_object_type); --- 752,759 ---- PyErr_SetFromErrno(mmap_module_error); return NULL; } ! /* Win9x appears to need us seeked to zero */ ! fseek(&_iob[fileno], 0, SEEK_SET); } m_obj = PyObject_NEW (mmap_object, &mmap_object_type); diff -c -3 -r1.3 test_mmap.py *** test_mmap.py 2000/03/31 01:20:33 1.3 --- test_mmap.py 2000/04/05 13:52:04 *************** *** 59,64 **** --- 59,66 ---- assert start == PAGESIZE assert end == PAGESIZE + 6 + m.close() + os.unlink("foo") print ' Test passed' test_both() From fdrake@acm.org Wed Apr 5 15:17:39 2000 From: fdrake@acm.org (Fred L. Drake, Jr.) Date: Wed, 5 Apr 2000 10:17:39 -0400 (EDT) Subject: [Patches] Patch for mmap module on Win9x In-Reply-To: References: Message-ID: <14571.19203.167311.530879@seahag.cnri.reston.va.us> Mark Hammond writes: > This patch fixes the mmap module on Windows 9x. > > Also updates the mmap test to remove the test file. Thanks Mark! -Fred -- Fred L. Drake, Jr. Corporation for National Research Initiatives From tismer@tismer.com Wed Apr 5 16:22:13 2000 From: tismer@tismer.com (Christian Tismer) Date: Wed, 05 Apr 2000 17:22:13 +0200 Subject: [Patches] portable garbage collection for Python References: <20000405025037.B16978@acs.ucalgary.ca> Message-ID: <38EB5A25.70A03160@tismer.com> Neil Schemenauer wrote: > > I have a new version of my garbage collection patch available. > If you have time please test it out and send me comments. The > patch against the current CVS version of Python is available > from: > > http://www.enme.ucalgary.ca/~nascheme/python/gc-cycle.diff > > I will give some more details on my approach tomorrow after I get > some rest. :) This looks really great! One minor bug from just reading the diff: *************** *** 215,220 **** --- 219,227 ---- PyListObject *op; { int i; + #ifdef WITH_CYCLE_GC + PyGC_Remove((PyObject *)op); + #endif Py_TRASHCAN_SAFE_BEGIN(op) if (op->ob_item != NULL) { /* Do it backwards, for Christian Tismer. *************** *** 227,233 **** } free((ANY *)op->ob_item); } Code must not be inserted before Py_TRASHCAN_SAFE_BEGIN, this construct is supposed to enclose the whole destruction process, whatever it is. cheers - chris -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaunstr. 26 : *Starship* http://starship.python.net 14163 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF where do you want to jump today? http://www.stackless.com From guido@python.org Wed Apr 5 20:59:01 2000 From: guido@python.org (Guido van Rossum) Date: Wed, 05 Apr 2000 15:59:01 -0400 Subject: [Patches] fileinput.py argument handling (and suggestion) In-Reply-To: Your message of "Wed, 05 Apr 0100 19:07:55 +0200." <20000405170755.30583.qmail@lannert.rz.uni-duesseldorf.de> References: <20000405170755.30583.qmail@lannert.rz.uni-duesseldorf.de> Message-ID: <200004051959.PAA18356@eric.cnri.reston.va.us> I kind of like the chop switch. Anybody else got an opinion? +1 --Guido van Rossum (home page: http://www.python.org/~guido/) From Fredrik Lundh" This is a multi-part message in MIME format. ------=_NextPart_000_001B_01BF9F54.95FFC5E0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable the attached patch eliminates a MSVC compiler warning. I confirm that, to the best of my knowledge and belief, this = contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related = documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. =20 I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. ------=_NextPart_000_001B_01BF9F54.95FFC5E0 Content-Type: application/octet-stream; name="unicodeobject-patch-1" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="unicodeobject-patch-1" --- Objects\unicodeobject.c.bak Wed Apr 05 23:06:31 2000 +++ Objects\unicodeobject.c Wed Apr 05 23:08:35 2000 @@ -1959,7 +1959,7 @@ continue; } if (0 < ch < 256) { - *output++ = ch; + *output++ = (char) ch; continue; } /* All other characters are considered invalid */ ------=_NextPart_000_001B_01BF9F54.95FFC5E0-- From DavidA@ActiveState.com Wed Apr 5 23:05:04 2000 From: DavidA@ActiveState.com (David Ascher) Date: Wed, 5 Apr 2000 15:05:04 -0700 Subject: [Patches] fileinput.py argument handling (and suggestion) In-Reply-To: <200004051959.PAA18356@eric.cnri.reston.va.us> Message-ID: > I kind of like the chop switch. Anybody else got an opinion? > > +1 +0 How about also adding it to readlines()? --david From nascheme@enme.ucalgary.ca Thu Apr 6 02:44:35 2000 From: nascheme@enme.ucalgary.ca (Neil Schemenauer) Date: Wed, 5 Apr 2000 19:44:35 -0600 Subject: [Patches] New builtin function repeat? Message-ID: <20000405194435.A31381@acs.ucalgary.ca> --G4iJoqBmSsgzjUCe Content-Type: text/plain; charset=us-ascii I made this module some time about but I still think it is neat. It creates a new function called repeat (I'm not stuck on the name). You can use it like this: for line in repeat(sys.stdin.readline): ... The repeat function creates a new sequence object. The function supplied is called for __getitem__. By default, a false value returned from the function will raise an IndexError. You can specifiy an alternate termination value. For example: for line in repeat(sys.stdin.readline, ''): ... would work as well. While I'm throwing out crazy ideas, how about adding some sequence methods to PyFileObject? You could then do: file = open(...) for line in file: ... Too weird? Here is a patch and the module. Neil -- "The lyf so short, the craft so long to lerne." -- Chaucer --G4iJoqBmSsgzjUCe Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="file-seq.diff" diff -cr Python-cvs/Objects/fileobject.c Python-file/Objects/fileobject.c *** Python-cvs/Objects/fileobject.c Fri Mar 24 22:32:30 2000 --- Python-file/Objects/fileobject.c Wed Apr 5 19:37:13 2000 *************** *** 1040,1045 **** --- 1040,1099 ---- return PyMember_Set((char *)f, file_memberlist, name, v); } + /* as_sequence */ + + static PyObject * + file_getitem(self, index) + PyObject *self; + int index; + { + PyObject *line; + if ((line = PyFile_GetLine(self, 0)) == NULL) { + return NULL; + } + if (!PyObject_IsTrue(line)) { + Py_DECREF(line); + PyErr_SetString(PyExc_IndexError, "file index out of range"); + return NULL; + } + return line; + } + + static int + file_length(self) + PyObject *self; + { + return 0; + } + + static PyObject * + file_concat(self, other) + PyObject *self; + PyObject *other; + { + PyErr_SetString(PyExc_AttributeError, "__concat__"); + return NULL; + } + + static PyObject * + file_repeat(self, count) + PyObject *self; + int count; + { + PyErr_SetString(PyExc_AttributeError, "__repeat__"); + return NULL; + } + + static PySequenceMethods file_as_sequence = { + (inquiry)file_length, /*sq_length*/ + (binaryfunc)file_concat, /*sq_concat*/ + (intargfunc)file_repeat, /*sq_repeat*/ + (intargfunc)file_getitem, /*sq_item*/ + (intintargfunc)0, /*sq_slice*/ + (intobjargproc)0, /*sq_ass_item*/ + (intintobjargproc)0, /*sq_ass_slice*/ + }; + PyTypeObject PyFile_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, *************** *** 1052,1057 **** --- 1106,1113 ---- (setattrfunc)file_setattr, /*tp_setattr*/ 0, /*tp_compare*/ (reprfunc)file_repr, /*tp_repr*/ + 0, /*tp_as_number*/ + &file_as_sequence, /*tp_as_sequence*/ }; /* Interface for the 'soft space' between print items. */ --G4iJoqBmSsgzjUCe Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="repeatmodule.c" /* * A little Python extension module so you can do stuff like: * * import sys * from repeat import repeat * for line in repeat(sys.stdin.readline): * ... * * repeat(, []) -> RepeatObject * * RepeatObjects are sequences that only support the method __getitem__. * is called on __getitem__. If is not specified a * false value from raises an IndexError. If is * specified, if the value is equal to then IndexError is * raised. * * * Neil Schemenauer April, 2000 * */ #include "Python.h" typedef struct { PyObject_HEAD PyObject *function; PyObject *until; } repeatObject; staticforward PyTypeObject repeat_Type; static repeatObject * newrepeatObject(args) PyObject *args; { repeatObject *self; PyObject *function; PyObject *until; until = NULL; if (!PyArg_ParseTuple(args, "O|O", &function, &until)) return NULL; if (!PyCallable_Check(function)) { PyErr_SetString(PyExc_TypeError, "callable object required"); return NULL; } self = PyObject_NEW(repeatObject, &repeat_Type); if (self == NULL) return NULL; Py_INCREF(function); self->function = function; if (until != NULL) Py_INCREF(until); self->until = until; return self; } static void repeat_dealloc(self) repeatObject *self; { Py_XDECREF(self->function); Py_XDECREF(self->until); PyMem_DEL(self); } static PyObject * repeat_getitem(self, index) repeatObject *self; int index; { PyObject *item; item = PyEval_CallObject(self->function, NULL); if ( item == NULL ) { return NULL; } if ( (self->until && PyObject_Compare(item, self->until) == 0) || (!self->until && !PyObject_IsTrue(item)) ) { PyErr_SetString(PyExc_IndexError, "repeat completed"); return NULL; } return item; } static int repeat_length(self) PyObject *self; { return 0; } static PyObject * repeat_concat(self, other) PyObject *self; PyObject *other; { PyErr_SetString(PyExc_AttributeError, "__concat__"); return NULL; } static PyObject * repeat_repeat(self, count) PyObject *self; int count; { PyErr_SetString(PyExc_AttributeError, "__repeat__"); return NULL; } static PyMethodDef repeat_methods[] = { {NULL, NULL} /* sentinel */ }; static PySequenceMethods repeat_as_sequence = { (inquiry)repeat_length, /*sq_length*/ (binaryfunc)repeat_concat, /*sq_concat*/ (intargfunc)repeat_repeat, /*sq_repeat*/ (intargfunc)repeat_getitem, /*sq_item*/ (intintargfunc)0, /*sq_slice*/ (intobjargproc)0, /*sq_ass_item*/ (intintobjargproc)0, /*sq_ass_slice*/ }; staticforward PyTypeObject repeat_Type = { PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ "repeat", /*tp_name*/ sizeof(repeatObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ /* methods */ (destructor)repeat_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ (getattrfunc)0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ &repeat_as_sequence, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ }; static PyObject * repeat_new(self, args) PyObject *self; /* Not used */ PyObject *args; { repeatObject *rv; rv = newrepeatObject(args); if ( rv == NULL ) return NULL; return (PyObject *)rv; } /* List of functions defined in the module */ static PyMethodDef repeatmodule_methods[] = { {"repeat", repeat_new, 1}, {NULL, NULL} /* sentinel */ }; /* Initialization function for the module (*must* be called initrepeat) */ void initrepeat() { PyObject *m, *d; /* Create the module and add the functions */ repeat_Type.ob_type = &PyType_Type; m = Py_InitModule("repeat", repeatmodule_methods); /* Add some symbolic constants to the module */ d = PyModule_GetDict(m); } --G4iJoqBmSsgzjUCe-- From mhammond@skippinet.com.au Thu Apr 6 02:45:59 2000 From: mhammond@skippinet.com.au (Mark Hammond) Date: Thu, 6 Apr 2000 11:45:59 +1000 Subject: [Patches] zlib build problems. Message-ID: Im trying to build the zlib module I came across some wierdness. If the problem is as simple as I think it is, then patches is appropriate for the discussion :-) Im building zlib itself from sources, rather than using the binaries. Im using the static zlib library. This combination produced linker errors. The following patch made everything work: diff -c -2 -r2.30 zlibmodule.c *** zlibmodule.c 2000/02/29 13:59:24 2.30 --- zlibmodule.c 2000/04/06 01:36:18 *************** *** 5,9 **** #include "Python.h" #ifdef MS_WIN32 - #define ZLIB_DLL #endif #include "zlib.h" --- 5,8 ---- ie, we do not want to define ZLIB_DLL, as we are using the static ZLIB library. [I assume we _are_ trying to use the static lib - checkin of revision 1.6 says we are :-] So, the question I had was "how did this work for Guido et al"? It appears that zlib.dsp is set to point to inconsistent directories. The include files come from "..\..\zlib113", while the .lib file comes from "..\..\zlib113dll\static32\zlibstat.lib" - note that these are different directory structures. That is the only reason I could come up with?? I have not added a patch for the .dsp, but it does appear this needs to be changed, so that the .h and .lib files come from the same branch. Further, once I applied this change, I added a "/nod:msvcrt" option to the Debug linker switch (not needed on the release build). This silences a linker warning. Release info: I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. Mark. From guido@python.org Thu Apr 6 14:21:23 2000 From: guido@python.org (Guido van Rossum) Date: Thu, 06 Apr 2000 09:21:23 -0400 Subject: [Patches] zlib build problems. In-Reply-To: Your message of "Thu, 06 Apr 2000 11:45:59 +1000." References: Message-ID: <200004061321.JAA23839@eric.cnri.reston.va.us> > Im trying to build the zlib module I came across some wierdness. If > the problem is as simple as I think it is, then patches is > appropriate for the discussion :-) > > Im building zlib itself from sources, rather than using the > binaries. Im using the static zlib library. This combination > produced linker errors. > > The following patch made everything work: > > diff -c -2 -r2.30 zlibmodule.c > *** zlibmodule.c 2000/02/29 13:59:24 2.30 > --- zlibmodule.c 2000/04/06 01:36:18 > *************** > *** 5,9 **** > #include "Python.h" > #ifdef MS_WIN32 > - #define ZLIB_DLL > #endif > #include "zlib.h" > --- 5,8 ---- I got rid of the #ifdef MS_WIN32 ... #endif as well :-) > ie, we do not want to define ZLIB_DLL, as we are using the static > ZLIB library. > > [I assume we _are_ trying to use the static lib - checkin of > revision 1.6 says we are :-] Yes we are. Using the DLL version is madness -- too many incomaptible zlib.dll files around. > So, the question I had was "how did this work for Guido et al"? Beats me. > It appears that zlib.dsp is set to point to inconsistent > directories. The include files come from "..\..\zlib113", while the > .lib file comes from "..\..\zlib113dll\static32\zlibstat.lib" - note > that these are different directory structures. That is the only > reason I could come up with?? I doubt it. The zlib113dll directory *only* contains binaries (.dll and .lib files). The zlib113 directory contains the sources from which these binaries apparently were built. Both were downloaded from the websites mentioned in the top of the zlibmodule.c source file, and extracted in the directory names suggested by the archive names. Just to be sure I downloaded them again; the build goes fine. I decided not to change the extraction directory. > I have not added a patch for the .dsp, but it does appear this needs > to be changed, so that the .h and .lib files come from the same > branch. Further, once I applied this change, I added a > "/nod:msvcrt" option to the Debug linker switch (not needed on the > release build). This silences a linker warning. I've added that one to make you happy. --Guido van Rossum (home page: http://www.python.org/~guido/) From guido@python.org Thu Apr 6 14:26:42 2000 From: guido@python.org (Guido van Rossum) Date: Thu, 06 Apr 2000 09:26:42 -0400 Subject: [Patches] New builtin function repeat? In-Reply-To: Your message of "Wed, 05 Apr 2000 19:44:35 MDT." <20000405194435.A31381@acs.ucalgary.ca> References: <20000405194435.A31381@acs.ucalgary.ca> Message-ID: <200004061326.JAA23867@eric.cnri.reston.va.us> > I made this module some time about but I still think it is neat. > It creates a new function called repeat (I'm not stuck on the > name). You can use it like this: > > for line in repeat(sys.stdin.readline): > ... > > The repeat function creates a new sequence object. The function > supplied is called for __getitem__. By default, a false value > returned from the function will raise an IndexError. You can > specifiy an alternate termination value. For example: > > for line in repeat(sys.stdin.readline, ''): > ... > > would work as well. > > While I'm throwing out crazy ideas, how about adding some > sequence methods to PyFileObject? You could then do: > > file = open(...) > for line in file: > ... > > Too weird? Here is a patch and the module. All Python 1.7 or Py3K material... To be discussed on python-dev. I expect to redesign the way for loops interact with sequences; there will be a separate protocol, probably a method to extract a generator from an arbitrary object, where the generator has first/next methods. Then "for line in list" will create a list generator which keeps track of the loop index, while "for line in file" will create a file generator which leaves the state up to the file object. Some b/w compat issues arise. --Guido van Rossum (home page: http://www.python.org/~guido/) From guido@python.org Thu Apr 6 20:07:02 2000 From: guido@python.org (Guido van Rossum) Date: Thu, 06 Apr 2000 15:07:02 -0400 Subject: [Patches] zlib build problems. In-Reply-To: Your message of "Thu, 06 Apr 2000 09:21:23 EDT." <200004061321.JAA23839@eric.cnri.reston.va.us> References: <200004061321.JAA23839@eric.cnri.reston.va.us> Message-ID: <200004061907.PAA25761@eric.cnri.reston.va.us> > > The following patch made everything work: > > > > diff -c -2 -r2.30 zlibmodule.c > > *** zlibmodule.c 2000/02/29 13:59:24 2.30 > > --- zlibmodule.c 2000/04/06 01:36:18 > > *************** > > *** 5,9 **** > > #include "Python.h" > > #ifdef MS_WIN32 > > - #define ZLIB_DLL > > #endif > > #include "zlib.h" > > --- 5,8 ---- > > I got rid of the #ifdef MS_WIN32 ... #endif as well :-) Strange... This suddenly broke for me. I can now only get it to compile by define ZLIB_DLL again -- but I'm not using the DLL! I can revert the checkin, or I can define the symbol in the setup dialog. What would you prefer? --Guido van Rossum (home page: http://www.python.org/~guido/) From mhammond@skippinet.com.au Fri Apr 7 00:11:24 2000 From: mhammond@skippinet.com.au (Mark Hammond) Date: Fri, 7 Apr 2000 09:11:24 +1000 Subject: [Patches] zlib build problems. In-Reply-To: <200004061907.PAA25761@eric.cnri.reston.va.us> Message-ID: > > I got rid of the #ifdef MS_WIN32 ... #endif as well :-) > > Strange... This suddenly broke for me. I can now only get it to > compile by define ZLIB_DLL again -- but I'm not using the DLL! > > I can revert the checkin, or I can define the symbol in the setup > dialog. What would you prefer? Very strange - I wonder if changing the referenced directories to the .h and the .lib come from the same tree solve it? Otherwise - In the setup dialog - I need to change this project locally to reflect the local path to zlib, so then I can also change the define - ie, if the change is in the .dsp, I can make it work without hacking the source code. Thanks, Mark. From Vladimir.Marangozov@inrialpes.fr Fri Apr 7 01:16:31 2000 From: Vladimir.Marangozov@inrialpes.fr (Vladimir Marangozov) Date: Fri, 7 Apr 2000 02:16:31 +0200 (CEST) Subject: [Patches] code_repr lineno fix for -O Message-ID: <200004070016.CAA21719@python.inrialpes.fr> This fixes the line number in the string representation of code objects when optimization is on (python -O). It was always reported as -1 instead of the real lineno. -- Vladimir MARANGOZOV | Vladimir.Marangozov@inrialpes.fr http://sirac.inrialpes.fr/~marangoz | tel:(+33-4)76615277 fax:76615252 -- I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. -------------------------------[ cut here ]--------------------------- *** Python/compile.c-1.6a1 Fri Apr 7 01:56:18 2000 --- Python/compile.c Fri Apr 7 02:06:44 2000 *************** *** 121,133 **** { char buf[500]; int lineno = -1; - unsigned char *p; char *filename = "???"; char *name = "???"; ! _PyCode_GETCODEPTR(co, &p); ! if (*p == SET_LINENO) ! lineno = (p[1] & 0xff) | ((p[2] & 0xff) << 8); if (co->co_filename && PyString_Check(co->co_filename)) filename = PyString_AsString(co->co_filename); if (co->co_name && PyString_Check(co->co_name)) --- 121,131 ---- { char buf[500]; int lineno = -1; char *filename = "???"; char *name = "???"; ! if (co->co_firstlineno != 0) ! lineno = co->co_firstlineno; if (co->co_filename && PyString_Check(co->co_filename)) filename = PyString_AsString(co->co_filename); if (co->co_name && PyString_Check(co->co_name)) From gansevle@cs.utwente.nl Fri Apr 7 14:55:15 2000 From: gansevle@cs.utwente.nl (Fred Gansevles) Date: Fri, 07 Apr 2000 15:55:15 +0200 Subject: [Patches] (no subject) Message-ID: <200004071355.PAA23203@localhost.localdomain> The copytree function doesn't pass the symlinks parameter in recursicve calls ---------------------------------------------------------------- I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. FAQ about legal I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. ---------------------------------------------------------------- Index: shutil.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/shutil.py,v retrieving revision 1.15 diff -c -r1.15 shutil.py *** shutil.py 2000/02/04 15:28:41 1.15 --- shutil.py 2000/04/07 13:48:42 *************** *** 88,94 **** linkto = os.readlink(srcname) os.symlink(linkto, dstname) elif os.path.isdir(srcname): ! copytree(srcname, dstname) else: copy2(srcname, dstname) # XXX What about devices, sockets etc.? --- 88,94 ---- linkto = os.readlink(srcname) os.symlink(linkto, dstname) elif os.path.isdir(srcname): ! copytree(srcname, dstname, symlinks) else: copy2(srcname, dstname) # XXX What about devices, sockets etc.? From fdrake@acm.org Fri Apr 7 15:35:17 2000 From: fdrake@acm.org (Fred L. Drake, Jr.) Date: Fri, 7 Apr 2000 10:35:17 -0400 (EDT) Subject: [Patches] (no subject) In-Reply-To: <200004071355.PAA23203@localhost.localdomain> References: <200004071355.PAA23203@localhost.localdomain> Message-ID: <14573.61989.402432.716689@seahag.cnri.reston.va.us> Fred Gansevles writes: > The copytree function doesn't pass the symlinks parameter in recursicve > calls Fred, I've applied your fix; thanks! -Fred -- Fred L. Drake, Jr. Corporation for National Research Initiatives From tismer@tismer.com Fri Apr 7 20:19:26 2000 From: tismer@tismer.com (Christian Tismer) Date: Fri, 07 Apr 2000 21:19:26 +0200 Subject: [Patches] Long Multiplication is not commutative. References: <38ED0291.65CB7B5F@tismer.com> Message-ID: <38EE34BE.6C452AD3@tismer.com> > The following factorial loops differ by a remarkable > factor of 1.8, and we can gain this speed by changing > long_mult to always put the lower multiplicand into the left. > > This was reported to me by Lenny Kneler, who thought he had > found a Stackless bug, but he was actually testing long math. :-) > > This buddy... > > >>> def ifact3(n) : > ... p = 1L > ... for i in range(1,n+1) : > ... p = i*p > ... return p > > performs better by a factor of 1.8 than this one: > > >>> def ifact1(n) : > ... p = 1L > ... for i in range(1,n+1) : > ... p = p*i > ... return p Checkin-message: long multiplication is more efficient if the smaller argument is at the left side. This patch swaps the arguments accordingly. Thanks to Lenny Kneler who let me find this out by chance. Changed files: longobject.c test_long.py Diff: *** //d/cvsroot/python-pu/python/dist/src/lib/test/test_long.py Thu Dec 23 15:36:42 1999 --- //d/python/python-1.5.2/lib/test/test_long.py Fri Apr 07 20:55:38 2000 *************** *** 77,82 **** --- 77,84 ---- def test_division_2(x, y): q, r = divmod(x, y) q2, r2 = x/y, x%y + pab, pba = x*y, y*x + check(pab == pba, "multiplication does not commute for", x, y) check(q == q2, "divmod returns different quotient than / for", x, y) check(r == r2, "divmod returns different mod than % for", x, y) check(x == q*y + r, "x != q*y + r after divmod on", x, y) *** //d/cvsroot/python-pu/python/dist/src/objects/longobject.c Thu Dec 23 15:41:28 1999 --- //d/python/python-1.5.2/objects/longobject.c Fri Apr 07 20:59:16 2000 *************** *** 1196,1201 **** --- 1196,1210 ---- size_a = ABS(a->ob_size); size_b = ABS(b->ob_size); + if (size_a > size_b) { + /* we are faster with the small object on the left */ + int hold_sa = size_a; + PyLongObject *hold_a = a; + size_a = size_b; + size_b = hold_sa; + a = b; + b = hold_a; + } z = _PyLong_New(size_a + size_b); if (z == NULL) return NULL; %%%%%%%%%%%%%%%%%%%%%%% end patch %%%%%%%%%%%%%%%%%%%%%%%%%% Disclaimer: I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaunstr. 26 : *Starship* http://starship.python.net 14163 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF where do you want to jump today? http://www.stackless.com From gward@mems-exchange.org Fri Apr 7 23:17:33 2000 From: gward@mems-exchange.org (Greg Ward) Date: Fri, 7 Apr 2000 18:17:33 -0400 Subject: [Patches] Fix main Makefile to create prefix, exec_prefix Message-ID: <20000407181732.A11360@mems-exchange.org> This patch fixes the top Python Makefile so it creates $(prefix) or $(exec_prefix) before attempting to create directories under them. Handy when you use prefixes like "/usr/local/python-1.5.2" and "/usr/local/python-1.6a1", which don't exist until you install Python into them. diff -c -r1.85 Makefile.in *** Makefile.in 2000/03/31 15:13:17 1.85 --- Makefile.in 2000/04/07 22:14:10 *************** *** 257,263 **** # Install the interpreter with $(VERSION) affixed # This goes into $(exec_prefix) altbininstall: python$(EXE) ! @for i in $(BINDIR); \ do \ if test ! -d $$i; then \ echo "Creating directory $$i"; \ --- 257,263 ---- # Install the interpreter with $(VERSION) affixed # This goes into $(exec_prefix) altbininstall: python$(EXE) ! @for i in $(exec_prefix) $(BINDIR); \ do \ if test ! -d $$i; then \ echo "Creating directory $$i"; \ *************** *** 274,280 **** # Install the manual page maninstall: ! @for i in $(MANDIR) $(MANDIR)/man1; \ do \ if test ! -d $$i; then \ echo "Creating directory $$i"; \ --- 274,280 ---- # Install the manual page maninstall: ! @for i in $(prefix) $(MANDIR) $(MANDIR)/man1; \ do \ if test ! -d $$i; then \ echo "Creating directory $$i"; \ *************** *** 292,298 **** LIBSUBDIRS= lib-old lib-tk test test/output encodings \ distutils distutils/command $(MACHDEPS) libinstall: python $(srcdir)/Lib/$(PLATDIR) ! @for i in $(SCRIPTDIR) $(LIBDEST); \ do \ if test ! -d $$i; then \ echo "Creating directory $$i"; \ --- 292,298 ---- LIBSUBDIRS= lib-old lib-tk test test/output encodings \ distutils distutils/command $(MACHDEPS) libinstall: python $(srcdir)/Lib/$(PLATDIR) ! @for i in $(prefix) $(SCRIPTDIR) $(LIBDEST); \ do \ if test ! -d $$i; then \ echo "Creating directory $$i"; \ -- Greg Ward - software developer gward@mems-exchange.org MEMS Exchange / CNRI voice: +1-703-262-5376 Reston, Virginia, USA fax: +1-703-262-5367 From fdrake@acm.org Sat Apr 8 06:05:20 2000 From: fdrake@acm.org (Fred L. Drake, Jr.) Date: Sat, 8 Apr 2000 01:05:20 -0400 (EDT) Subject: [Patches] Fix main Makefile to create prefix, exec_prefix In-Reply-To: <20000407181732.A11360@mems-exchange.org> References: <20000407181732.A11360@mems-exchange.org> Message-ID: <14574.48656.133609.387194@seahag.cnri.reston.va.us> Greg Ward writes: > This patch fixes the top Python Makefile so it creates $(prefix) or > $(exec_prefix) before attempting to create directories under them. > Handy when you use prefixes like "/usr/local/python-1.5.2" and > "/usr/local/python-1.6a1", which don't exist until you install Python I say check it in. If Guido disagrees he can yell/email about it later; this is quite reasonable given the recent discussion of "stow" and the need of developers to keep multiple versions (including patch levels!) installed. -Fred -- Fred L. Drake, Jr. Corporation for National Research Initiatives From Vladimir.Marangozov@inrialpes.fr Sat Apr 8 12:05:39 2000 From: Vladimir.Marangozov@inrialpes.fr (Vladimir Marangozov) Date: Sat, 8 Apr 2000 13:05:39 +0200 (CEST) Subject: [Patches] code_compare Message-ID: <200004081105.NAA28779@python.inrialpes.fr> Add the co_name field comparison to differentiate named code objects, even when their code is the same. This caused side effects for -O because of constant folding. A side note: anonymous code objects (co_name == "?") would still be subject to constant folding optimization. -- Vladimir MARANGOZOV | Vladimir.Marangozov@inrialpes.fr http://sirac.inrialpes.fr/~marangoz | tel:(+33-4)76615277 fax:76615252 -- I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. -------------------------------[ cut here ]--------------------------- *** Python/compile.c-orig Sat Apr 8 11:39:23 2000 --- Python/compile.c Sat Apr 8 11:39:28 2000 *************** *** 153,158 **** --- 153,160 ---- cmp = PyObject_Compare(co->co_names, cp->co_names); if (cmp) return cmp; cmp = PyObject_Compare(co->co_varnames, cp->co_varnames); + if (cmp) return cmp; + cmp = PyObject_Compare(co->co_name, cp->co_name); return cmp; } From gstein@lyra.org Sat Apr 8 13:05:30 2000 From: gstein@lyra.org (Greg Stein) Date: Sat, 8 Apr 2000 05:05:30 -0700 (PDT) Subject: [Patches] fileinput.py argument handling (and suggestion) In-Reply-To: <200004051959.PAA18356@eric.cnri.reston.va.us> Message-ID: On Wed, 5 Apr 2000, Guido van Rossum wrote: > I kind of like the chop switch. Anybody else got an opinion? > > +1 +1 here, too. I usually find it a pain to worry about that darn newline. I might go one further, and ask for a way to *strip* the line, rather than just take the newline off the end. I can't think of a clean way to do so. For example: fileinput.input() fileinput.input(strip=fileinput.STRIP_NL) fileinput.input(strip=fileinput.STRIP_ALL) It just seems a bit wordy, especially compared to the "chop=1" thing. Cheers, -g -- Greg Stein, http://www.lyra.org/ From guido@python.org Sat Apr 8 16:40:06 2000 From: guido@python.org (Guido van Rossum) Date: Sat, 08 Apr 2000 11:40:06 -0400 Subject: [Patches] fileinput.py argument handling (and suggestion) In-Reply-To: Your message of "Sat, 08 Apr 2000 05:05:30 PDT." References: Message-ID: <200004081540.LAA28124@eric.cnri.reston.va.us> > On Wed, 5 Apr 2000, Guido van Rossum wrote: > > I kind of like the chop switch. Anybody else got an opinion? > > > > +1 [Greg Stein] > +1 here, too. I usually find it a pain to worry about that darn newline. > > I might go one further, and ask for a way to *strip* the line, rather than > just take the newline off the end. I can't think of a clean way to do so. > For example: > > fileinput.input() > fileinput.input(strip=fileinput.STRIP_NL) > fileinput.input(strip=fileinput.STRIP_ALL) > > It just seems a bit wordy, especially compared to the "chop=1" thing. fileinput.input(strip=1)? But I think this is going too far. Next we get fileinput.input(lower=1) fileinput.input(split=1) fileinput.input(split=1, sep=':') fileinput.input(split=1, sep=':', maxplit=3) fileinput.input(strip=1, capitalize=1, expandtabs=1) fileinput.input(startswith="#") fileinput.input(find="spam") ... :-) --Guido van Rossum (home page: http://www.python.org/~guido/) From guido@python.org Sat Apr 8 16:41:45 2000 From: guido@python.org (Guido van Rossum) Date: Sat, 08 Apr 2000 11:41:45 -0400 Subject: [Patches] code_compare In-Reply-To: Your message of "Sat, 08 Apr 2000 13:05:39 +0200." <200004081105.NAA28779@python.inrialpes.fr> References: <200004081105.NAA28779@python.inrialpes.fr> Message-ID: <200004081541.LAA28136@eric.cnri.reston.va.us> > *** Python/compile.c-orig Sat Apr 8 11:39:23 2000 > --- Python/compile.c Sat Apr 8 11:39:28 2000 > *************** > *** 153,158 **** > --- 153,160 ---- > cmp = PyObject_Compare(co->co_names, cp->co_names); > if (cmp) return cmp; > cmp = PyObject_Compare(co->co_varnames, cp->co_varnames); > + if (cmp) return cmp; > + cmp = PyObject_Compare(co->co_name, cp->co_name); > return cmp; > } If you compare the name first, sorting a list of code objects would sort them by name first -- whgich is kind of nice. Also, strictly speaking, the hash function should be updated. --Guido van Rossum (home page: http://www.python.org/~guido/) From Vladimir.Marangozov@inrialpes.fr Sat Apr 8 17:18:55 2000 From: Vladimir.Marangozov@inrialpes.fr (Vladimir Marangozov) Date: Sat, 8 Apr 2000 18:18:55 +0200 (CEST) Subject: [Patches] code_compare In-Reply-To: <200004081541.LAA28136@eric.cnri.reston.va.us> from "Guido van Rossum" at Apr 08, 2000 11:41:45 AM Message-ID: <200004081618.SAA01225@python.inrialpes.fr> Guido van Rossum wrote: > > If you compare the name first, sorting a list of code objects would > sort them by name first -- whgich is kind of nice. > > Also, strictly speaking, the hash function should be updated. > Right -- done. -- Add the co_name field comparison to differentiate named code objects, even when their code is the same. This caused side effects for -O because of constant folding, like this one: >>> class C: ... def foo(self): pass ... def bar(self): pass ... >>> C.bar >>> -- Vladimir MARANGOZOV | Vladimir.Marangozov@inrialpes.fr http://sirac.inrialpes.fr/~marangoz | tel:(+33-4)76615277 fax:76615252 -- I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. -------------------------------[ cut here ]--------------------------- *** Python/compile.c-orig Sat Apr 8 11:39:23 2000 --- Python/compile.c Sat Apr 8 18:06:10 2000 *************** *** 140,145 **** --- 140,147 ---- PyCodeObject *co, *cp; { int cmp; + cmp = PyObject_Compare(co->co_name, cp->co_name); + if (cmp) return cmp; cmp = co->co_argcount - cp->co_argcount; if (cmp) return cmp; cmp = co->co_nlocals - cp->co_nlocals; *************** *** 160,175 **** code_hash(co) PyCodeObject *co; { ! long h, h1, h2, h3, h4; ! h1 = PyObject_Hash(co->co_code); if (h1 == -1) return -1; ! h2 = PyObject_Hash(co->co_consts); if (h2 == -1) return -1; ! h3 = PyObject_Hash(co->co_names); if (h3 == -1) return -1; ! h4 = PyObject_Hash(co->co_varnames); if (h4 == -1) return -1; ! h = h1 ^ h2 ^ h3 ^ h4 ^ co->co_argcount ^ co->co_nlocals ^ co->co_flags; if (h == -1) h = -2; return h; --- 162,179 ---- code_hash(co) PyCodeObject *co; { ! long h, h1, h2, h3, h4, h5; ! h1 = PyObject_Hash(co->co_name); if (h1 == -1) return -1; ! h2 = PyObject_Hash(co->co_code); if (h2 == -1) return -1; ! h3 = PyObject_Hash(co->co_consts); if (h3 == -1) return -1; ! h4 = PyObject_Hash(co->co_names); if (h4 == -1) return -1; ! h5 = PyObject_Hash(co->co_varnames); ! if (h5 == -1) return -1; ! h = h1 ^ h2 ^ h3 ^ h4 ^ h5 ^ co->co_argcount ^ co->co_nlocals ^ co->co_flags; if (h == -1) h = -2; return h; From Moshe Zadka Sat Apr 8 18:16:43 2000 From: Moshe Zadka (Moshe Zadka) Date: Sat, 8 Apr 2000 19:16:43 +0200 (IST) Subject: [Patches] fileinput.py argument handling (and suggestion) In-Reply-To: <200004081540.LAA28124@eric.cnri.reston.va.us> Message-ID: On Sat, 8 Apr 2000, Guido van Rossum wrote: > fileinput.input(strip=1)? > > But I think this is going too far. Next we get > > fileinput.input(lower=1) > > fileinput.input(split=1) > > fileinput.input(split=1, sep=':') > > fileinput.input(split=1, sep=':', maxplit=3) > > fileinput.input(strip=1, capitalize=1, expandtabs=1) > > fileinput.input(startswith="#") > > fileinput.input(find="spam") Hmmmm....I'm sure Python is expressive enough to solve this problem in a nice way? How about having the FileInput class documentedy subclassable, and make available some nice mixins? I'm sure such a scheme could work. I'll have to think about it some more -- I'm hoping to come up with something soon. too-much-time-without-a-cute-design-problem-ly y'rs, Z. -- Moshe Zadka . http://www.oreilly.com/news/prescod_0300.html http://www.linux.org.il -- we put the penguin in .com From skip@mojam.com (Skip Montanaro) Sun Apr 9 14:57:59 2000 From: skip@mojam.com (Skip Montanaro) (Skip Montanaro) Date: Sun, 9 Apr 2000 08:57:59 -0500 (CDT) Subject: [Patches] fileinput.py argument handling (and suggestion) In-Reply-To: <200004081540.LAA28124@eric.cnri.reston.va.us> References: <200004081540.LAA28124@eric.cnri.reston.va.us> Message-ID: <14576.35943.88104.517797@beluga.mojam.com> Greg> fileinput.input(strip=fileinput.STRIP_NL) Greg> fileinput.input(strip=fileinput.STRIP_ALL) Guido> fileinput.input(strip=1)? Guido> But I think this is going too far. Agreed. "chop" is a special case where you have to detect different line termination cases on a platform-specific basis. Plain old line stripping is handled just fine by existing functions. Speaking of chop, If I am on a platform X box (X in Unix, Windows, Mac, Be) and try to fileinput.input(chop=1) a file from a different box, will it do the right thing (e.g. recognize ^M as a line termination character on a Unix or Windows machine)? -- Skip Montanaro | http://www.mojam.com/ skip@mojam.com | http://www.musi-cal.com/ From guido@python.org Sun Apr 9 23:18:10 2000 From: guido@python.org (Guido van Rossum) Date: Sun, 09 Apr 2000 18:18:10 -0400 Subject: [Patches] fileinput.py argument handling (and suggestion) In-Reply-To: Your message of "Sun, 09 Apr 2000 08:57:59 CDT." <14576.35943.88104.517797@beluga.mojam.com> References: <200004081540.LAA28124@eric.cnri.reston.va.us> <14576.35943.88104.517797@beluga.mojam.com> Message-ID: <200004092218.SAA28627@eric.cnri.reston.va.us> > Agreed. "chop" is a special case where you have to detect different line > termination cases on a platform-specific basis. Plain old line stripping is > handled just fine by existing functions. Not really. Chop is special because it doesn't exist as a built-in. What we really want is Perl's chomp, which can be coded in Python as def chomp(s): if s[-1:] == '\n': return s[:-1] else: return s Perl's chop() is like s[:-1], and steals the last character of the file if it is not a newline. The CR-LF issue is taken care of at a different level: > Speaking of chop, If I am on a platform X box (X in Unix, Windows, Mac, Be) > and try to fileinput.input(chop=1) a file from a different box, will it do > the right thing (e.g. recognize ^M as a line termination character on a Unix > or Windows machine)? Currently, it won't. A good change for Python would be for files opened for reading in text mode (on all platforms!) to use Java's algorithm (line terminators are either CR, LF or CRLF) but to translate all three kinds of terminator into \n, so that Python code can be written to look for \n everywhere. (This is the intention of the current text mode too, but it fails when a file uses another platform's convention.) --Guido van Rossum (home page: http://www.python.org/~guido/) From guido@python.org Sun Apr 9 23:40:21 2000 From: guido@python.org (Guido van Rossum) Date: Sun, 09 Apr 2000 18:40:21 -0400 Subject: [Patches] Fix main Makefile to create prefix, exec_prefix In-Reply-To: Your message of "Sat, 08 Apr 2000 01:05:20 EDT." <14574.48656.133609.387194@seahag.cnri.reston.va.us> References: <20000407181732.A11360@mems-exchange.org> <14574.48656.133609.387194@seahag.cnri.reston.va.us> Message-ID: <200004092240.SAA28776@eric.cnri.reston.va.us> > Greg Ward writes: > > This patch fixes the top Python Makefile so it creates $(prefix) or > > $(exec_prefix) before attempting to create directories under them. > > Handy when you use prefixes like "/usr/local/python-1.5.2" and > > "/usr/local/python-1.6a1", which don't exist until you install Python > > I say check it in. If Guido disagrees he can yell/email about it > later; this is quite reasonable given the recent discussion of "stow" > and the need of developers to keep multiple versions (including patch > levels!) installed. I still don't like it. Let's discuss this face-to-face. My argument why it doesn't do this (where I know that it easily could!) is that if root makes a typo and says make install prefix=/usr/kocal it will happily create /usr/kocal. I think this is bad. --Guido van Rossum (home page: http://www.python.org/~guido/) From mhammond@skippinet.com.au Mon Apr 10 04:06:14 2000 From: mhammond@skippinet.com.au (Mark Hammond) Date: Mon, 10 Apr 2000 13:06:14 +1000 Subject: [Patches] Change to attribute error message for instances. Message-ID: In line with a similar checkin to object.c a while ago, this patch gives a more descriptive error message for an attribute error on a class instance. The message now looks like: AttributeError: 'Descriptor' instance has no attribute 'GetReturnType' [Maybe the module name would also be useful, but IMO this is fine and a nice improvement] Release info: I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. Mark. diff -c -2 -r2.83 classobject.c *** classobject.c 2000/02/28 15:03:15 2.83 --- classobject.c 2000/04/10 03:01:08 *************** *** 593,597 **** v = class_lookup(inst->in_class, name, &class); if (v == NULL) { ! PyErr_SetObject(PyExc_AttributeError, name); return NULL; } --- 593,600 ---- v = class_lookup(inst->in_class, name, &class); if (v == NULL) { ! PyErr_Format(PyExc_AttributeError, ! "'%.50s' instance has no attribute '%.400s'", ! PyString_AsString(inst->in_class->cl_name), ! sname); return NULL; } From mal@lemburg.com Mon Apr 10 10:51:44 2000 From: mal@lemburg.com (M.-A. Lemburg) Date: Mon, 10 Apr 2000 11:51:44 +0200 Subject: [Patches] Unicode Patch Set 2000-04-10 Message-ID: <38F1A430.D70DF89@lemburg.com> This is a multi-part message in MIME format. --------------3642FC2D466120215DDB5BCE Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit The attached patch includes the following fixes and additions: * More test cases for test_contains.py. * New exported API PyUnicode_Resize() * '...%s...' % u"abc" now coerces to Unicode just like string methods. Care is taken not to reevaluate already formatted arguments -- only the first Unicode object appearing in the argument mapping is looked up twice. Added test cases for this to test_unicode.py. * TypeErrors during comparing of mixed type arguments including a Unicode object are now masked (just like they are for all other combinations). * The experimental Keep-Alive optimization was turned back on after some tweaks to the implementation. It should now work without causing core dumps... this has yet to tested though (switching it off is easy: see the unicodeobject.c file for details). * Fixed a memory leak in the Unicode freelist cleanup code. * Added tests to correctly process the return code from _PyUnicode_Resize(). * Fixed a bug in the 'ignore' error handling routines of some builtin codecs. Added test cases for these to test_unicode.py. -- Marc-Andre Lemburg ______________________________________________________________________ Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ --------------3642FC2D466120215DDB5BCE Content-Type: text/plain; charset=iso-8859-1; name="Unicode-Implementation-2000-04-10.patch" Content-Transfer-Encoding: 8bit Content-Disposition: inline; filename="Unicode-Implementation-2000-04-10.patch" diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x distutils -x PC -x PCbuild -x *.py CVS-Python/Include/unicodeobject.h Python+Unicode/Include/unicodeobject.h --- CVS-Python/Include/unicodeobject.h Thu Apr 6 10:00:22 2000 +++ Python+Unicode/Include/unicodeobject.h Sat Apr 8 12:56:27 2000 @@ -237,6 +237,25 @@ PyObject *unicode /* Unicode object */ ); +/* Resize an already allocated Unicode object to the new size length. + + *unicode is modified to point to the new (resized) object and 0 + returned on success. + + This API may only be called by the function which also called the + Unicode constructor. The refcount on the object must be 1. Otherwise, + an error is returned. + + Error handling is implemented as follows: an exception is set, -1 + is returned and *unicode left untouched. + +*/ + +extern DL_IMPORT(int) PyUnicode_Resize( + PyObject **unicode, /* Pointer to the Unicode object */ + int length /* New length */ + ); + /* Coerce obj to an Unicode object and return a reference with *incremented* refcount. diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x distutils -x PC -x PCbuild -x *.py CVS-Python/Objects/object.c Python+Unicode/Objects/object.c --- CVS-Python/Objects/object.c Tue Mar 28 09:19:17 2000 +++ Python+Unicode/Objects/object.c Wed Apr 5 02:44:28 2000 @@ -347,8 +347,21 @@ return cmp; } } - else if (PyUnicode_Check(v) || PyUnicode_Check(w)) - return PyUnicode_Compare(v, w); + else if (PyUnicode_Check(v) || PyUnicode_Check(w)) { + int result = PyUnicode_Compare(v, w); + if (result == -1 && PyErr_Occurred() && + PyErr_ExceptionMatches(PyExc_TypeError)) + /* TypeErrors are ignored: if Unicode coercion + fails due to one of the arguments not + having the right type, we continue as + defined by the coercion protocol (see + above). Luckily, decoding errors are + reported as ValueErrors and are not masked + by this technique. */ + PyErr_Clear(); + else + return result; + } else if (vtp->tp_as_number != NULL) vname = ""; else if (wtp->tp_as_number != NULL) diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x distutils -x PC -x PCbuild -x *.py CVS-Python/Objects/stringobject.c Python+Unicode/Objects/stringobject.c --- CVS-Python/Objects/stringobject.c Fri Mar 24 00:01:30 2000 +++ Python+Unicode/Objects/stringobject.c Sat Apr 8 01:04:08 2000 @@ -389,9 +389,9 @@ { register char *s, *end; register char c; - if (!PyString_Check(el)) + if (PyUnicode_Check(el)) return PyUnicode_Contains(a, el); - if (PyString_Size(el) != 1) { + if (!PyString_Check(el) || PyString_Size(el) != 1) { PyErr_SetString(PyExc_TypeError, "string member test needs char left operand"); return -1; @@ -2384,12 +2384,13 @@ char *fmt, *res; int fmtcnt, rescnt, reslen, arglen, argidx; int args_owned = 0; - PyObject *result; + PyObject *result, *orig_args; PyObject *dict = NULL; if (format == NULL || !PyString_Check(format) || args == NULL) { PyErr_BadInternalCall(); return NULL; } + orig_args = args; fmt = PyString_AsString(format); fmtcnt = PyString_Size(format); reslen = rescnt = fmtcnt + 100; @@ -2434,6 +2435,8 @@ int sign; int len; char tmpbuf[120]; /* For format{float,int,char}() */ + char *fmt_start = fmt; + fmt++; if (*fmt == '(') { char *keystart; @@ -2584,6 +2587,10 @@ break; case 's': case 'r': + if (PyUnicode_Check(v)) { + fmt = fmt_start; + goto unicode; + } if (c == 's') temp = PyObject_Str(v); else @@ -2716,6 +2723,47 @@ } _PyString_Resize(&result, reslen - rescnt); return result; + + unicode: + if (args_owned) { + Py_DECREF(args); + args_owned = 0; + } + /* Fiddle args right (remove the first argidx-1 arguments) */ + --argidx; + if (PyTuple_Check(orig_args) && argidx > 0) { + PyObject *v; + int n = PyTuple_GET_SIZE(orig_args) - argidx; + v = PyTuple_New(n); + if (v == NULL) + goto error; + while (--n >= 0) { + PyObject *w = PyTuple_GET_ITEM(orig_args, n + argidx); + Py_INCREF(w); + PyTuple_SET_ITEM(v, n, w); + } + args = v; + } else { + Py_INCREF(orig_args); + args = orig_args; + } + /* Paste rest of format string to what we have of the result + string; we reuse result for this */ + rescnt = res - PyString_AS_STRING(result); + fmtcnt = PyString_GET_SIZE(format) - \ + (fmt - PyString_AS_STRING(format)); + if (_PyString_Resize(&result, rescnt + fmtcnt)) { + Py_DECREF(args); + goto error; + } + memcpy(PyString_AS_STRING(result) + rescnt, fmt, fmtcnt); + format = result; + /* Let Unicode do its magic */ + result = PyUnicode_Format(format, args); + Py_DECREF(format); + Py_DECREF(args); + return result; + error: Py_DECREF(result); if (args_owned) { diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x distutils -x PC -x PCbuild -x *.py CVS-Python/Objects/unicodeobject.c Python+Unicode/Objects/unicodeobject.c --- CVS-Python/Objects/unicodeobject.c Mon Apr 10 11:22:21 2000 +++ Python+Unicode/Objects/unicodeobject.c Sat Apr 8 14:23:58 2000 @@ -76,6 +76,7 @@ #ifdef MS_WIN32 #include #endif + /* Limit for the Unicode object free list */ #define MAX_UNICODE_FREELIST_SIZE 1024 @@ -87,18 +88,17 @@ limit. This reduces malloc() overhead for small Unicode objects. At worst this will result in MAX_UNICODE_FREELIST_SIZE * - (sizeof(PyUnicodeObject) + STAYALIVE_SIZE_LIMIT + + (sizeof(PyUnicodeObject) + KEEPALIVE_SIZE_LIMIT + malloc()-overhead) bytes of unused garbage. Setting the limit to 0 effectively turns the feature off. - XXX The feature is currently turned off because there are - apparently some lingering bugs in its implementation which I - haven't yet been able to sort out. + Note: This is an experimental feature ! If you get core dumps when + using Unicode objects, turn this feature off. */ -#define STAYALIVE_SIZE_LIMIT 0 +#define KEEPALIVE_SIZE_LIMIT 9 /* Endianness switches; defaults to little endian */ @@ -125,9 +125,9 @@ { void *oldstr; - /* Shortcut if there's nothing to do. */ + /* Shortcut if there's nothing much to do. */ if (unicode->length == length) - return 0; + goto reset; /* Resizing unicode_empty is not allowed. */ if (unicode == unicode_empty) { @@ -148,6 +148,7 @@ unicode->str[length] = 0; unicode->length = length; + reset: /* Reset the object caches */ if (unicode->utf8str) { Py_DECREF(unicode->utf8str); @@ -158,6 +159,23 @@ return 0; } +int PyUnicode_Resize(PyObject **unicode, + int length) +{ + PyUnicodeObject *v; + + if (unicode == NULL) { + PyErr_BadInternalCall(); + return -1; + } + v = (PyUnicodeObject *)*unicode; + if (v == NULL || !PyUnicode_Check(v) || v->ob_refcnt != 1) { + PyErr_BadInternalCall(); + return -1; + } + return _PyUnicode_Resize(v, length); +} + /* We allocate one more byte to make sure the string is Ux0000 terminated -- XXX is this needed ? @@ -185,7 +203,9 @@ unicode->ob_type = &PyUnicode_Type; _Py_NewReference((PyObject *)unicode); if (unicode->str) { - if (unicode->length < length && + /* Keep-Alive optimization: we only upsize the buffer, + never downsize it. */ + if ((unicode->length < length) && _PyUnicode_Resize(unicode, length)) { free(unicode->str); PyMem_DEL(unicode); @@ -220,19 +240,25 @@ static void _PyUnicode_Free(register PyUnicodeObject *unicode) { - Py_XDECREF(unicode->utf8str); if (unicode_freelist_size < MAX_UNICODE_FREELIST_SIZE) { - if (unicode->length >= STAYALIVE_SIZE_LIMIT) { + /* Keep-Alive optimization */ + if (unicode->length >= KEEPALIVE_SIZE_LIMIT) { free(unicode->str); unicode->str = NULL; unicode->length = 0; } + if (unicode->utf8str) { + Py_DECREF(unicode->utf8str); + unicode->utf8str = NULL; + } + /* Add to free list */ *(PyUnicodeObject **)unicode = unicode_freelist; unicode_freelist = unicode; unicode_freelist_size++; } else { free(unicode->str); + Py_XDECREF(unicode->utf8str); PyMem_DEL(unicode); } } @@ -665,7 +691,8 @@ } } *p = '\0'; - _PyString_Resize(&v, p - q); + if (_PyString_Resize(&v, p - q)) + goto onError; done: return v; @@ -1047,7 +1074,8 @@ break; } } - _PyUnicode_Resize(v, (int)(p - buf)); + if (_PyUnicode_Resize(v, (int)(p - buf))) + goto onError; return (PyObject *)v; onError: @@ -1119,9 +1147,14 @@ *p++ = q[1]; *p = '\0'; - _PyString_Resize(&repr, p - q); + if (_PyString_Resize(&repr, p - q)) + goto onError; return repr; + + onError: + Py_DECREF(repr); + return NULL; } PyObject *PyUnicode_EncodeUnicodeEscape(const Py_UNICODE *s, @@ -1209,7 +1242,8 @@ s += i; *p++ = x; } - _PyUnicode_Resize(v, (int)(p - buf)); + if (_PyUnicode_Resize(v, (int)(p - buf))) + goto onError; return (PyObject *)v; onError: @@ -1247,9 +1281,14 @@ *p++ = (char) ch; } *p = '\0'; - _PyString_Resize(&repr, p - q); + if (_PyString_Resize(&repr, p - q)) + goto onError; return repr; + + onError: + Py_DECREF(repr); + return NULL; } PyObject *PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode) @@ -1305,6 +1344,7 @@ } else if (strcmp(errors,"replace") == 0) { **dest = '?'; + (*dest)++; return 0; } else { @@ -1321,12 +1361,13 @@ const char *errors) { PyObject *repr; - char *s; + char *s, *start; repr = PyString_FromStringAndSize(NULL, size); if (repr == NULL) return NULL; s = PyString_AS_STRING(repr); + start = s; while (size-- > 0) { Py_UNICODE ch = *p++; if (ch >= 256) { @@ -1337,6 +1378,10 @@ else *s++ = (char)ch; } + /* Resize if error handling skipped some characters */ + if (s - start < PyString_GET_SIZE(repr)) + if (_PyString_Resize(&repr, s - start)) + goto onError; return repr; onError: @@ -1411,8 +1456,9 @@ "ordinal not in range(128)")) goto onError; } - if (p - PyUnicode_AS_UNICODE(v) < size) - _PyUnicode_Resize(v, (int)(p - PyUnicode_AS_UNICODE(v))); + if (p - PyUnicode_AS_UNICODE(v) < PyString_GET_SIZE(v)) + if (_PyUnicode_Resize(v, (int)(p - PyUnicode_AS_UNICODE(v)))) + goto onError; return (PyObject *)v; onError: @@ -1438,6 +1484,7 @@ } else if (strcmp(errors,"replace") == 0) { **dest = '?'; + (*dest)++; return 0; } else { @@ -1454,12 +1501,13 @@ const char *errors) { PyObject *repr; - char *s; + char *s, *start; repr = PyString_FromStringAndSize(NULL, size); if (repr == NULL) return NULL; s = PyString_AS_STRING(repr); + start = s; while (size-- > 0) { Py_UNICODE ch = *p++; if (ch >= 128) { @@ -1470,6 +1518,10 @@ else *s++ = (char)ch; } + /* Resize if error handling skipped some characters */ + if (s - start < PyString_GET_SIZE(repr)) + if (_PyString_Resize(&repr, s - start)) + goto onError; return repr; onError: @@ -1898,7 +1950,8 @@ Py_DECREF(x); } if (p - PyUnicode_AS_UNICODE(v) < PyUnicode_GET_SIZE(v)) - _PyUnicode_Resize(v, (int)(p - PyUnicode_AS_UNICODE(v))); + if (_PyUnicode_Resize(v, (int)(p - PyUnicode_AS_UNICODE(v)))) + goto onError; done: return (PyObject *)v; @@ -1959,7 +2012,7 @@ continue; } if (0 < ch && ch < 256) { - *output++ = (char) ch; + *output++ = ch; continue; } /* All other characters are considered invalid */ @@ -4539,7 +4592,8 @@ Py_DECREF(args); } Py_DECREF(uformat); - _PyUnicode_Resize(result, reslen - rescnt); + if (_PyUnicode_Resize(result, reslen - rescnt)) + goto onError; return (PyObject *)result; onError: @@ -4605,6 +4659,9 @@ while (u != NULL) { PyUnicodeObject *v = u; u = *(PyUnicodeObject **)u; + if (v->str) + free(v->str); + Py_XDECREF(v->utf8str); free(v); } Py_XDECREF(unicode_empty); diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x distutils -x PC -x PCbuild -x *.c -x *.h -x *.in -x output CVS-Python/Lib/test/test_contains.py Python+Unicode/Lib/test/test_contains.py --- CVS-Python/Lib/test/test_contains.py Tue Mar 7 16:52:01 2000 +++ Python+Unicode/Lib/test/test_contains.py Wed Apr 5 11:23:44 2000 @@ -17,7 +17,7 @@ def check(ok, *args): if not ok: - raise TestFailed, join(map(str, args), " ") + raise TestFailed, " ".join(map(str, args)) a = base_set(1) b = set(1) @@ -60,5 +60,62 @@ try: None in 'abc' check(0, "None in 'abc' did not raise error") +except TypeError: + pass + +# Test char in Unicode + +check('c' in u'abc', "'c' not in u'abc'") +check('d' not in u'abc', "'d' in u'abc'") + +try: + '' in u'abc' + check(0, "'' in u'abc' did not raise error") +except TypeError: + pass + +try: + 'ab' in u'abc' + check(0, "'ab' in u'abc' did not raise error") +except TypeError: + pass + +try: + None in u'abc' + check(0, "None in u'abc' did not raise error") +except TypeError: + pass + +# Test Unicode char in Unicode + +check(u'c' in u'abc', "u'c' not in u'abc'") +check(u'd' not in u'abc', "u'd' in u'abc'") + +try: + u'' in u'abc' + check(0, "u'' in u'abc' did not raise error") +except TypeError: + pass + +try: + u'ab' in u'abc' + check(0, "u'ab' in u'abc' did not raise error") +except TypeError: + pass + +# Test Unicode char in string + +check(u'c' in 'abc', "u'c' not in 'abc'") +check(u'd' not in 'abc', "u'd' in 'abc'") + +try: + u'' in 'abc' + check(0, "u'' in 'abc' did not raise error") +except TypeError: + pass + +try: + u'ab' in 'abc' + check(0, "u'ab' in 'abc' did not raise error") except TypeError: pass diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x distutils -x PC -x PCbuild -x *.c -x *.h -x *.in -x output CVS-Python/Lib/test/test_unicode.py Python+Unicode/Lib/test/test_unicode.py --- CVS-Python/Lib/test/test_unicode.py Thu Apr 6 10:00:25 2000 +++ Python+Unicode/Lib/test/test_unicode.py Sat Apr 8 00:52:42 2000 @@ -255,6 +255,15 @@ assert u"%r, %r" % (u"abc", "abc") == u"u'abc', 'abc'" assert u"%(x)s, %(y)s" % {'x':u"abc", 'y':"def"} == u'abc, def' assert u"%(x)s, %(ä)s" % {'x':u"abc", u'ä'.encode('utf-8'):"def"} == u'abc, def' +# formatting jobs delegated from the string implementation: +assert '...%(foo)s...' % {'foo':u"abc"} == u'...abc...' +assert '...%(foo)s...' % {'foo':"abc"} == '...abc...' +assert '...%(foo)s...' % {u'foo':"abc"} == '...abc...' +assert '...%(foo)s...' % {u'foo':u"abc"} == u'...abc...' +assert '...%(foo)s...' % {u'foo':u"abc",'def':123} == u'...abc...' +assert '...%(foo)s...' % {u'foo':u"abc",u'def':123} == u'...abc...' +assert '...%s...%s...%s...%s...' % (1,2,3,u"abc") == u'...1...2...3...abc...' +assert '...%s...' % u"abc" == u'...abc...' print 'done.' # Test builtin codecs @@ -264,6 +273,26 @@ assert unicode('hello','utf-8') == u'hello' assert unicode('hello','utf8') == u'hello' assert unicode('hello','latin-1') == u'hello' + +try: + u'Andr\202 x'.encode('ascii') + u'Andr\202 x'.encode('ascii','strict') +except ValueError: + pass +else: + raise AssertionError, "u'Andr\202'.encode('ascii') failed to raise an exception" +assert u'Andr\202 x'.encode('ascii','ignore') == "Andr x" +assert u'Andr\202 x'.encode('ascii','replace') == "Andr? x" + +try: + unicode('Andr\202 x','ascii') + unicode('Andr\202 x','ascii','strict') +except ValueError: + pass +else: + raise AssertionError, "unicode('Andr\202') failed to raise an exception" +assert unicode('Andr\202 x','ascii','ignore') == u"Andr x" +assert unicode('Andr\202 x','ascii','replace') == u'Andr\uFFFD x' assert u'hello'.encode('ascii') == 'hello' assert u'hello'.encode('utf-8') == 'hello' --------------3642FC2D466120215DDB5BCE-- From gstein@lyra.org Mon Apr 10 10:53:48 2000 From: gstein@lyra.org (Greg Stein) Date: Mon, 10 Apr 2000 02:53:48 -0700 (PDT) Subject: [Patches] Unicode Patch Set 2000-04-10 In-Reply-To: <38F1A430.D70DF89@lemburg.com> Message-ID: On Mon, 10 Apr 2000, M.-A. Lemburg wrote: > The attached patch includes the following fixes and additions: >... > * '...%s...' % u"abc" now coerces to Unicode just like > string methods. Care is taken not to reevaluate already formatted > arguments -- only the first Unicode object appearing in the > argument mapping is looked up twice. Added test cases for > this to test_unicode.py. >... I missed a chance to bring this up on the first round of discussion, but is this really the right thing to do? We never coerce the string on the left based on operands. For example: if the operands are class instances, we call __str__ -- we don't call __coerce__. It seems a bit weird to magically revise the left operand. In many cases, a Unicode used as a string is used as a UTF-8 value. Why is that different in this case? Seems like a wierd special case. Cheers, -g -- Greg Stein, http://www.lyra.org/ From mal@lemburg.com Mon Apr 10 11:55:50 2000 From: mal@lemburg.com (M.-A. Lemburg) Date: Mon, 10 Apr 2000 12:55:50 +0200 Subject: [Python-Dev] Re: [Patches] Unicode Patch Set 2000-04-10 References: Message-ID: <38F1B336.12B6707@lemburg.com> Greg Stein wrote: > > On Mon, 10 Apr 2000, M.-A. Lemburg wrote: > > The attached patch includes the following fixes and additions: > >... > > * '...%s...' % u"abc" now coerces to Unicode just like > > string methods. Care is taken not to reevaluate already formatted > > arguments -- only the first Unicode object appearing in the > > argument mapping is looked up twice. Added test cases for > > this to test_unicode.py. > >... > > I missed a chance to bring this up on the first round of discussion, but > is this really the right thing to do? We never coerce the string on the > left based on operands. For example: if the operands are class instances, > we call __str__ -- we don't call __coerce__. > > It seems a bit weird to magically revise the left operand. > > In many cases, a Unicode used as a string is used as a UTF-8 value. Why is > that different in this case? Seems like a wierd special case. It's not a special case: % works just like a method call and all string methods auto-coerce to Unicode in case a Unicode object is found among the arguments. -- Marc-Andre Lemburg ______________________________________________________________________ Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ From skip@mojam.com (Skip Montanaro) Mon Apr 10 12:13:24 2000 From: skip@mojam.com (Skip Montanaro) (Skip Montanaro) Date: Mon, 10 Apr 2000 06:13:24 -0500 Subject: [Patches] add string precisions to PyErr_Format calls Message-ID: <200004101113.GAA09190@beluga.mojam.com> The following attachments add string precisions to a number of calls to PyErr_Format to prevent possible buffer overruns. I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. -- Skip Montanaro | http://www.mojam.com/ skip@mojam.com | http://www.musi-cal.com/ [ATTACHMENT ~/src/python/dist/src/Objects/object.c.diff, text/plain] [ATTACHMENT ~/src/python/dist/src/Objects/unicodeobject.c.diff, text/plain] [ATTACHMENT ~/src/python/dist/src/Modules/pyexpat.c.diff, text/plain] [ATTACHMENT ~/src/python/dist/src/Python/dynload_next.c.diff, text/plain] [ATTACHMENT ~/src/python/dist/src/Python/ceval.c.diff, text/plain] From skip@mojam.com (Skip Montanaro) Mon Apr 10 12:22:58 2000 From: skip@mojam.com (Skip Montanaro) (Skip Montanaro) Date: Mon, 10 Apr 2000 06:22:58 -0500 (CDT) Subject: [Patches] add string precisions to PyErr_Format calls In-Reply-To: <200004101113.GAA09190@beluga.mojam.com> References: <200004101113.GAA09190@beluga.mojam.com> Message-ID: <14577.47506.14149.790979@beluga.mojam.com> Skip> [ATTACHMENT ~/src/python/dist/src/Objects/object.c.diff, text/plain] Skip> [ATTACHMENT ~/src/python/dist/src/Objects/unicodeobject.c.diff, text/plain] Skip> [ATTACHMENT ~/src/python/dist/src/Modules/pyexpat.c.diff, text/plain] Skip> [ATTACHMENT ~/src/python/dist/src/Python/dynload_next.c.diff, text/plain] Skip> [ATTACHMENT ~/src/python/dist/src/Python/ceval.c.diff, text/plain] Ack! The attachments didn't attach! Here they are as plain text appended one after the other... Skip *** /tmp/object.c.~2.65~ Mon Apr 10 06:01:08 2000 --- /tmp/object.c Mon Apr 10 06:01:08 2000 *************** *** 236,242 **** return NULL; if (!PyString_Check(res)) { PyErr_Format(PyExc_TypeError, ! "__repr__ returned non-string (type %s)", res->ob_type->tp_name); Py_DECREF(res); return NULL; --- 236,242 ---- return NULL; if (!PyString_Check(res)) { PyErr_Format(PyExc_TypeError, ! "__repr__ returned non-string (type %.200s)", res->ob_type->tp_name); Py_DECREF(res); return NULL; *************** *** 273,279 **** return NULL; if (!PyString_Check(res)) { PyErr_Format(PyExc_TypeError, ! "__str__ returned non-string (type %s)", res->ob_type->tp_name); Py_DECREF(res); return NULL; --- 273,279 ---- return NULL; if (!PyString_Check(res)) { PyErr_Format(PyExc_TypeError, ! "__str__ returned non-string (type %.200s)", res->ob_type->tp_name); Py_DECREF(res); return NULL; *** /tmp/unicodeobject.c.~2.8~ Mon Apr 10 06:04:11 2000 --- /tmp/unicodeobject.c Mon Apr 10 06:04:11 2000 *************** *** 365,371 **** goto onError; if (!PyUnicode_Check(unicode)) { PyErr_Format(PyExc_TypeError, ! "decoder did not return an unicode object (type=%s)", unicode->ob_type->tp_name); Py_DECREF(unicode); goto onError; --- 365,371 ---- goto onError; if (!PyUnicode_Check(unicode)) { PyErr_Format(PyExc_TypeError, ! "decoder did not return an unicode object (type=%.400s)", unicode->ob_type->tp_name); Py_DECREF(unicode); goto onError; *************** *** 416,422 **** /* XXX Should we really enforce this ? */ if (!PyString_Check(v)) { PyErr_Format(PyExc_TypeError, ! "encoder did not return a string object (type=%s)", v->ob_type->tp_name); Py_DECREF(v); goto onError; --- 416,422 ---- /* XXX Should we really enforce this ? */ if (!PyString_Check(v)) { PyErr_Format(PyExc_TypeError, ! "encoder did not return a string object (type=%.400s)", v->ob_type->tp_name); Py_DECREF(v); goto onError; *************** *** 484,490 **** if ((errors == NULL) || (strcmp(errors,"strict") == 0)) { PyErr_Format(PyExc_UnicodeError, ! "UTF-8 decoding error: %s", details); return -1; } --- 484,490 ---- if ((errors == NULL) || (strcmp(errors,"strict") == 0)) { PyErr_Format(PyExc_UnicodeError, ! "UTF-8 decoding error: %.400s", details); return -1; } *************** *** 500,506 **** } else { PyErr_Format(PyExc_ValueError, ! "UTF-8 decoding error; unknown error handling code: %s", errors); return -1; } --- 500,506 ---- } else { PyErr_Format(PyExc_ValueError, ! "UTF-8 decoding error; unknown error handling code: %.400s", errors); return -1; } *************** *** 607,613 **** if ((errors == NULL) || (strcmp(errors,"strict") == 0)) { PyErr_Format(PyExc_UnicodeError, ! "UTF-8 encoding error: %s", details); return -1; } --- 607,613 ---- if ((errors == NULL) || (strcmp(errors,"strict") == 0)) { PyErr_Format(PyExc_UnicodeError, ! "UTF-8 encoding error: %.400s", details); return -1; } *************** *** 622,628 **** else { PyErr_Format(PyExc_ValueError, "UTF-8 encoding error; " ! "unknown error handling code: %s", errors); return -1; } --- 622,628 ---- else { PyErr_Format(PyExc_ValueError, "UTF-8 encoding error; " ! "unknown error handling code: %.400s", errors); return -1; } *************** *** 728,734 **** if ((errors == NULL) || (strcmp(errors,"strict") == 0)) { PyErr_Format(PyExc_UnicodeError, ! "UTF-16 decoding error: %s", details); return -1; } --- 728,734 ---- if ((errors == NULL) || (strcmp(errors,"strict") == 0)) { PyErr_Format(PyExc_UnicodeError, ! "UTF-16 decoding error: %.400s", details); return -1; } *************** *** 744,750 **** } else { PyErr_Format(PyExc_ValueError, ! "UTF-16 decoding error; unknown error handling code: %s", errors); return -1; } --- 744,750 ---- } else { PyErr_Format(PyExc_ValueError, ! "UTF-16 decoding error; unknown error handling code: %.400s", errors); return -1; } *************** *** 918,924 **** if ((errors == NULL) || (strcmp(errors,"strict") == 0)) { PyErr_Format(PyExc_UnicodeError, ! "Unicode-Escape decoding error: %s", details); return -1; } --- 918,924 ---- if ((errors == NULL) || (strcmp(errors,"strict") == 0)) { PyErr_Format(PyExc_UnicodeError, ! "Unicode-Escape decoding error: %.400s", details); return -1; } *************** *** 932,938 **** else { PyErr_Format(PyExc_ValueError, "Unicode-Escape decoding error; " ! "unknown error handling code: %s", errors); return -1; } --- 932,938 ---- else { PyErr_Format(PyExc_ValueError, "Unicode-Escape decoding error; " ! "unknown error handling code: %.400s", errors); return -1; } *************** *** 1296,1302 **** if ((errors == NULL) || (strcmp(errors,"strict") == 0)) { PyErr_Format(PyExc_UnicodeError, ! "Latin-1 encoding error: %s", details); return -1; } --- 1296,1302 ---- if ((errors == NULL) || (strcmp(errors,"strict") == 0)) { PyErr_Format(PyExc_UnicodeError, ! "Latin-1 encoding error: %.400s", details); return -1; } *************** *** 1310,1316 **** else { PyErr_Format(PyExc_ValueError, "Latin-1 encoding error; " ! "unknown error handling code: %s", errors); return -1; } --- 1310,1316 ---- else { PyErr_Format(PyExc_ValueError, "Latin-1 encoding error; " ! "unknown error handling code: %.400s", errors); return -1; } *************** *** 1366,1372 **** if ((errors == NULL) || (strcmp(errors,"strict") == 0)) { PyErr_Format(PyExc_UnicodeError, ! "ASCII decoding error: %s", details); return -1; } --- 1366,1372 ---- if ((errors == NULL) || (strcmp(errors,"strict") == 0)) { PyErr_Format(PyExc_UnicodeError, ! "ASCII decoding error: %.400s", details); return -1; } *************** *** 1381,1387 **** else { PyErr_Format(PyExc_ValueError, "ASCII decoding error; " ! "unknown error handling code: %s", errors); return -1; } --- 1381,1387 ---- else { PyErr_Format(PyExc_ValueError, "ASCII decoding error; " ! "unknown error handling code: %.400s", errors); return -1; } *************** *** 1429,1435 **** if ((errors == NULL) || (strcmp(errors,"strict") == 0)) { PyErr_Format(PyExc_UnicodeError, ! "ASCII encoding error: %s", details); return -1; } --- 1429,1435 ---- if ((errors == NULL) || (strcmp(errors,"strict") == 0)) { PyErr_Format(PyExc_UnicodeError, ! "ASCII encoding error: %.400s", details); return -1; } *************** *** 1443,1449 **** else { PyErr_Format(PyExc_ValueError, "ASCII encoding error; " ! "unknown error handling code: %s", errors); return -1; } --- 1443,1449 ---- else { PyErr_Format(PyExc_ValueError, "ASCII encoding error; " ! "unknown error handling code: %.400s", errors); return -1; } *************** *** 1558,1564 **** if ((errors == NULL) || (strcmp(errors,"strict") == 0)) { PyErr_Format(PyExc_UnicodeError, ! "charmap decoding error: %s", details); return -1; } --- 1558,1564 ---- if ((errors == NULL) || (strcmp(errors,"strict") == 0)) { PyErr_Format(PyExc_UnicodeError, ! "charmap decoding error: %.400s", details); return -1; } *************** *** 1573,1579 **** else { PyErr_Format(PyExc_ValueError, "charmap decoding error; " ! "unknown error handling code: %s", errors); return -1; } --- 1573,1579 ---- else { PyErr_Format(PyExc_ValueError, "charmap decoding error; " ! "unknown error handling code: %.400s", errors); return -1; } *************** *** 1674,1680 **** if ((errors == NULL) || (strcmp(errors,"strict") == 0)) { PyErr_Format(PyExc_UnicodeError, ! "charmap encoding error: %s", details); return -1; } --- 1674,1680 ---- if ((errors == NULL) || (strcmp(errors,"strict") == 0)) { PyErr_Format(PyExc_UnicodeError, ! "charmap encoding error: %.400s", details); return -1; } *************** *** 1689,1695 **** else { PyErr_Format(PyExc_ValueError, "charmap encoding error; " ! "unknown error handling code: %s", errors); return -1; } --- 1689,1695 ---- else { PyErr_Format(PyExc_ValueError, "charmap encoding error; " ! "unknown error handling code: %.400s", errors); return -1; } *************** *** 1806,1812 **** if ((errors == NULL) || (strcmp(errors,"strict") == 0)) { PyErr_Format(PyExc_UnicodeError, ! "translate error: %s", details); return -1; } --- 1806,1812 ---- if ((errors == NULL) || (strcmp(errors,"strict") == 0)) { PyErr_Format(PyExc_UnicodeError, ! "translate error: %.400s", details); return -1; } *************** *** 1821,1827 **** else { PyErr_Format(PyExc_ValueError, "translate error; " ! "unknown error handling code: %s", errors); return -1; } --- 1821,1827 ---- else { PyErr_Format(PyExc_ValueError, "translate error; " ! "unknown error handling code: %.400s", errors); return -1; } *** /tmp/pyexpat.c.~2.2~ Mon Apr 10 06:01:33 2000 --- /tmp/pyexpat.c Mon Apr 10 06:01:33 2000 *************** *** 307,313 **** return NULL; } else if (rv == 0) { ! PyErr_Format(ErrorObject, "%s: line %i, column %i", XML_ErrorString( XML_GetErrorCode(self->itself) ), XML_GetErrorLineNumber(self->itself), XML_GetErrorColumnNumber(self->itself) ); --- 307,313 ---- return NULL; } else if (rv == 0) { ! PyErr_Format(ErrorObject, "%.200s: line %i, column %i", XML_ErrorString( XML_GetErrorCode(self->itself) ), XML_GetErrorLineNumber(self->itself), XML_GetErrorColumnNumber(self->itself) ); *** /tmp/dynload_next.c.~2.2~-YCj-2 Mon Apr 10 06:00:09 2000 --- /tmp/dynload_next.c-YCVIG Mon Apr 10 06:00:09 2000 *************** *** 185,191 **** if (!NSIsSymbolNameDefined(funcname)) { /* UnlinkModule() isn't implimented in current versions, but calling it does no harm */ NSUnLinkModule(newModule, FALSE); ! PyErr_Format(PyExc_ImportError, "Loaded module does not contain symbol %s", funcname); return NULL; } theSym = NSLookupAndBindSymbol(funcname); --- 185,193 ---- if (!NSIsSymbolNameDefined(funcname)) { /* UnlinkModule() isn't implimented in current versions, but calling it does no harm */ NSUnLinkModule(newModule, FALSE); ! PyErr_Format(PyExc_ImportError, ! "Loaded module does not contain symbol %.200s", ! funcname); return NULL; } theSym = NSLookupAndBindSymbol(funcname); *** /tmp/ceval.c.~2.174~-YCW7k Mon Apr 10 06:00:41 2000 --- /tmp/ceval.c-YCjFr Mon Apr 10 06:00:41 2000 *************** *** 2513,2519 **** else { if (!PyFunction_Check(func)) { PyErr_Format(PyExc_TypeError, ! "call of non-function (type %s)", func->ob_type->tp_name); return NULL; } --- 2513,2519 ---- else { if (!PyFunction_Check(func)) { PyErr_Format(PyExc_TypeError, ! "call of non-function (type %.200s)", func->ob_type->tp_name); return NULL; } From gstein@lyra.org Mon Apr 10 13:30:29 2000 From: gstein@lyra.org (Greg Stein) Date: Mon, 10 Apr 2000 05:30:29 -0700 (PDT) Subject: [Patches] add string precisions to PyErr_Format calls In-Reply-To: <14577.47506.14149.790979@beluga.mojam.com> Message-ID: Wouldn't it be best to simply fix PyErr_Format so that we don't have to continue to worry about buffer overruns? Cheers, -g On Mon, 10 Apr 2000, Skip Montanaro wrote: > > Skip> [ATTACHMENT ~/src/python/dist/src/Objects/object.c.diff, text/plain] > Skip> [ATTACHMENT ~/src/python/dist/src/Objects/unicodeobject.c.diff, text/plain] > Skip> [ATTACHMENT ~/src/python/dist/src/Modules/pyexpat.c.diff, text/plain] > Skip> [ATTACHMENT ~/src/python/dist/src/Python/dynload_next.c.diff, text/plain] > Skip> [ATTACHMENT ~/src/python/dist/src/Python/ceval.c.diff, text/plain] > > Ack! The attachments didn't attach! Here they are as plain text appended > one after the other... > > Skip > > *** /tmp/object.c.~2.65~ Mon Apr 10 06:01:08 2000 > --- /tmp/object.c Mon Apr 10 06:01:08 2000 > *************** > *** 236,242 **** > return NULL; > if (!PyString_Check(res)) { > PyErr_Format(PyExc_TypeError, > ! "__repr__ returned non-string (type %s)", > res->ob_type->tp_name); > Py_DECREF(res); > return NULL; > --- 236,242 ---- > return NULL; > if (!PyString_Check(res)) { > PyErr_Format(PyExc_TypeError, > ! "__repr__ returned non-string (type %.200s)", > res->ob_type->tp_name); > Py_DECREF(res); > return NULL; > *************** > *** 273,279 **** > return NULL; > if (!PyString_Check(res)) { > PyErr_Format(PyExc_TypeError, > ! "__str__ returned non-string (type %s)", > res->ob_type->tp_name); > Py_DECREF(res); > return NULL; > --- 273,279 ---- > return NULL; > if (!PyString_Check(res)) { > PyErr_Format(PyExc_TypeError, > ! "__str__ returned non-string (type %.200s)", > res->ob_type->tp_name); > Py_DECREF(res); > return NULL; > > *** /tmp/unicodeobject.c.~2.8~ Mon Apr 10 06:04:11 2000 > --- /tmp/unicodeobject.c Mon Apr 10 06:04:11 2000 > *************** > *** 365,371 **** > goto onError; > if (!PyUnicode_Check(unicode)) { > PyErr_Format(PyExc_TypeError, > ! "decoder did not return an unicode object (type=%s)", > unicode->ob_type->tp_name); > Py_DECREF(unicode); > goto onError; > --- 365,371 ---- > goto onError; > if (!PyUnicode_Check(unicode)) { > PyErr_Format(PyExc_TypeError, > ! "decoder did not return an unicode object (type=%.400s)", > unicode->ob_type->tp_name); > Py_DECREF(unicode); > goto onError; > *************** > *** 416,422 **** > /* XXX Should we really enforce this ? */ > if (!PyString_Check(v)) { > PyErr_Format(PyExc_TypeError, > ! "encoder did not return a string object (type=%s)", > v->ob_type->tp_name); > Py_DECREF(v); > goto onError; > --- 416,422 ---- > /* XXX Should we really enforce this ? */ > if (!PyString_Check(v)) { > PyErr_Format(PyExc_TypeError, > ! "encoder did not return a string object (type=%.400s)", > v->ob_type->tp_name); > Py_DECREF(v); > goto onError; > *************** > *** 484,490 **** > if ((errors == NULL) || > (strcmp(errors,"strict") == 0)) { > PyErr_Format(PyExc_UnicodeError, > ! "UTF-8 decoding error: %s", > details); > return -1; > } > --- 484,490 ---- > if ((errors == NULL) || > (strcmp(errors,"strict") == 0)) { > PyErr_Format(PyExc_UnicodeError, > ! "UTF-8 decoding error: %.400s", > details); > return -1; > } > *************** > *** 500,506 **** > } > else { > PyErr_Format(PyExc_ValueError, > ! "UTF-8 decoding error; unknown error handling code: %s", > errors); > return -1; > } > --- 500,506 ---- > } > else { > PyErr_Format(PyExc_ValueError, > ! "UTF-8 decoding error; unknown error handling code: %.400s", > errors); > return -1; > } > *************** > *** 607,613 **** > if ((errors == NULL) || > (strcmp(errors,"strict") == 0)) { > PyErr_Format(PyExc_UnicodeError, > ! "UTF-8 encoding error: %s", > details); > return -1; > } > --- 607,613 ---- > if ((errors == NULL) || > (strcmp(errors,"strict") == 0)) { > PyErr_Format(PyExc_UnicodeError, > ! "UTF-8 encoding error: %.400s", > details); > return -1; > } > *************** > *** 622,628 **** > else { > PyErr_Format(PyExc_ValueError, > "UTF-8 encoding error; " > ! "unknown error handling code: %s", > errors); > return -1; > } > --- 622,628 ---- > else { > PyErr_Format(PyExc_ValueError, > "UTF-8 encoding error; " > ! "unknown error handling code: %.400s", > errors); > return -1; > } > *************** > *** 728,734 **** > if ((errors == NULL) || > (strcmp(errors,"strict") == 0)) { > PyErr_Format(PyExc_UnicodeError, > ! "UTF-16 decoding error: %s", > details); > return -1; > } > --- 728,734 ---- > if ((errors == NULL) || > (strcmp(errors,"strict") == 0)) { > PyErr_Format(PyExc_UnicodeError, > ! "UTF-16 decoding error: %.400s", > details); > return -1; > } > *************** > *** 744,750 **** > } > else { > PyErr_Format(PyExc_ValueError, > ! "UTF-16 decoding error; unknown error handling code: %s", > errors); > return -1; > } > --- 744,750 ---- > } > else { > PyErr_Format(PyExc_ValueError, > ! "UTF-16 decoding error; unknown error handling code: %.400s", > errors); > return -1; > } > *************** > *** 918,924 **** > if ((errors == NULL) || > (strcmp(errors,"strict") == 0)) { > PyErr_Format(PyExc_UnicodeError, > ! "Unicode-Escape decoding error: %s", > details); > return -1; > } > --- 918,924 ---- > if ((errors == NULL) || > (strcmp(errors,"strict") == 0)) { > PyErr_Format(PyExc_UnicodeError, > ! "Unicode-Escape decoding error: %.400s", > details); > return -1; > } > *************** > *** 932,938 **** > else { > PyErr_Format(PyExc_ValueError, > "Unicode-Escape decoding error; " > ! "unknown error handling code: %s", > errors); > return -1; > } > --- 932,938 ---- > else { > PyErr_Format(PyExc_ValueError, > "Unicode-Escape decoding error; " > ! "unknown error handling code: %.400s", > errors); > return -1; > } > *************** > *** 1296,1302 **** > if ((errors == NULL) || > (strcmp(errors,"strict") == 0)) { > PyErr_Format(PyExc_UnicodeError, > ! "Latin-1 encoding error: %s", > details); > return -1; > } > --- 1296,1302 ---- > if ((errors == NULL) || > (strcmp(errors,"strict") == 0)) { > PyErr_Format(PyExc_UnicodeError, > ! "Latin-1 encoding error: %.400s", > details); > return -1; > } > *************** > *** 1310,1316 **** > else { > PyErr_Format(PyExc_ValueError, > "Latin-1 encoding error; " > ! "unknown error handling code: %s", > errors); > return -1; > } > --- 1310,1316 ---- > else { > PyErr_Format(PyExc_ValueError, > "Latin-1 encoding error; " > ! "unknown error handling code: %.400s", > errors); > return -1; > } > *************** > *** 1366,1372 **** > if ((errors == NULL) || > (strcmp(errors,"strict") == 0)) { > PyErr_Format(PyExc_UnicodeError, > ! "ASCII decoding error: %s", > details); > return -1; > } > --- 1366,1372 ---- > if ((errors == NULL) || > (strcmp(errors,"strict") == 0)) { > PyErr_Format(PyExc_UnicodeError, > ! "ASCII decoding error: %.400s", > details); > return -1; > } > *************** > *** 1381,1387 **** > else { > PyErr_Format(PyExc_ValueError, > "ASCII decoding error; " > ! "unknown error handling code: %s", > errors); > return -1; > } > --- 1381,1387 ---- > else { > PyErr_Format(PyExc_ValueError, > "ASCII decoding error; " > ! "unknown error handling code: %.400s", > errors); > return -1; > } > *************** > *** 1429,1435 **** > if ((errors == NULL) || > (strcmp(errors,"strict") == 0)) { > PyErr_Format(PyExc_UnicodeError, > ! "ASCII encoding error: %s", > details); > return -1; > } > --- 1429,1435 ---- > if ((errors == NULL) || > (strcmp(errors,"strict") == 0)) { > PyErr_Format(PyExc_UnicodeError, > ! "ASCII encoding error: %.400s", > details); > return -1; > } > *************** > *** 1443,1449 **** > else { > PyErr_Format(PyExc_ValueError, > "ASCII encoding error; " > ! "unknown error handling code: %s", > errors); > return -1; > } > --- 1443,1449 ---- > else { > PyErr_Format(PyExc_ValueError, > "ASCII encoding error; " > ! "unknown error handling code: %.400s", > errors); > return -1; > } > *************** > *** 1558,1564 **** > if ((errors == NULL) || > (strcmp(errors,"strict") == 0)) { > PyErr_Format(PyExc_UnicodeError, > ! "charmap decoding error: %s", > details); > return -1; > } > --- 1558,1564 ---- > if ((errors == NULL) || > (strcmp(errors,"strict") == 0)) { > PyErr_Format(PyExc_UnicodeError, > ! "charmap decoding error: %.400s", > details); > return -1; > } > *************** > *** 1573,1579 **** > else { > PyErr_Format(PyExc_ValueError, > "charmap decoding error; " > ! "unknown error handling code: %s", > errors); > return -1; > } > --- 1573,1579 ---- > else { > PyErr_Format(PyExc_ValueError, > "charmap decoding error; " > ! "unknown error handling code: %.400s", > errors); > return -1; > } > *************** > *** 1674,1680 **** > if ((errors == NULL) || > (strcmp(errors,"strict") == 0)) { > PyErr_Format(PyExc_UnicodeError, > ! "charmap encoding error: %s", > details); > return -1; > } > --- 1674,1680 ---- > if ((errors == NULL) || > (strcmp(errors,"strict") == 0)) { > PyErr_Format(PyExc_UnicodeError, > ! "charmap encoding error: %.400s", > details); > return -1; > } > *************** > *** 1689,1695 **** > else { > PyErr_Format(PyExc_ValueError, > "charmap encoding error; " > ! "unknown error handling code: %s", > errors); > return -1; > } > --- 1689,1695 ---- > else { > PyErr_Format(PyExc_ValueError, > "charmap encoding error; " > ! "unknown error handling code: %.400s", > errors); > return -1; > } > *************** > *** 1806,1812 **** > if ((errors == NULL) || > (strcmp(errors,"strict") == 0)) { > PyErr_Format(PyExc_UnicodeError, > ! "translate error: %s", > details); > return -1; > } > --- 1806,1812 ---- > if ((errors == NULL) || > (strcmp(errors,"strict") == 0)) { > PyErr_Format(PyExc_UnicodeError, > ! "translate error: %.400s", > details); > return -1; > } > *************** > *** 1821,1827 **** > else { > PyErr_Format(PyExc_ValueError, > "translate error; " > ! "unknown error handling code: %s", > errors); > return -1; > } > --- 1821,1827 ---- > else { > PyErr_Format(PyExc_ValueError, > "translate error; " > ! "unknown error handling code: %.400s", > errors); > return -1; > } > > *** /tmp/pyexpat.c.~2.2~ Mon Apr 10 06:01:33 2000 > --- /tmp/pyexpat.c Mon Apr 10 06:01:33 2000 > *************** > *** 307,313 **** > return NULL; > } > else if (rv == 0) { > ! PyErr_Format(ErrorObject, "%s: line %i, column %i", > XML_ErrorString( XML_GetErrorCode(self->itself) ), > XML_GetErrorLineNumber(self->itself), > XML_GetErrorColumnNumber(self->itself) ); > --- 307,313 ---- > return NULL; > } > else if (rv == 0) { > ! PyErr_Format(ErrorObject, "%.200s: line %i, column %i", > XML_ErrorString( XML_GetErrorCode(self->itself) ), > XML_GetErrorLineNumber(self->itself), > XML_GetErrorColumnNumber(self->itself) ); > > *** /tmp/dynload_next.c.~2.2~-YCj-2 Mon Apr 10 06:00:09 2000 > --- /tmp/dynload_next.c-YCVIG Mon Apr 10 06:00:09 2000 > *************** > *** 185,191 **** > if (!NSIsSymbolNameDefined(funcname)) { > /* UnlinkModule() isn't implimented in current versions, but calling it does no harm */ > NSUnLinkModule(newModule, FALSE); > ! PyErr_Format(PyExc_ImportError, "Loaded module does not contain symbol %s", funcname); > return NULL; > } > theSym = NSLookupAndBindSymbol(funcname); > --- 185,193 ---- > if (!NSIsSymbolNameDefined(funcname)) { > /* UnlinkModule() isn't implimented in current versions, but calling it does no harm */ > NSUnLinkModule(newModule, FALSE); > ! PyErr_Format(PyExc_ImportError, > ! "Loaded module does not contain symbol %.200s", > ! funcname); > return NULL; > } > theSym = NSLookupAndBindSymbol(funcname); > > *** /tmp/ceval.c.~2.174~-YCW7k Mon Apr 10 06:00:41 2000 > --- /tmp/ceval.c-YCjFr Mon Apr 10 06:00:41 2000 > *************** > *** 2513,2519 **** > else { > if (!PyFunction_Check(func)) { > PyErr_Format(PyExc_TypeError, > ! "call of non-function (type %s)", > func->ob_type->tp_name); > return NULL; > } > --- 2513,2519 ---- > else { > if (!PyFunction_Check(func)) { > PyErr_Format(PyExc_TypeError, > ! "call of non-function (type %.200s)", > func->ob_type->tp_name); > return NULL; > } > > _______________________________________________ > Patches mailing list > Patches@python.org > http://www.python.org/mailman/listinfo/patches > -- Greg Stein, http://www.lyra.org/ From skip@mojam.com (Skip Montanaro) Mon Apr 10 12:29:58 2000 From: skip@mojam.com (Skip Montanaro) (Skip Montanaro) Date: Mon, 10 Apr 2000 06:29:58 -0500 (CDT) Subject: [Patches] add string precisions to PyErr_Format calls In-Reply-To: References: <14577.47506.14149.790979@beluga.mojam.com> Message-ID: <14577.47926.702463.105644@beluga.mojam.com> Greg> Wouldn't it be best to simply fix PyErr_Format so that we don't Greg> have to continue to worry about buffer overruns? Yeah, probably, but checking for missing string precisions seemed to be the simplest way to close these particular loopholes. Whenever anyone decides to fix PyErr_Format, please also fix sysmodule.c:mywrite. Skip From gward@mems-exchange.org Mon Apr 10 14:20:56 2000 From: gward@mems-exchange.org (Greg Ward) Date: Mon, 10 Apr 2000 09:20:56 -0400 Subject: [Patches] fileinput.py argument handling (and suggestion) In-Reply-To: ; from gstein@lyra.org on Sat, Apr 08, 2000 at 05:05:30AM -0700 References: <200004051959.PAA18356@eric.cnri.reston.va.us> Message-ID: <20000410092055.A562@mems-exchange.org> On 08 April 2000, Greg Stein said: > I might go one further, and ask for a way to *strip* the line, rather than > just take the newline off the end. I can't think of a clean way to do so. > For example: > > fileinput.input() > fileinput.input(strip=fileinput.STRIP_NL) > fileinput.input(strip=fileinput.STRIP_ALL) > > It just seems a bit wordy, especially compared to the "chop=1" thing. See the distutils.text_file module for a rather overblown approach to this problem: it takes care of stripping newlines, deleting blank lines, stripping comments, trimming whitespace (leading, trailing, or both), collapsing lines joined with trailing backslashes, and maybe a few other things. All features are optional. The code is a bit hairy, and I make no guarantees about performance (except that it probably sucks). But it works, and I never have to write all that damn logic again. I'd vote for keeping fileinput.py relatively simple (adding chop sounds like a good idea, but anything else is overkill), and putting the complicated logic in a higher-level module like my text_file.py. Or maybe in a higher-level class also provided by fileinput.py. Whatever. Greg -- Greg Ward - software developer gward@mems-exchange.org MEMS Exchange / CNRI voice: +1-703-262-5376 Reston, Virginia, USA fax: +1-703-262-5367 From guido@python.org Mon Apr 10 14:33:00 2000 From: guido@python.org (Guido van Rossum) Date: Mon, 10 Apr 2000 09:33:00 -0400 Subject: [Patches] Change to attribute error message for instances. In-Reply-To: Your message of "Mon, 10 Apr 2000 13:06:14 +1000." References: Message-ID: <200004101333.JAA29910@eric.cnri.reston.va.us> > In line with a similar checkin to object.c a while ago, this patch > gives a more descriptive error message for an attribute error on a > class instance. The message now looks like: > > AttributeError: 'Descriptor' instance has no attribute > 'GetReturnType' > > [Maybe the module name would also be useful, but IMO this is fine > and a nice improvement] [...] > diff -c -2 -r2.83 classobject.c > *** classobject.c 2000/02/28 15:03:15 2.83 > --- classobject.c 2000/04/10 03:01:08 > *************** > *** 593,597 **** > v = class_lookup(inst->in_class, name, &class); > if (v == NULL) { > ! PyErr_SetObject(PyExc_AttributeError, name); > return NULL; > } > --- 593,600 ---- > v = class_lookup(inst->in_class, name, &class); > if (v == NULL) { > ! PyErr_Format(PyExc_AttributeError, > ! "'%.50s' instance has no attribute '%.400s'", > ! PyString_AsString(inst->in_class->cl_name), > ! sname); > return NULL; > } One problem with this: it breaks test_extcall.py!!! That code was expecting just the attribute name as the exception message. I wonder if there's more (user) code that makes a similar exception? I think we may have to be careful with this (kind of) change... At the very least I'll mention it in the list of code breakage on python.org/1.6/. --Guido van Rossum (home page: http://www.python.org/~guido/) From DavidA@ActiveState.com Mon Apr 10 18:49:04 2000 From: DavidA@ActiveState.com (David Ascher) Date: Mon, 10 Apr 2000 10:49:04 -0700 Subject: [Patches] Change to attribute error message for instances. In-Reply-To: <200004101333.JAA29910@eric.cnri.reston.va.us> Message-ID: > One problem with this: it breaks test_extcall.py!!! That code was > expecting just the attribute name as the exception message. > > I wonder if there's more (user) code that makes a similar exception? Probably. IMO, tough. > I think we may have to be careful with this (kind of) change... At > the very least I'll mention it in the list of code breakage on > python.org/1.6/. Sure, but I want to point out that this kind of change is what helps newbies more than almost anything else -- Python's error messages are liked by folks who have to deal with bad C compilers on a daily basis, but hated by real newbies. As far as I know, the content of the message of AttributeError was never documented, right? --david From mal@lemburg.com Mon Apr 10 19:05:42 2000 From: mal@lemburg.com (M.-A. Lemburg) Date: Mon, 10 Apr 2000 20:05:42 +0200 Subject: [Patches] Change to attribute error message for instances. References: Message-ID: <38F217F6.EE171DB2@lemburg.com> David Ascher wrote: > > > One problem with this: it breaks test_extcall.py!!! That code was > > expecting just the attribute name as the exception message. > > > > I wonder if there's more (user) code that makes a similar exception? > > Probably. IMO, tough. > > > I think we may have to be careful with this (kind of) change... At > > the very least I'll mention it in the list of code breakage on > > python.org/1.6/. > > Sure, but I want to point out that this kind of change is what helps newbies > more than almost anything else -- Python's error messages are liked by folks > who have to deal with bad C compilers on a daily basis, but hated by real > newbies. > > As far as I know, the content of the message of AttributeError was never > documented, right? Not sure, but aren't the error objects supposed to carry this kind of additional infomation in error instance attributes ?! The text should really never be used in other ways than to write it to a log file or print it to stderr, IMHO... -- Marc-Andre Lemburg ______________________________________________________________________ Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ From skip@mojam.com (Skip Montanaro) Mon Apr 10 18:04:43 2000 From: skip@mojam.com (Skip Montanaro) (Skip Montanaro) Date: Mon, 10 Apr 2000 12:04:43 -0500 (CDT) Subject: [Patches] Change to attribute error message for instances. In-Reply-To: References: <200004101333.JAA29910@eric.cnri.reston.va.us> Message-ID: <14578.2475.904738.937642@beluga.mojam.com> >> I think we may have to be careful with this (kind of) change... At >> the very least I'll mention it in the list of code breakage on >> python.org/1.6/. David> Sure, but I want to point out that this kind of change is what David> helps newbies more than almost anything else -- Python's error David> messages are liked by folks who have to deal with bad C compilers David> on a daily basis, but hated by real newbies. I will re-raise my suggestion that somewhere along the way Python needs error codes as well as error messages (maybe not until Py3k). I know it won't be easy to do, but if people are really parsing exception messages in their scripts, it suggests a need for error codes to make that job easier. -- Skip Montanaro | http://www.mojam.com/ skip@mojam.com | http://www.musi-cal.com/ From guido@python.org Mon Apr 10 19:44:01 2000 From: guido@python.org (Guido van Rossum) Date: Mon, 10 Apr 2000 14:44:01 -0400 Subject: [Patches] Getting ready for 1.6 alpha 2 Message-ID: <200004101844.OAA02610@eric.cnri.reston.va.us> I'm getting ready for the release of alpha 2. Tomorrow afternoon (around 5:30pm east coast time) I'm going on vacation for the rest of the week, followed by a business trip most of the week after. Obviously, I'm anxious to release a solid alpha tomorrow. Please, send only simple or essential patches between now and the release date! --Guido van Rossum (home page: http://www.python.org/~guido/) From gstein@lyra.org Mon Apr 10 20:01:19 2000 From: gstein@lyra.org (Greg Stein) Date: Mon, 10 Apr 2000 12:01:19 -0700 (PDT) Subject: [Patches] fileinput.py argument handling (and suggestion) In-Reply-To: <20000410092055.A562@mems-exchange.org> Message-ID: On Mon, 10 Apr 2000, Greg Ward wrote: >... > See the distutils.text_file module for a rather overblown approach to > this problem: it takes care of stripping newlines, deleting blank lines, > stripping comments, trimming whitespace (leading, trailing, or both), > collapsing lines joined with trailing backslashes, and maybe a few other > things. All features are optional. The code is a bit hairy, and I make > no guarantees about performance (except that it probably sucks). But it > works, and I never have to write all that damn logic again. > > I'd vote for keeping fileinput.py relatively simple (adding chop sounds > like a good idea, but anything else is overkill), and putting the > complicated logic in a higher-level module like my text_file.py. Or > maybe in a higher-level class also provided by fileinput.py. Whatever. +1 on adding the new class to fileinput.py. I've implemented similar code several times... and would like to avoid that :-) Cheers, -g -- Greg Stein, http://www.lyra.org/ From gward@mems-exchange.org Mon Apr 10 20:16:27 2000 From: gward@mems-exchange.org (Greg Ward) Date: Mon, 10 Apr 2000 15:16:27 -0400 Subject: [Patches] fileinput.py argument handling (and suggestion) In-Reply-To: ; from gstein@lyra.org on Mon, Apr 10, 2000 at 12:01:19PM -0700 References: <20000410092055.A562@mems-exchange.org> Message-ID: <20000410151626.A1168@mems-exchange.org> On 10 April 2000, Greg Stein said: > +1 on adding the new class to fileinput.py. I've implemented similar code > several times... and would like to avoid that :-) Well, that's one. Is anyone else interested in seeing a super-beefed up (possibly over-engineered) "read a `text' file with some subset of the usual Unix conventions" class added to fileinput.py? Here's the docstring for my nominee (text_file.py, which you presently all have in your Python source tree squirreled away in Lib/distutils): """Provides a file-like object that takes care of all the things you commonly want to do when processing a text file that has some line-by-line syntax: strip comments (as long as "#" is your comment character), skip blank lines, join adjacent lines by escaping the newline (ie. backslash at end of line), strip leading and/or trailing whitespace, and collapse internal whitespace. All of these are optional and independently controllable. Provides a 'warn()' method so you can generate warning messages that report physical line number, even if the logical line in question spans multiple physical lines. Also provides 'unreadline()' for implementing line-at-a-time lookahead. Constructor is called as: TextFile (filename=None, file=None, **options) It bombs (RuntimeError) if both 'filename' and 'file' are None; 'filename' should be a string, and 'file' a file object (or something that provides 'readline()' and 'close()' methods). It is recommended that you supply at least 'filename', so that TextFile can include it in warning messages. If 'file' is not supplied, TextFile creates its own using the 'open()' builtin. The options are all boolean, and affect the value returned by 'readline()': strip_comments [default: true] strip from "#" to end-of-line, as well as any whitespace leading up to the "#" -- unless it is escaped by a backslash lstrip_ws [default: false] strip leading whitespace from each line before returning it rstrip_ws [default: true] strip trailing whitespace (including line terminator!) from each line before returning it skip_blanks [default: true} skip lines that are empty *after* stripping comments and whitespace. (If both lstrip_ws and rstrip_ws are true, then some lines may consist of solely whitespace: these will *not* be skipped, even if 'skip_blanks' is true.) join_lines [default: false] if a backslash is the last non-newline character on a line after stripping comments and whitespace, join the following line to it to form one "logical line"; if N consecutive lines end with a backslash, then N+1 physical lines will be joined to form one logical line. collapse_ws [default: false] after stripping comments and whitespace and joining physical lines into logical lines, all internal whitespace (strings of whitespace surrounded by non-whitespace characters, and not at the beginning or end of the logical line) will be collapsed to a single space. Note that since 'rstrip_ws' can strip the trailing newline, the semantics of 'readline()' must differ from those of the builtin file object's 'readline()' method! In particular, 'readline()' returns None for end-of-file: an empty string might just be a blank line (or an all-whitespace line), if 'rstrip_ws' is true but 'skip_blanks' is not.""" Is this too much? Not enough? Silly to put it in fileinput.py when I'll already have to include it with the Distutils for pre-1.6 Pythons? Greg -- Greg Ward - software developer gward@mems-exchange.org MEMS Exchange / CNRI voice: +1-703-262-5376 Reston, Virginia, USA fax: +1-703-262-5367 From guido@python.org Mon Apr 10 20:27:45 2000 From: guido@python.org (Guido van Rossum) Date: Mon, 10 Apr 2000 15:27:45 -0400 Subject: [Patches] fileinput.py argument handling (and suggestion) In-Reply-To: Your message of "Mon, 10 Apr 2000 15:16:27 EDT." <20000410151626.A1168@mems-exchange.org> References: <20000410092055.A562@mems-exchange.org> <20000410151626.A1168@mems-exchange.org> Message-ID: <200004101927.PAA02984@eric.cnri.reston.va.us> > Well, that's one. Is anyone else interested in seeing a super-beefed up > (possibly over-engineered) "read a `text' file with some subset of the > usual Unix conventions" class added to fileinput.py? To me, text_file.py really works at a higher level than fileinput.py. It deals with lexical analysis issues: comments, line continuations, whitespace stripping. But it isn't very configurable: it has fixed notions of what's a continuation line, what's a comment, and so on, and you can only define a simple "profile" of options. For another approach, see Eric Raymond's shlex.py, which is a standard module since Python 1.5.2. It deals with splitting into tokens and handling quotes -- again, using rather fixed rules, although you can change what's a quote and what's in a word (a step up from text_file.py). Together with ConfigParser.py, I think we've got a rather eclectic and haphazard set of modules. Before we standardize on any particular one, we should analyze the needs of our users more! --Guido van Rossum (home page: http://www.python.org/~guido/) From Moshe Zadka Tue Apr 11 07:43:56 2000 From: Moshe Zadka (Moshe Zadka) Date: Tue, 11 Apr 2000 08:43:56 +0200 (IST) Subject: [Patches] fileinput.py argument handling (and suggestion) In-Reply-To: <20000410151626.A1168@mems-exchange.org> Message-ID: I really like the text_file.py. Can't it just be in the standard library and have a__getitem__ method (or is there one already? I only looked at the doc you sent). This will at least solve the FAQ about reading a file line-by-line in a nice way. -- Moshe Zadka . http://www.oreilly.com/news/prescod_0300.html http://www.linux.org.il -- we put the penguin in .com From gansevle@cs.utwente.nl Tue Apr 11 09:14:34 2000 From: gansevle@cs.utwente.nl (Fred Gansevles) Date: Tue, 11 Apr 2000 10:14:34 +0200 Subject: [Patches] (no subject) Message-ID: <200004110814.KAA28088@localhost.localdomain> The format of Doc/api/refcount.dat has changed but the parsing-code didn't. This patch updates the Doc/tools/refcount.py parsing script ---------------------------------------------------------------- I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. FAQ about legal I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. ---------------------------------------------------------------- Index: refcounts.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Doc/tools/refcounts.py,v retrieving revision 1.1 diff -r1.1 refcounts.py 36c36 < if refcount: --- > if not refcount in ('', 'null'): From mal@lemburg.com Tue Apr 11 11:03:09 2000 From: mal@lemburg.com (M.-A. Lemburg) Date: Tue, 11 Apr 2000 12:03:09 +0200 Subject: [Patches] Unicode Patch Set 2000-04-11 Message-ID: <38F2F85D.446DA68E@lemburg.com> This is a multi-part message in MIME format. --------------16779387E85086A13F2E7D09 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit This patch changes the semantics of the .splitlines() argument. This method previously had an argument maxsplit which worked just like the .split() method's argument of the same name. For line splitting, maxsplit doesn't make much sense, so instead, the argument is now called "keepends" and defaults to 0. When given and true, line end markers are included in the list entries. I hope its not too late for this change: .splitlines() isn't documented anywhere and probably hasn't had too much exposure yet -- besides, this is alpha software ;-) BTW, The change was needed in order to make file .readline() et al. methods work with arbitrary string-like objects. Patch Set Contents: ------------------- Include/unicodeobject.h: Changed PyUnicode_Splitlines() maxsplit argument to keepends. The maxsplit functionality was replaced by the keepends functionality which allows keeping the line end markers together with the string. Objects/stringobject.c: The maxsplit functionality in .splitlines() was replaced by the keepends functionality which allows keeping the line end markers together with the string. Added support for '%r' % obj: this inserts repr(obj) rather than str(obj). Objects/unicodectype.c: Added a few missing whitespace Unicode char mappings. Thanks to Brian Hooper. Objects/unicodeobject.c: The maxsplit functionality in .splitlines() was replaced by the keepends functionality which allows keeping the line end markers together with the string. Python/bltinmodule.c: Added special case to unicode(): when being passed a Unicode object as first argument, return the object as-is. Raises an exception when given a Unicode object *and* an encoding name. Lib/UserString.py: The maxsplit functionality in .splitlines() was replaced by the keepends functionality which allows keeping the line end markers together with the string. Lib/codecs.py: Added .writelines(), .readlines() and .readline() to all codec classes. Added encoding name attributes to wrapper classes which allow applications to check the used encoding names. Lib/test/test_string.py: Modified .splitlines() tests according to the changes in stringobject.c. Lib/test/test_unicode.py: Modified .splitlines() tests according to the changes in unicodeobject.c. -- Marc-Andre Lemburg ______________________________________________________________________ Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ --------------16779387E85086A13F2E7D09 Content-Type: text/plain; charset=us-ascii; name="Unicode-Implementation-2000-04-11.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="Unicode-Implementation-2000-04-11.patch" diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x *.orig -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x distutils -x PC -x PCbuild -x *.py CVS-Python/Include/unicodeobject.h Python+Unicode/Include/unicodeobject.h --- CVS-Python/Include/unicodeobject.h Mon Apr 10 15:41:41 2000 +++ Python+Unicode/Include/unicodeobject.h Mon Apr 10 21:23:21 2000 @@ -674,7 +674,7 @@ extern DL_IMPORT(PyObject*) PyUnicode_Splitlines( PyObject *s, /* String to split */ - int maxsplit /* Maxsplit count */ + int keepends /* If true, line end markers are included */ ); /* Translate a string by applying a character mapping table to it and Only in CVS-Python/Lib/test/output: test_zipfile diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x *.orig -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x distutils -x PC -x PCbuild -x *.py CVS-Python/Objects/stringobject.c Python+Unicode/Objects/stringobject.c --- CVS-Python/Objects/stringobject.c Mon Apr 10 15:47:21 2000 +++ Python+Unicode/Objects/stringobject.c Tue Apr 11 11:20:24 2000 @@ -2072,11 +2072,11 @@ static char splitlines__doc__[] = -"S.splitlines([maxsplit]]) -> list of strings\n\ +"S.splitlines([keepends]]) -> list of strings\n\ \n\ Return a list of the lines in S, breaking at line boundaries.\n\ -If maxsplit is given, at most maxsplit are done. Line breaks are not\n\ -included in the resulting list."; +Line breaks are not included in the resulting list unless keepends\n\ +is given and true."; #define SPLIT_APPEND(data, left, right) \ str = PyString_FromStringAndSize(data + left, right - left); \ @@ -2092,43 +2092,43 @@ static PyObject* string_splitlines(PyStringObject *self, PyObject *args) { - int maxcount = -1; register int i; register int j; int len; + int keepends = 0; PyObject *list; PyObject *str; char *data; - if (!PyArg_ParseTuple(args, "|i:splitlines", &maxcount)) + if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends)) return NULL; data = PyString_AS_STRING(self); len = PyString_GET_SIZE(self); - if (maxcount < 0) - maxcount = INT_MAX; - list = PyList_New(0); if (!list) goto onError; for (i = j = 0; i < len; ) { + int eol; + /* Find a line and append it */ while (i < len && data[i] != '\n' && data[i] != '\r') i++; - if (maxcount-- <= 0) - break; - SPLIT_APPEND(data, j, i); /* Skip the line break reading CRLF as one line break */ + eol = i; if (i < len) { if (data[i] == '\r' && i + 1 < len && data[i+1] == '\n') i += 2; else i++; + if (keepends) + eol = i; } + SPLIT_APPEND(data, j, eol); j = i; } if (j < len) { @@ -2591,7 +2591,10 @@ fmt = fmt_start; goto unicode; } + if (c == 's') temp = PyObject_Str(v); + else + temp = PyObject_Repr(v); if (temp == NULL) goto error; if (!PyString_Check(temp)) { diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x *.orig -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x distutils -x PC -x PCbuild -x *.py CVS-Python/Objects/unicodectype.c Python+Unicode/Objects/unicodectype.c --- CVS-Python/Objects/unicodectype.c Fri Mar 10 23:52:46 2000 +++ Python+Unicode/Objects/unicodectype.c Tue Apr 11 10:40:08 2000 @@ -633,8 +633,8 @@ #ifndef WANT_WCTYPE_FUNCTIONS -/* Returns 1 for Unicode characters having the type 'WS', 'B' or 'S', - 0 otherwise. */ +/* Returns 1 for Unicode characters having the bidirectional type + 'WS', 'B' or 'S' or the category 'Zs', 0 otherwise. */ int _PyUnicode_IsWhitespace(register const Py_UNICODE ch) { @@ -649,6 +649,8 @@ case 0x001E: /* RECORD SEPARATOR */ case 0x001F: /* UNIT SEPARATOR */ case 0x0020: /* SPACE */ + case 0x0085: /* NEXT LINE */ + case 0x00A0: /* NO-BREAK SPACE */ case 0x1680: /* OGHAM SPACE MARK */ case 0x2000: /* EN QUAD */ case 0x2001: /* EM QUAD */ @@ -661,7 +663,9 @@ case 0x2008: /* PUNCTUATION SPACE */ case 0x2009: /* THIN SPACE */ case 0x200A: /* HAIR SPACE */ + case 0x200B: /* ZERO WIDTH SPACE */ case 0x2028: /* LINE SEPARATOR */ + case 0x2029: /* PARAGRAPH SEPARATOR */ case 0x202F: /* NARROW NO-BREAK SPACE */ case 0x3000: /* IDEOGRAPHIC SPACE */ return 1; diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x *.orig -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x distutils -x PC -x PCbuild -x *.py CVS-Python/Objects/unicodeobject.c Python+Unicode/Objects/unicodeobject.c --- CVS-Python/Objects/unicodeobject.c Mon Apr 10 15:51:10 2000 +++ Python+Unicode/Objects/unicodeobject.c Tue Apr 11 11:47:03 2000 @@ -2516,7 +2516,7 @@ } PyObject *PyUnicode_Splitlines(PyObject *string, - int maxcount) + int keepends) { register int i; register int j; @@ -2531,29 +2531,29 @@ data = PyUnicode_AS_UNICODE(string); len = PyUnicode_GET_SIZE(string); - if (maxcount < 0) - maxcount = INT_MAX; - list = PyList_New(0); if (!list) goto onError; for (i = j = 0; i < len; ) { + int eol; + /* Find a line and append it */ while (i < len && !Py_UNICODE_ISLINEBREAK(data[i])) i++; - if (maxcount-- <= 0) - break; - SPLIT_APPEND(data, j, i); /* Skip the line break reading CRLF as one line break */ + eol = i; if (i < len) { if (data[i] == '\r' && i + 1 < len && data[i+1] == '\n') i += 2; else i++; + if (keepends) + eol = i; } + SPLIT_APPEND(data, j, eol); j = i; } if (j < len) { @@ -3785,21 +3785,21 @@ } static char splitlines__doc__[] = -"S.splitlines([maxsplit]]) -> list of strings\n\ +"S.splitlines([keepends]]) -> list of strings\n\ \n\ Return a list of the lines in S, breaking at line boundaries.\n\ -If maxsplit is given, at most maxsplit are done. Line breaks are not\n\ -included in the resulting list."; +Line breaks are not included in the resulting list unless keepends\n\ +is given and true."; static PyObject* unicode_splitlines(PyUnicodeObject *self, PyObject *args) { - int maxcount = -1; + int keepends = 0; - if (!PyArg_ParseTuple(args, "|i:splitlines", &maxcount)) + if (!PyArg_ParseTuple(args, "|i:splitlines", &keepends)) return NULL; - return PyUnicode_Splitlines((PyObject *)self, maxcount); + return PyUnicode_Splitlines((PyObject *)self, keepends); } static diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x *.orig -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x distutils -x PC -x PCbuild -x *.py CVS-Python/Python/bltinmodule.c Python+Unicode/Python/bltinmodule.c --- CVS-Python/Python/bltinmodule.c Wed Apr 5 22:11:21 2000 +++ Python+Unicode/Python/bltinmodule.c Tue Apr 11 11:12:50 2000 @@ -165,15 +165,28 @@ PyObject *self; PyObject *args; { - char *s; + PyObject *v; + const void *buffer; int len; char *encoding = NULL; char *errors = NULL; - if ( !PyArg_ParseTuple(args, "s#|ss:unicode", &s, &len, - &encoding, &errors) ) + if ( !PyArg_ParseTuple(args, "O|ss:unicode", &v, &encoding, &errors) ) return NULL; - return PyUnicode_Decode(s, len, encoding, errors); + /* Special case: Unicode will stay Unicode */ + if (PyUnicode_Check(v)) { + if (encoding) { + PyErr_SetString(PyExc_TypeError, + "unicode() does not support decoding of Unicode objects"); + return NULL; + } + Py_INCREF(v); + return v; + } + /* Read raw data and decode it */ + if (PyObject_AsReadBuffer(v, &buffer, &len)) + return NULL; + return PyUnicode_Decode((const char *)buffer, len, encoding, errors); } static char unicode_doc[] = diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x *.orig -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x distutils -x PC -x PCbuild -x *.c -x *.h -x *.in -x output CVS-Python/Lib/UserString.py Python+Unicode/Lib/UserString.py --- CVS-Python/Lib/UserString.py Mon Apr 3 05:51:49 2000 +++ Python+Unicode/Lib/UserString.py Tue Apr 11 11:36:56 2000 @@ -96,7 +96,7 @@ def rstrip(self): return self.__class__(self.data.rstrip()) def split(self, sep=None, maxsplit=-1): return self.data.split(sep, maxsplit) - def splitlines(self, maxsplit=-1): return self.data.splitlines(maxsplit) + def splitlines(self, keepends=0): return self.data.splitlines(keepends) def startswith(self, prefix, start=0, end=sys.maxint): return self.data.startswith(prefix, start, end) def strip(self): return self.__class__(self.data.strip()) diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x *.orig -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x distutils -x PC -x PCbuild -x *.c -x *.h -x *.in -x output CVS-Python/Lib/codecs.py Python+Unicode/Lib/codecs.py --- CVS-Python/Lib/codecs.py Fri Mar 31 19:22:29 2000 +++ Python+Unicode/Lib/codecs.py Mon Apr 10 22:29:00 2000 @@ -127,14 +127,19 @@ self.stream = stream self.errors = errors - def write(self,object): + def write(self, object): """ Writes the object's contents encoded to self.stream. """ data, consumed = self.encode(object,self.errors) self.stream.write(data) - # XXX .writelines() ? + def writelines(self, list): + + """ Writes the concatenated list of strings to the stream + using .write(). + """ + self.write(''.join(list)) def reset(self): @@ -179,7 +184,7 @@ self.stream = stream self.errors = errors - def read(self,size=-1): + def read(self, size=-1): """ Decodes data from the stream self.stream and returns the resulting object. @@ -221,8 +226,44 @@ else: return object - # XXX .readline() and .readlines() (these are hard to implement - # without using buffers for keeping read-ahead data) + def readline(self, size=None): + + """ Read one line from the input stream and return the + decoded data. + + Note: Unlike the .readlines() method, line breaking must + be implemented by the underlying stream's .readline() + method -- there is currently no support for line breaking + using the codec decoder due to lack of line buffering. + + size, if given, is passed as size argument to the stream's + .readline() method. + + """ + if size is None: + line = self.stream.readline() + else: + line = self.stream.readline(size) + return self.decode(line)[0] + + + def readlines(self, sizehint=0): + + """ Read all lines available on the input stream + and return them as list of lines. + + Line breaks are implemented using the codec's decoder + method and are included in the list entries. + + sizehint, if given, is passed as size argument to the + stream's .read() method. + + """ + if sizehint is None: + data = self.stream.read() + else: + data = self.stream.read(sizehint) + return self.decode(data)[0].splitlines(1) def reset(self): @@ -247,6 +288,9 @@ class StreamReaderWriter: + # Optional attributes set by the file wrappers below + encoding = 'unknown' + def __init__(self,stream,Reader,Writer,errors='strict'): """ Creates a StreamReaderWriter instance. @@ -269,10 +313,22 @@ return self.reader.read(size) + def readline(size=None): + + return self.reader.readline(size) + + def readlines(sizehint=None): + + return self.reader.readlines(sizehint) + def write(self,data): return self.writer.write(data) + def writelines(self,list): + + return self.writer.writelines(list) + def reset(self): self.reader.reset() @@ -290,6 +346,10 @@ class StreamRecoder: + # Optional attributes set by the file wrappers below + data_encoding = 'unknown' + file_encoding = 'unknown' + def __init__(self,stream,encode,decode,Reader,Writer,errors='strict'): """ Creates a StreamRecoder instance which implements a two-way @@ -328,13 +388,34 @@ data, bytesencoded = self.encode(data, self.errors) return data + def readline(self,size=None): + + if size is None: + data = self.reader.readline() + else: + data = self.reader.readline(size) + data, bytesencoded = self.encode(data, self.errors) + return data + + def readlines(self,sizehint=None): + + if sizehint is None: + data = self.reader.read() + else: + data = self.reader.read(sizehint) + data, bytesencoded = self.encode(data, self.errors) + return data.splitlines(1) + def write(self,data): data, bytesdecoded = self.decode(data, self.errors) return self.writer.write(data) - # .writelines(), .readline() and .readlines() ... see notes - # above. + def writelines(self,list): + + data = ''.join(list) + data, bytesdecoded = self.decode(data, self.errors) + return self.writer.write(data) def reset(self): @@ -380,33 +461,45 @@ if encoding is None: return file (e,d,sr,sw) = lookup(encoding) - return StreamReaderWriter(file, sr, sw, errors) + srw = StreamReaderWriter(file, sr, sw, errors) + # Add attributes to simplify introspection + srw.encoding = encoding + return srw -def EncodedFile(file, input, output=None, errors='strict'): +def EncodedFile(file, data_encoding, file_encoding=None, errors='strict'): """ Return a wrapped version of file which provides transparent encoding translation. Strings written to the wrapped file are interpreted according - to the given input encoding and then written to the original - file as string using the output encoding. The intermediate - encoding will usually be Unicode but depends on the specified - codecs. + to the given data_encoding and then written to the original + file as string using file_encoding. The intermediate encoding + will usually be Unicode but depends on the specified codecs. - If output is not given, it defaults to input. + Strings are read from the file using file_encoding and then + passed back to the caller as string using data_encoding. + + If file_encoding is not given, it defaults to data_encoding. errors may be given to define the error handling. It defaults to 'strict' which causes ValueErrors to be raised in case an encoding error occurs. + data_encoding and file_encoding are added to the wrapped file + object as attributes .data_encoding and .file_encoding resp. + """ - if output is None: - output = input - encode, decode = lookup(input)[:2] - Reader, Writer = lookup(output)[2:] - return StreamRecoder(file, - encode,decode,Reader,Writer, - errors) + if file_encoding is None: + file_encoding = data_encoding + encode, decode = lookup(data_encoding)[:2] + Reader, Writer = lookup(file_encoding)[2:] + sr = StreamRecoder(file, + encode,decode,Reader,Writer, + errors) + # Add attributes to simplify introspection + sr.data_encoding = data_encoding + sr.file_encoding = file_encoding + return sr ### Tests @@ -414,5 +507,8 @@ import sys - # Make stdout translate Latin-1 into Unicode-Escape - sys.stdout = EncodedFile(sys.stdout, 'latin-1', 'unicode-escape') + # Make stdout translate Latin-1 output into UTF-8 output + sys.stdout = EncodedFile(sys.stdout, 'latin-1', 'utf-8') + + # Have stdin translate Latin-1 input into UTF-8 input + sys.stdin = EncodedFile(sys.stdin, 'utf-8', 'latin-1') diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x *.orig -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x distutils -x PC -x PCbuild -x *.c -x *.h -x *.in -x output CVS-Python/Lib/test/test_string.py Python+Unicode/Lib/test/test_string.py --- CVS-Python/Lib/test/test_string.py Mon Mar 20 17:36:30 2000 +++ Python+Unicode/Lib/test/test_string.py Tue Apr 11 11:20:50 2000 @@ -90,8 +90,7 @@ test('splitlines', "abc\ndef\r\nghi\n", ['abc', 'def', 'ghi']) test('splitlines', "abc\ndef\r\nghi\n\r", ['abc', 'def', 'ghi', '']) test('splitlines', "\nabc\ndef\r\nghi\n\r", ['', 'abc', 'def', 'ghi', '']) -test('splitlines', "\nabc\ndef\r\nghi\n\r", ['', 'abc\012def\015\012ghi\012\015'], 1) -test('splitlines', "\nabc\ndef\r\nghi\n\r", ['', 'abc', 'def\015\012ghi\012\015'], 2) +test('splitlines', "\nabc\ndef\r\nghi\n\r", ['\n', 'abc\n', 'def\r\n', 'ghi\n', '\r'], 1) transtable = '\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037 !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`xyzdefghijklmnopqrstuvwxyz{|}~\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377' diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x *.orig -x Demo -x CVS -x Doc -x *.orig -x .#* -x *.txt -x distutils -x PC -x PCbuild -x *.c -x *.h -x *.in -x output CVS-Python/Lib/test/test_unicode.py Python+Unicode/Lib/test/test_unicode.py --- CVS-Python/Lib/test/test_unicode.py Mon Apr 10 15:52:48 2000 +++ Python+Unicode/Lib/test/test_unicode.py Tue Apr 11 11:23:02 2000 @@ -212,8 +212,7 @@ test('splitlines', u"abc\ndef\r\nghi\n", [u'abc', u'def', u'ghi']) test('splitlines', u"abc\ndef\r\nghi\n\r", [u'abc', u'def', u'ghi', u'']) test('splitlines', u"\nabc\ndef\r\nghi\n\r", [u'', u'abc', u'def', u'ghi', u'']) -test('splitlines', u"\nabc\ndef\r\nghi\n\r", [u'', u'abc\012def\015\012ghi\012\015'], 1) -test('splitlines', u"\nabc\ndef\r\nghi\n\r", [u'', u'abc', u'def\015\012ghi\012\015'], 2) +test('splitlines', u"\nabc\ndef\r\nghi\n\r", [u'\n', u'abc\n', u'def\r\n', u'ghi\n', u'\r'], 1) test('translate', u"abababc", u'bbbc', {ord('a'):None}) test('translate', u"abababc", u'iiic', {ord('a'):None, ord('b'):ord('i')}) Only in CVS-Python/Lib/test: test_zipfile.py --------------16779387E85086A13F2E7D09-- From Markovitch@ISO.RU Tue Apr 11 13:11:55 2000 From: Markovitch@ISO.RU (Markovitch Yakov) Date: Tue, 11 Apr 2000 16:11:55 +0400 Subject: [Patches] Patch for thread_nt.h, radically increasing Python perfomance Message-ID: <119FEF4BC996D311869E0050044D464D05D6FC@EXCHANGE> Hello Guido. Here's the new version of thread_nt.h. More particular, there is a new version of thread lock that uses kernel object (e.g. semaphore) only in case of contention; in other case it simply uses interlocked functions, which are faster by the order of magnitude. It doesn't make much difference without threads present, but as soon as thread machinery initialised and (mostly) the interpreter global lock is on, difference becomes tremendous. I've included a small script, which initialises threads and launches pystone. With original thread_nt.h, Pystone results with initialised threads are twofold worse then w/o threads. With the new version, only 10% worse. I have used this patch for about 6 months (with threaded and non-threaded applications). It works remarkably well (though I'd desperately prefer Python was free-threaded; I hope, it will soon). Here's the legal mumbo-yumbo: I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. Here's the diff against the current CVS version: diff -r2.6 thread_nt.h 5c5 < All Rights Reserved --- > All Rights Reserved 32a33 > /* Fast NonRecursiveMutex support by Yakov Markovitch, markovitch@iso.ru */ 37a39,140 > typedef struct NRMUTEX { > LONG owned ; > DWORD thread_id ; > HANDLE hevent ; > > } NRMUTEX, *PNRMUTEX ; > > > typedef PVOID WINAPI interlocked_cmp_xchg_t(PVOID *dest, PVOID exc, PVOID comperand) ; > > /* Sorry mate, but we haven't got InterlockedCompareExchange in Win95! */ > static PVOID WINAPI interlocked_cmp_xchg(PVOID *dest, PVOID exc, PVOID comperand) > { > static LONG spinlock = 0 ; > PVOID result ; > > /* Acqire spinlock (yielding control to other threads if cant aquire for the moment) */ > while(InterlockedExchange(&spinlock, 1)) Sleep(0) ; > result = *dest ; > if (result == comperand) > *dest = exc ; > /* Release spinlock */ > spinlock = 0 ; > return result ; > } ; > > static interlocked_cmp_xchg_t *ixchg ; > BOOL InitializeNonRecursiveMutex(PNRMUTEX mutex) > { > if (!ixchg) > { > /* Sorely, Win95 has no InterlockedCompareExchange API (Win98 has), so we have to use emulation */ > HANDLE kernel = GetModuleHandle("kernel32.dll") ; > if (!kernel || (ixchg = (interlocked_cmp_xchg_t *)GetProcAddress(kernel, "InterlockedCompareExchange")) == NULL) > ixchg = interlocked_cmp_xchg ; > } > > mutex->owned = -1 ; /* No threads have entered NonRecursiveMutex */ > mutex->thread_id = 0 ; > mutex->hevent = CreateEvent(NULL, FALSE, FALSE, NULL) ; > return mutex->hevent != NULL ; /* TRUE if the mutex is created */ > } > > #define InterlockedCompareExchange(dest,exchange,comperand) (ixchg((dest), (exchange), (comperand))) > > VOID DeleteNonRecursiveMutex(PNRMUTEX mutex) > { > /* No in-use check */ > CloseHandle(mutex->hevent) ; > mutex->hevent = NULL ; /* Just in case */ > } > > DWORD EnterNonRecursiveMutex(PNRMUTEX mutex, BOOL wait) > { > /* Assume that the thread waits successfully */ > DWORD ret ; > > /* InterlockedIncrement(&mutex->owned) == 0 means that no thread currently owns the mutex */ > if (!wait) > { > if (InterlockedCompareExchange((PVOID *)&mutex->owned, (PVOID)0, (PVOID)-1) != (PVOID)-1) > return WAIT_TIMEOUT ; > ret = WAIT_OBJECT_0 ; > } > else > ret = InterlockedIncrement(&mutex->owned) ? > /* Some thread owns the mutex, let's wait... */ > WaitForSingleObject(mutex->hevent, INFINITE) : WAIT_OBJECT_0 ; > > mutex->thread_id = GetCurrentThreadId() ; /* We own it */ > return ret ; > } > > BOOL LeaveNonRecursiveMutex(PNRMUTEX mutex) > { > /* We don't own the mutex */ > mutex->thread_id = 0 ; > return > InterlockedDecrement(&mutex->owned) < 0 || > SetEvent(mutex->hevent) ; /* Other threads are waiting, wake one on them up */ > } > > PNRMUTEX AllocNonRecursiveMutex() > { > PNRMUTEX mutex = (PNRMUTEX)malloc(sizeof(NRMUTEX)) ; > if (mutex && !InitializeNonRecursiveMutex(mutex)) > { > free(mutex) ; > mutex = NULL ; > } > return mutex ; > } > > void FreeNonRecursiveMutex(PNRMUTEX mutex) > { > if (mutex) > { > DeleteNonRecursiveMutex(mutex) ; > free(mutex) ; > } > } > 65c168 < --- > 68c171 < dprintf(("%ld: PyThread_start_new_thread succeeded: %ld\n", PyThread_get_thread_ident(), rv)); --- > dprintf(("%ld: PyThread_start_new_thread succeeded: %ld\n", PyThread_get_thread_ident(), aThreadId)); 82c185 < --- > 136c239 < HANDLE aLock; --- > PNRMUTEX aLock; 142,146c245 < aLock = CreateSemaphore(NULL, /* Security attributes */ < 1, /* Initial value */ < 1, /* Maximum value */ < NULL); < /* Name of semaphore */ --- > aLock = AllocNonRecursiveMutex() ; 157c256 < CloseHandle((HANDLE) aLock); --- > FreeNonRecursiveMutex(aLock) ; 168,169c267 < int success = 1; < DWORD waitResult; --- > int success ; 173,177c271 < waitResult = WaitForSingleObject((HANDLE) aLock, (waitflag == 1 ? INFINITE : 0)); < < if (waitResult != WAIT_OBJECT_0) { < success = 0; /* We failed */ < } --- > success = aLock && EnterNonRecursiveMutex((PNRMUTEX) aLock, (waitflag == 1 ? INFINITE : 0)) == WAIT_OBJECT_0 ; 188,192c282 < if (!ReleaseSemaphore( < (HANDLE) aLock, /* Handle of semaphore */ < 1, /* increment count by one */ < NULL)) /* not interested in previous count */ < { --- > if (!(aLock && LeaveNonRecursiveMutex((PNRMUTEX) aLock))) 194d283 < } Yours sincerely Yakov Markovitch, Lead Programmer InterSoft Lab Phone: 7 095 218-4014 e-mail: markovitch@iso.ru begin 600 thread_nt.h M+RHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ*BHJ M*BHJ*BHJ*BHJ*BHJ*BHJ#0I#;W!Y2!G7)I9VAT(&YO=&EC M92!A<'!E87(@:6X@86QL(&-O<&EE2!T:&4@0V]R<&]R871I;VX@9F]R($YA=&EO;F%L M(%)EPT*("`@("`@ M($Q/3D<@("!O=VYE9"`[#0H@("`@("`@1%=/4D0@('1H7!E9&5F(%!63TE$(%=)3D%022!I;G1E&-H9U]T*%!63TE$("ID97-T+"!05D])1"!E>&,L(%!63TE$(&-O;7!E2!M871E+"!B=70@=V4@:&%V96XG="!G;W0@26YT M97)L;V-K961#;VUP87)E17AC:&%N9V4@:6X@5VEN.34A("HO#0IS=&%T:6,@ M4%9/240@5TE.05!)(&EN=&5R;&]C:V5D7V-M<%]X8VAG*%!63TE$("ID97-T M+"!05D])1"!E>&,L(%!63TE$(&-O;7!E&-H9RD-"@E[#0H)"2\J(%-O2P@5VEN.34@:&%S(&YO($EN M=&5R;&]C:V5D0V]M<&%R945X8VAA;F=E($%022`H5VEN.3@@:&%S*2P@&-H M86YG92(I*2`]/2!.54Q,*0T*"0D):7AC:&<@/2!I;G1E&-H9R`[#0H)?0T*#0H);75T97@M/F]W;F5D(#T@+3$@.R`@+RH@3F\@=&AR M96%D"T^=&AR96%D7VED(#T@,"`[#0H);75T97@M/FAE=F5N="`]($-R96%T945V M96YT*$Y53$PL($9!3%-%+"!&04Q312P@3E5,3"D@.PT*"7)E='5R;B!M=71E M>"T^:&5V96YT("$]($Y53$P@.PDO*B!44E5%(&EF('1H92!M=71E>"!I&-H9R@H9&5S="DL M("AE>&-H86YG92DL("AC;VUP97)A;F0I*2D-"@T*5D])1"!$96QE=&5.;VY2 M96-U"A03E)-551%6"!M=71E>"D-"GL-"@DO*B!.;R!I;BUU M"T^:&5V96YT*2`[#0H) M;75T97@M/FAE=F5N="`]($Y53$P@.R`O*B!*=7-T(&EN(&-A"A03E)-551%6"!M=71E M>"P@0D]/3"!W86ET*0T*>PT*"2\J($%S"T^;W=N960I(#T](#`@;65A;G,@ M=&AA="!N;R!T:')E860@8W5R"T^;W=N960L("A05D])1"DP+"`H4%9/240I M+3$I("$]("A05D])1"DM,2D-"@D)"7)E='5R;B!704E47U1)345/550@.PT* M"0ER970@/2!704E47T]"2D5#5%\P(#L-"@E]#0H)96QS90T*"0ER970@/2!) M;G1E"P@;&5T)W,@=V%I="XN+B`J+PT* M"0D)5V%I=$9O"T^:&5V96YT+"!)3D9)3DE4 M12D@.B!704E47T]"2D5#5%\P(#L-"@T*"6UU=&5X+3YT:')E861?:60@/2!' M971#=7)R96YT5&AR96%D260H*2`[("\J(%=E(&]W;B!I="`J+PT*"7)E='5R M;B!R970@.PT*?0T*#0I"3T],($QE879E3F]N4F5C=7)S:79E375T97@H4$Y2 M355415@@;75T97@I#0I[#0H)+RH@5V4@9&]N)W0@;W=N('1H92!M=71E>"`J M+PT*"6UU=&5X+3YT:')E861?:60@/2`P(#L-"@ER971U"`] M("A03E)-551%6"EM86QL;V,H"D@.PT*"0EM=71E>"`]($Y53$P@.PT*"7T-"@ER M971U"A03E)-551%6"!M=71E>"D-"GL-"@EI9B`H;75T97@I#0H)>PT*"0E$96QE M=&5.;VY296-U"AM=71E>"D@.PT*"0EFF%T:6]N(&]F('1H92!#('!A8VMA9V4L M('-H;W5L9"!N;W0@8F4@;F5E9&5D+@T*("HO#0IS=&%T:6,@=F]I9"!0>51H MPT*"6QO;F<@ MF5D*0T*"0E0>51H51H&ET7W1H51H&ET7W1H51H&ET7W!R;VF5D*0T*"0EI9B`H;F]?8VQE86YU<"D-"@D)"5]E>&ET*'-T871U51H&ET M7W!R;V51H51HF5D*0T*"0E0>51H%QN(BP@4'E4:')E861?9V5T7W1H51H7!E7VQO8VLI(&%,;V-K.PT* M?0T*#0IV;VED(%!Y5&AR96%D7V9R965?;&]C:RA0>51H7!E7VQO M8VL@84QO8VLI#0I[#0H)9'!R:6YT9B@H(B5L9#H@4'E4:')E861?9G)E95]L M;V-K*"5L>"D@8V%L;&5D7&XB+"!0>51H"AA M3&]C:RD@.PT*?0T*#0HO*@T*("H@4F5T=7)N(#$@;VX@2!T:&ES('1H51H7!E7VQO8VL@84QO8VLL(&EN="!W86ET9FQA9RD-"GL- M"@EI;G0@51H51H"@H4$Y2 M355415@I(&%,;V-K+"`H=V%I=&9L86<@/3T@,2`_($E.1DE.251%(#H@,"DI M(#T](%=!251?3T)*14-47S`@.PT*#0H)9'!R:6YT9B@H(B5L9#H@4'E4:')E M861?86-Q=6ER95]L;V-K*"5L>"P@)60I("T^("5D7&XB+"!0>51H51H51H7!E7W-E;6$@4'E4:')E861?86QL;V-A M=&5?51H&EM=6T@=F%L=64)"2`@*B\-"B`@("`@("`@ M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@3E5,3"D["2`@("`O*B!. M86UE(&]F('-E;6%P:&]R90D@("HO#0H-"@ED<')I;G1F*"@B)6QD.B!0>51H M51H51H"D@51H M7!E7W-E;6$@85-E;6%P:&]R92D-"GL-"@E296QE87-E4V5M87!H M;W)E*`T*"0DH2$%.1$Q%*2!A4V5M87!H;W)E+`D@("`@+RH@2&%N9&QE(&]F M('-E;6%P:&]R90D)*B\-"@D),2P)"2\J(&EN8W)E;65N="!C;W5N="!B>2!O M;F4)("`@("HO#0H)"4Y53$PI.PD)("`@("\J(&YO="!I;G1E51H2!T:')E860@=&\@:6YI=&EA M;&ES92!T:')E860@;65C:&%N:6-S("AA;F0@9VQO8F%L(&QO8VLA*0T*(R!4 M:&ES('1H2!T:'5S('=O;B=T M(&UA:V4@;75C:"!I;F9L=65N8V4@;VX-"B,@=&5S="!R97-U;'1S(&)Y(&ET M2!B>2!T:&%T(&9A8W0@=&AA="!I="!I;FET:6%L:7-E For the reviewer(s): Most of the changes are simple translations, i.e.: string.split (s, sep) --> s.split (sep) Some of the changes also take the context into account, see: - cgi.py - formatter.py - imaplib.py Both 'make test' and 'Lib/compileall.py Lib' produced no error-output so I'd expect no big problems. The following migt go into the csv-log: ________________________________________________________________________ This (mega-)patch updates all the modules in the standard-module (all Lib/*.py files) to use the new string-methods instead of the old string module. ---------------------------------------------------------------- I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. FAQ about legal I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. ---------------------------------------------------------------- Index: Lib/BaseHTTPServer.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/BaseHTTPServer.py,v retrieving revision 1.9 diff -c -r1.9 BaseHTTPServer.py *** BaseHTTPServer.py 1999/10/26 13:01:36 1.9 --- BaseHTTPServer.py 2000/04/11 11:56:38 *************** *** 67,73 **** import sys import time import socket # For gethostbyaddr() - import string import mimetools import SocketServer --- 67,72 ---- *************** *** 212,218 **** """ # The Python system version, truncated to its first component. ! sys_version = "Python/" + string.split(sys.version)[0] # The server software version. You may want to override this. # The format is multiple whitespace-separated strings, --- 211,217 ---- """ # The Python system version, truncated to its first component. ! sys_version = "Python/" + sys.version.split[0] # The server software version. You may want to override this. # The format is multiple whitespace-separated strings, *************** *** 237,243 **** elif requestline[-1:] == '\n': requestline = requestline[:-1] self.requestline = requestline ! words = string.split(requestline) if len(words) == 3: [command, path, version] = words if version[:5] != 'HTTP/': --- 236,242 ---- elif requestline[-1:] == '\n': requestline = requestline[:-1] self.requestline = requestline ! words = requestline.split() if len(words) == 3: [command, path, version] = words if version[:5] != 'HTTP/': *************** *** 485,491 **** """ if sys.argv[1:]: ! port = string.atoi(sys.argv[1]) else: port = 8000 server_address = ('', port) --- 484,490 ---- """ if sys.argv[1:]: ! port = int (sys.argv[1]) else: port = 8000 server_address = ('', port) Index: Lib/CGIHTTPServer.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/CGIHTTPServer.py,v retrieving revision 1.12 diff -c -r1.12 CGIHTTPServer.py *** CGIHTTPServer.py 1999/10/18 13:43:44 1.12 --- CGIHTTPServer.py 2000/04/11 11:56:38 *************** *** 82,93 **** def run_cgi(self): """Execute a CGI script.""" dir, rest = self.cgi_info ! i = string.rfind(rest, '?') if i >= 0: rest, query = rest[:i], rest[i+1:] else: query = '' ! i = string.find(rest, '/') if i >= 0: script, rest = rest[:i], rest[i:] else: --- 82,93 ---- def run_cgi(self): """Execute a CGI script.""" dir, rest = self.cgi_info ! i = rest.rfind('?') if i >= 0: rest, query = rest[:i], rest[i+1:] else: query = '' ! i = rest.find('/') if i >= 0: script, rest = rest[:i], rest[i:] else: *************** *** 149,166 **** accept = [] for line in self.headers.getallmatchingheaders('accept'): if line[:1] in string.whitespace: ! accept.append(string.strip(line)) else: ! accept = accept + string.split(line[7:], ',') ! env['HTTP_ACCEPT'] = string.joinfields(accept, ',') ua = self.headers.getheader('user-agent') if ua: env['HTTP_USER_AGENT'] = ua co = filter(None, self.headers.getheaders('cookie')) if co: ! env['HTTP_COOKIE'] = string.join(co, ', ') # XXX Other HTTP_* headers ! decoded_query = string.replace(query, '+', ' ') try: os.setuid(nobody) except os.error: --- 149,166 ---- accept = [] for line in self.headers.getallmatchingheaders('accept'): if line[:1] in string.whitespace: ! accept.append(line.strip()) else: ! accept = accept + line[7:].split(',') ! env['HTTP_ACCEPT'] = ','.join(accept) ua = self.headers.getheader('user-agent') if ua: env['HTTP_USER_AGENT'] = ua co = filter(None, self.headers.getheaders('cookie')) if co: ! env['HTTP_COOKIE'] = ', '.join(co) # XXX Other HTTP_* headers ! decoded_query = query.replace('+', ' ') try: os.setuid(nobody) except os.error: Index: Lib/ConfigParser.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/ConfigParser.py,v retrieving revision 1.17 diff -c -r1.17 ConfigParser.py *** ConfigParser.py 2000/03/03 20:43:57 1.17 --- ConfigParser.py 2000/04/11 11:56:38 *************** *** 259,265 **** depth = 0 while depth < 10: # Loop through this until it's done depth = depth + 1 ! if string.find(value, "%(") >= 0: try: value = value % d except KeyError, key: --- 259,265 ---- depth = 0 while depth < 10: # Loop through this until it's done depth = depth + 1 ! if value.find("%(") >= 0: try: value = value % d except KeyError, key: *************** *** 271,290 **** return conv(self.get(section, option)) def getint(self, section, option): ! return self.__get(section, string.atoi, option) def getfloat(self, section, option): ! return self.__get(section, string.atof, option) def getboolean(self, section, option): v = self.get(section, option) ! val = string.atoi(v) if val not in (0, 1): raise ValueError, 'Not a boolean: %s' % v return val def optionxform(self, optionstr): ! return string.lower(optionstr) # # Regular expressions for parsing section headers and options. Note a --- 271,290 ---- return conv(self.get(section, option)) def getint(self, section, option): ! return self.__get(section, int, option) def getfloat(self, section, option): ! return self.__get(section, float, option) def getboolean(self, section, option): v = self.get(section, option) ! val = int(v) if val not in (0, 1): raise ValueError, 'Not a boolean: %s' % v return val def optionxform(self, optionstr): ! return optionstr.lower() # # Regular expressions for parsing section headers and options. Note a *************** *** 324,337 **** break lineno = lineno + 1 # comment or blank line? ! if string.strip(line) == '' or line[0] in '#;': continue ! if string.lower(string.split(line)[0]) == 'rem' \ and line[0] in "rR": # no leading whitespace continue # continuation line? if line[0] in ' \t' and cursect is not None and optname: ! value = string.strip(line) if value: cursect[optname] = cursect[optname] + '\n ' + value # a section header or option header? --- 324,337 ---- break lineno = lineno + 1 # comment or blank line? ! if line.strip() == '' or line[0] in '#;': continue ! if line.split()[0].lower() == 'rem' \ and line[0] in "rR": # no leading whitespace continue # continuation line? if line[0] in ' \t' and cursect is not None and optname: ! value = line.strip() if value: cursect[optname] = cursect[optname] + '\n ' + value # a section header or option header? *************** *** 357,370 **** mo = self.OPTCRE.match(line) if mo: optname, vi, optval = mo.group('option', 'vi', 'value') ! optname = string.lower(optname) if vi in ('=', ':') and ';' in optval: # ';' is a comment delimiter only if it follows # a spacing character ! pos = string.find(optval, ';') if pos and optval[pos-1] in string.whitespace: optval = optval[:pos] ! optval = string.strip(optval) # allow empty values if optval == '""': optval = '' --- 357,370 ---- mo = self.OPTCRE.match(line) if mo: optname, vi, optval = mo.group('option', 'vi', 'value') ! optname = optname.lower() if vi in ('=', ':') and ';' in optval: # ';' is a comment delimiter only if it follows # a spacing character ! pos = optval.find(';') if pos and optval[pos-1] in string.whitespace: optval = optval[:pos] ! optval = optval.strip() # allow empty values if optval == '""': optval = '' Index: Lib/MimeWriter.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/MimeWriter.py,v retrieving revision 1.4 diff -c -r1.4 MimeWriter.py *** MimeWriter.py 1998/04/23 13:34:57 1.4 --- MimeWriter.py 2000/04/11 11:56:38 *************** *** 7,13 **** """ - import string import mimetools --- 7,12 ---- *************** *** 86,97 **** self._headers = [] def addheader(self, key, value, prefix=0): ! lines = string.splitfields(value, "\n") while lines and not lines[-1]: del lines[-1] while lines and not lines[0]: del lines[0] for i in range(1, len(lines)): ! lines[i] = " " + string.strip(lines[i]) ! value = string.joinfields(lines, "\n") + "\n" line = key + ": " + value if prefix: self._headers.insert(0, line) --- 85,96 ---- self._headers = [] def addheader(self, key, value, prefix=0): ! lines = value.split("\n") while lines and not lines[-1]: del lines[-1] while lines and not lines[0]: del lines[0] for i in range(1, len(lines)): ! lines[i] = " " + lines[i].strip() ! value = "\n".join(lines) + "\n" line = key + ": " + value if prefix: self._headers.insert(0, line) Index: Lib/SimpleHTTPServer.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/SimpleHTTPServer.py,v retrieving revision 1.8 diff -c -r1.8 SimpleHTTPServer.py *** SimpleHTTPServer.py 1999/11/16 19:04:32 1.8 --- SimpleHTTPServer.py 2000/04/11 11:56:38 *************** *** 10,16 **** import os - import string import posixpath import BaseHTTPServer import urllib --- 10,15 ---- *************** *** 79,85 **** """ path = posixpath.normpath(urllib.unquote(path)) ! words = string.splitfields(path, '/') words = filter(None, words) path = os.getcwd() for word in words: --- 78,84 ---- """ path = posixpath.normpath(urllib.unquote(path)) ! words = path.split('/') words = filter(None, words) path = os.getcwd() for word in words: *************** *** 128,134 **** base, ext = posixpath.splitext(path) if self.extensions_map.has_key(ext): return self.extensions_map[ext] ! ext = string.lower(ext) if self.extensions_map.has_key(ext): return self.extensions_map[ext] else: --- 127,133 ---- base, ext = posixpath.splitext(path) if self.extensions_map.has_key(ext): return self.extensions_map[ext] ! ext = ext.lower() if self.extensions_map.has_key(ext): return self.extensions_map[ext] else: Index: Lib/StringIO.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/StringIO.py,v retrieving revision 1.9 diff -c -r1.9 StringIO.py *** StringIO.py 2000/02/28 15:12:25 1.9 --- StringIO.py 2000/04/11 11:56:38 *************** *** 28,35 **** - There's a simple test set (see end of this file). """ - import string - class StringIO: def __init__(self, buf = ''): self.buf = buf --- 28,33 ---- *************** *** 50,56 **** if self.closed: raise ValueError, "I/O operation on closed file" if self.buflist: ! self.buf = self.buf + string.joinfields(self.buflist, '') self.buflist = [] if mode == 1: pos = pos + self.pos --- 48,54 ---- if self.closed: raise ValueError, "I/O operation on closed file" if self.buflist: ! self.buf = self.buf + ''.join(self.buflist) self.buflist = [] if mode == 1: pos = pos + self.pos *************** *** 65,71 **** if self.closed: raise ValueError, "I/O operation on closed file" if self.buflist: ! self.buf = self.buf + string.joinfields(self.buflist, '') self.buflist = [] if n < 0: newpos = self.len --- 63,69 ---- if self.closed: raise ValueError, "I/O operation on closed file" if self.buflist: ! self.buf = self.buf + ''.join(self.buflist) self.buflist = [] if n < 0: newpos = self.len *************** *** 78,86 **** if self.closed: raise ValueError, "I/O operation on closed file" if self.buflist: ! self.buf = self.buf + string.joinfields(self.buflist, '') self.buflist = [] ! i = string.find(self.buf, '\n', self.pos) if i < 0: newpos = self.len else: --- 76,84 ---- if self.closed: raise ValueError, "I/O operation on closed file" if self.buflist: ! self.buf = self.buf + ''.join(self.buflist) self.buflist = [] ! i = self.buf.find('\n', self.pos) if i < 0: newpos = self.len else: *************** *** 108,114 **** newpos = self.pos + len(s) if self.pos < self.len: if self.buflist: ! self.buf = self.buf + string.joinfields(self.buflist, '') self.buflist = [] self.buflist = [self.buf[:self.pos], s, self.buf[newpos:]] self.buf = '' --- 106,112 ---- newpos = self.pos + len(s) if self.pos < self.len: if self.buflist: ! self.buf = self.buf + ''.join(self.buflist) self.buflist = [] self.buflist = [self.buf[:self.pos], s, self.buf[newpos:]] self.buf = '' *************** *** 117,129 **** self.len = newpos self.pos = newpos def writelines(self, list): ! self.write(string.joinfields(list, '')) def flush(self): if self.closed: raise ValueError, "I/O operation on closed file" def getvalue(self): if self.buflist: ! self.buf = self.buf + string.joinfields(self.buflist, '') self.buflist = [] return self.buf --- 115,127 ---- self.len = newpos self.pos = newpos def writelines(self, list): ! self.write(''.joinfields(list)) def flush(self): if self.closed: raise ValueError, "I/O operation on closed file" def getvalue(self): if self.buflist: ! self.buf = self.buf + ''.join(self.buflist) self.buflist = [] return self.buf Index: Lib/asynchat.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/asynchat.py,v retrieving revision 1.5 diff -c -r1.5 asynchat.py *** asynchat.py 2000/02/04 15:39:29 1.5 --- asynchat.py 2000/04/11 11:56:38 *************** *** 48,54 **** import socket import asyncore - import string class async_chat (asyncore.dispatcher): """This is an abstract class. You must derive from this class, and add --- 48,53 ---- *************** *** 120,126 **** # 3) end of buffer does not match any prefix: # collect data terminator_len = len(terminator) ! index = string.find (self.ac_in_buffer, terminator) if index != -1: # we found the terminator self.collect_incoming_data (self.ac_in_buffer[:index]) --- 119,125 ---- # 3) end of buffer does not match any prefix: # collect data terminator_len = len(terminator) ! index = self.ac_in_buffer.find (terminator) if index != -1: # we found the terminator self.collect_incoming_data (self.ac_in_buffer[:index]) Index: Lib/asyncore.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/asyncore.py,v retrieving revision 1.5 diff -c -r1.5 asyncore.py *** asyncore.py 2000/02/25 11:48:42 1.5 --- asyncore.py 2000/04/11 11:56:39 *************** *** 48,54 **** import select import socket - import string import sys import os --- 48,53 ---- *************** *** 152,158 **** status.append ('%s:%d' % self.addr) return '<%s %s at %x>' % ( self.__class__.__name__, ! string.join (status, ' '), id(self) ) except: --- 151,157 ---- status.append ('%s:%d' % self.addr) return '<%s %s at %x>' % ( self.__class__.__name__, ! ' '.join (status), id(self) ) except: *************** *** 407,418 **** del tb file, function, line = tbinfo[-1] ! info = '[' + string.join ( map ( ! lambda x: string.join (x, '|'), tbinfo ), ! '] [' ) + ']' return (file, function, line), t, v, info --- 406,417 ---- del tb file, function, line = tbinfo[-1] ! info = '[' + '] ['.join ( map ( ! lambda x: '|'.join (x), tbinfo ), ! ) + ']' return (file, function, line), t, v, info Index: Lib/bdb.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/bdb.py,v retrieving revision 1.27 diff -c -r1.27 bdb.py *** bdb.py 2000/02/02 15:10:14 1.27 --- bdb.py 2000/04/11 11:56:39 *************** *** 304,310 **** # def format_stack_entry(self, frame_lineno, lprefix=': '): ! import linecache, repr, string frame, lineno = frame_lineno filename = self.canonic(frame.f_code.co_filename) s = filename + '(' + `lineno` + ')' --- 304,310 ---- # def format_stack_entry(self, frame_lineno, lprefix=': '): ! import linecache, repr frame, lineno = frame_lineno filename = self.canonic(frame.f_code.co_filename) s = filename + '(' + `lineno` + ')' *************** *** 325,331 **** s = s + '->' s = s + repr.repr(rv) line = linecache.getline(filename, lineno) ! if line: s = s + lprefix + string.strip(line) return s # The following two methods can be called by clients to use --- 325,331 ---- s = s + '->' s = s + repr.repr(rv) line = linecache.getline(filename, lineno) ! if line: s = s + lprefix + line.strip() return s # The following two methods can be called by clients to use *************** *** 532,543 **** if not name: name = '???' print '+++ call', name, args def user_line(self, frame): ! import linecache, string name = frame.f_code.co_name if not name: name = '???' fn = self.canonic(frame.f_code.co_filename) line = linecache.getline(fn, frame.f_lineno) ! print '+++', fn, frame.f_lineno, name, ':', string.strip(line) def user_return(self, frame, retval): print '+++ return', retval def user_exception(self, frame, exc_stuff): --- 532,543 ---- if not name: name = '???' print '+++ call', name, args def user_line(self, frame): ! import linecache name = frame.f_code.co_name if not name: name = '???' fn = self.canonic(frame.f_code.co_filename) line = linecache.getline(fn, frame.f_lineno) ! print '+++', fn, frame.f_lineno, name, ':', line.strip() def user_return(self, frame, retval): print '+++ return', retval def user_exception(self, frame, exc_stuff): Index: Lib/binhex.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/binhex.py,v retrieving revision 1.12 diff -c -r1.12 binhex.py *** binhex.py 2000/02/04 15:39:29 1.12 --- binhex.py 2000/04/11 11:56:39 *************** *** 99,105 **** dsize = fp.tell() fp.close() dir, file = os.path.split(name) ! file = string.replace(file, ':', '-', 1) return file, finfo, dsize, 0 class openrsrc: --- 99,105 ---- dsize = fp.tell() fp.close() dir, file = os.path.split(name) ! file = file.replace(':', '-', 1) return file, finfo, dsize, 0 class openrsrc: Index: Lib/cgi.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/cgi.py,v retrieving revision 1.47 diff -c -r1.47 cgi.py *** cgi.py 2000/02/28 15:12:25 1.47 --- cgi.py 2000/04/11 11:56:40 *************** *** 518,524 **** if ctype == 'multipart/form-data': return parse_multipart(fp, pdict) elif ctype == 'application/x-www-form-urlencoded': ! clength = string.atoi(environ['CONTENT_LENGTH']) if maxlen and clength > maxlen: raise ValueError, 'Maximum content length exceeded' qs = fp.read(clength) --- 518,524 ---- if ctype == 'multipart/form-data': return parse_multipart(fp, pdict) elif ctype == 'application/x-www-form-urlencoded': ! clength = int(environ['CONTENT_LENGTH']) if maxlen and clength > maxlen: raise ValueError, 'Maximum content length exceeded' qs = fp.read(clength) *************** *** 589,604 **** Returns a list, as God intended. """ ! name_value_pairs = string.splitfields(qs, '&') r=[] for name_value in name_value_pairs: ! nv = string.splitfields(name_value, '=') if len(nv) != 2: if strict_parsing: raise ValueError, "bad query field: %s" % `name_value` continue ! name = urllib.unquote(string.replace(nv[0], '+', ' ')) ! value = urllib.unquote(string.replace(nv[1], '+', ' ')) r.append((name, value)) return r --- 589,604 ---- Returns a list, as God intended. """ ! name_value_pairs = qs.split('&') r=[] for name_value in name_value_pairs: ! nv = name_value.split('=') if len(nv) != 2: if strict_parsing: raise ValueError, "bad query field: %s" % `name_value` continue ! name = urllib.unquote(nv[0].replace('+', ' ')) ! value = urllib.unquote(nv[1].replace('+', ' ')) r.append((name, value)) return r *************** *** 643,650 **** clength = headers.getheader('content-length') if clength: try: ! bytes = string.atoi(clength) ! except string.atoi_error: pass if bytes > 0: if maxlen and bytes > maxlen: --- 643,650 ---- clength = headers.getheader('content-length') if clength: try: ! bytes = int(clength) ! except ValueError: pass if bytes > 0: if maxlen and bytes > maxlen: *************** *** 660,666 **** terminator = lastpart # End outer loop break if line[:2] == "--": ! terminator = string.strip(line) if terminator in (nextpart, lastpart): break lines.append(line) --- 660,666 ---- terminator = lastpart # End outer loop break if line[:2] == "--": ! terminator = line.strip() if terminator in (nextpart, lastpart): break lines.append(line) *************** *** 676,682 **** elif line[-1:] == "\n": line = line[:-1] lines[-1] = line ! data = string.joinfields(lines, "") line = headers['content-disposition'] if not line: continue --- 676,682 ---- elif line[-1:] == "\n": line = line[:-1] lines[-1] = line ! data = "".join(lines) line = headers['content-disposition'] if not line: continue *************** *** 701,715 **** Return the main content-type and a dictionary of options. """ ! plist = map(string.strip, string.splitfields(line, ';')) ! key = string.lower(plist[0]) del plist[0] pdict = {} for p in plist: ! i = string.find(p, '=') if i >= 0: ! name = string.lower(string.strip(p[:i])) ! value = string.strip(p[i+1:]) if len(value) >= 2 and value[0] == value[-1] == '"': value = value[1:-1] pdict[name] = value --- 701,715 ---- Return the main content-type and a dictionary of options. """ ! plist = map(lambda s: s.strip(), line.split(';')) ! key = plist[0].lower() del plist[0] pdict = {} for p in plist: ! i = p.find('=') if i >= 0: ! name = p[:i].strip().lower () ! value = p[i+1:].strip() if len(value) >= 2 and value[0] == value[-1] == '"': value = value[1:-1] pdict[name] = value *************** *** 820,826 **** self.keep_blank_values = keep_blank_values self.strict_parsing = strict_parsing if environ.has_key('REQUEST_METHOD'): ! method = string.upper(environ['REQUEST_METHOD']) if method == 'GET' or method == 'HEAD': if environ.has_key('QUERY_STRING'): qs = environ['QUERY_STRING'] --- 820,826 ---- self.keep_blank_values = keep_blank_values self.strict_parsing = strict_parsing if environ.has_key('REQUEST_METHOD'): ! method = environ['REQUEST_METHOD'].upper() if method == 'GET' or method == 'HEAD': if environ.has_key('QUERY_STRING'): qs = environ['QUERY_STRING'] *************** *** 884,890 **** clen = -1 if self.headers.has_key('content-length'): try: ! clen = string.atoi(self.headers['content-length']) except: pass if maxlen and clen > maxlen: --- 884,890 ---- clen = -1 if self.headers.has_key('content-length'): try: ! clen = int(self.headers['content-length']) except: pass if maxlen and clen > maxlen: *************** *** 1033,1039 **** break self.lines.append(line) if line[:2] == "--": ! strippedline = string.strip(line) if strippedline == next: break if strippedline == last: --- 1033,1039 ---- break self.lines.append(line) if line[:2] == "--": ! strippedline = line.strip() if strippedline == next: break if strippedline == last: *************** *** 1063,1069 **** break self.lines.append(line) if line[:2] == "--": ! strippedline = string.strip(line) if strippedline == next: break if strippedline == last: --- 1063,1069 ---- break self.lines.append(line) if line[:2] == "--": ! strippedline = line.strip() if strippedline == next: break if strippedline == last: *************** *** 1171,1181 **** def __getitem__( self, key ): v = SvFormContentDict.__getitem__( self, key ) if v[0] in string.digits+'+-.' : ! try: return string.atoi( v ) except ValueError: ! try: return string.atof( v ) except ValueError: pass ! return string.strip(v) def values( self ): lis = [] for key in self.keys(): --- 1171,1181 ---- def __getitem__( self, key ): v = SvFormContentDict.__getitem__( self, key ) if v[0] in string.digits+'+-.' : ! try: return int( v ) except ValueError: ! try: return float( v ) except ValueError: pass ! return v.strip() def values( self ): lis = [] for key in self.keys(): *************** *** 1211,1217 **** def length(self, key): return len(self.dict[key]) def stripped(self, key): ! if self.dict.has_key(key): return string.strip(self.dict[key][0]) else: return None def pars(self): return self.dict --- 1211,1217 ---- def length(self, key): return len(self.dict[key]) def stripped(self, key): ! if self.dict.has_key(key): return self.dict[key][0].strip() else: return None def pars(self): return self.dict *************** *** 1269,1275 **** list = traceback.format_tb(tb, limit) + \ traceback.format_exception_only(type, value) print "
%s%s
" % ( ! escape(string.join(list[:-1], "")), escape(list[-1]), ) del tb --- 1269,1275 ---- list = traceback.format_tb(tb, limit) + \ traceback.format_exception_only(type, value) print "
%s%s
" % ( ! escape("".join(list[:-1])), escape(list[-1]), ) del tb *************** *** 1369,1379 **** def escape(s, quote=None): """Replace special characters '&', '<' and '>' by SGML entities.""" ! s = string.replace(s, "&", "&") # Must be done first! ! s = string.replace(s, "<", "<") ! s = string.replace(s, ">", ">",) if quote: ! s = string.replace(s, '"', """) return s --- 1369,1378 ---- def escape(s, quote=None): """Replace special characters '&', '<' and '>' by SGML entities.""" ! # Replacing "&" with "&" must be done first! ! s = s.replace("&", "&").replace("<", "<").replace(">", ">") if quote: ! s = s.replace('"', """) return s Index: Lib/cmd.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/cmd.py,v retrieving revision 1.17 diff -c -r1.17 cmd.py *** cmd.py 2000/02/02 15:10:14 1.17 --- cmd.py 2000/04/11 11:56:41 *************** *** 89,95 **** pass def onecmd(self, line): ! line = string.strip(line) if line == '?': line = 'help' elif line == '!': --- 89,95 ---- pass def onecmd(self, line): ! line = line.strip() if line == '?': line = 'help' elif line == '!': *************** *** 102,108 **** self.lastcmd = line i, n = 0, len(line) while i < n and line[i] in self.identchars: i = i+1 ! cmd, arg = line[:i], string.strip(line[i:]) if cmd == '': return self.default(line) else: --- 102,108 ---- self.lastcmd = line i, n = 0, len(line) while i < n and line[i] in self.identchars: i = i+1 ! cmd, arg = line[:i], line[i:].strip() if cmd == '': return self.default(line) else: Index: Lib/code.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/code.py,v retrieving revision 1.9 diff -c -r1.9 code.py *** code.py 2000/02/28 15:12:25 1.9 --- code.py 2000/04/11 11:56:41 *************** *** 6,12 **** import sys - import string import traceback from codeop import compile_command --- 6,11 ---- *************** *** 242,248 **** """ self.buffer.append(line) ! source = string.join(self.buffer, "\n") more = self.runsource(source, self.filename) if not more: self.resetbuffer() --- 241,247 ---- """ self.buffer.append(line) ! source = "\n".join(self.buffer) more = self.runsource(source, self.filename) if not more: self.resetbuffer() Index: Lib/codeop.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/codeop.py,v retrieving revision 1.1 diff -c -r1.1 codeop.py *** codeop.py 1998/10/22 21:56:15 1.1 --- codeop.py 2000/04/11 11:56:41 *************** *** 1,7 **** """Utility to compile possibly incomplete Python source code.""" import sys - import string import traceback def compile_command(source, filename="", symbol="single"): --- 1,6 ---- *************** *** 47,54 **** """ # Check for source consisting of only blank lines and comments ! for line in string.split(source, "\n"): ! line = string.strip(line) if line and line[0] != '#': break # Leave it alone else: --- 46,53 ---- """ # Check for source consisting of only blank lines and comments ! for line in source.split("\n"): ! line = line.strip() if line and line[0] != '#': break # Leave it alone else: Index: Lib/dis.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/dis.py,v retrieving revision 1.21 diff -c -r1.21 dis.py *** dis.py 2000/03/30 15:02:11 1.21 --- dis.py 2000/04/11 11:56:41 *************** *** 1,7 **** """Disassembler of Python byte code into mnemonics.""" import sys - import string import types def dis(x=None): --- 1,6 ---- *************** *** 64,76 **** else: print ' ', if i in labels: print '>>', else: print ' ', ! print string.rjust(`i`, 4), ! print string.ljust(opname[op], 20), i = i+1 if op >= HAVE_ARGUMENT: oparg = ord(code[i]) + ord(code[i+1])*256 i = i+2 ! print string.rjust(`oparg`, 5), if op in hasconst: print '(' + `co.co_consts[oparg]` + ')', elif op in hasname: --- 63,75 ---- else: print ' ', if i in labels: print '>>', else: print ' ', ! print `i`.rjust(4), ! print opname[op].ljust(20), i = i+1 if op >= HAVE_ARGUMENT: oparg = ord(code[i]) + ord(code[i+1])*256 i = i+2 ! print `oparg`.rjust(5), if op in hasconst: print '(' + `co.co_consts[oparg]` + ')', elif op in hasname: Index: Lib/dospath.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/dospath.py,v retrieving revision 1.12 diff -c -r1.12 dospath.py *** dospath.py 2000/02/04 15:39:29 1.12 --- dospath.py 2000/04/11 11:56:41 *************** *** 15,21 **** single '_', but this has been removed. This functionality should possibly be added as a new function.""" ! return string.lower(string.replace(s, "/", "\\")) def isabs(s): --- 15,21 ---- single '_', but this has been removed. This functionality should possibly be added as a new function.""" ! return s.replace(s, "/", "\\").lower() def isabs(s): *************** *** 248,256 **** path = path[index + 1:] pathlen = len(path) try: ! index = string.index(path, '\'') res = res + '\'' + path[:index + 1] ! except string.index_error: res = res + path index = pathlen -1 elif c == '$': # variable or '$$' --- 248,256 ---- path = path[index + 1:] pathlen = len(path) try: ! index = path.index('\'') res = res + '\'' + path[:index + 1] ! except ValueError: res = res + path index = pathlen -1 elif c == '$': # variable or '$$' *************** *** 261,271 **** path = path[index+2:] pathlen = len(path) try: ! index = string.index(path, '}') var = path[:index] if os.environ.has_key(var): res = res + os.environ[var] ! except string.index_error: res = res + path index = pathlen - 1 else: --- 261,271 ---- path = path[index+2:] pathlen = len(path) try: ! index = path.index('}') var = path[:index] if os.environ.has_key(var): res = res + os.environ[var] ! except ValueError: res = res + path index = pathlen - 1 else: *************** *** 290,301 **** """Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A/B. Also, components of the path are silently truncated to 8+3 notation.""" ! path = string.replace(path, "/", "\\") prefix, path = splitdrive(path) while path[:1] == os.sep: prefix = prefix + os.sep path = path[1:] ! comps = string.splitfields(path, os.sep) i = 0 while i < len(comps): if comps[i] == '.': --- 290,301 ---- """Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A/B. Also, components of the path are silently truncated to 8+3 notation.""" ! path = path.replace("/", "\\") prefix, path = splitdrive(path) while path[:1] == os.sep: prefix = prefix + os.sep path = path[1:] ! comps = path.split(os.sep) i = 0 while i < len(comps): if comps[i] == '.': *************** *** 307,313 **** elif comps[i] == '' and i > 0 and comps[i-1] <> '': del comps[i] elif '.' in comps[i]: ! comp = string.splitfields(comps[i], '.') comps[i] = comp[0][:8] + '.' + comp[1][:3] i = i+1 elif len(comps[i]) > 8: --- 307,313 ---- elif comps[i] == '' and i > 0 and comps[i-1] <> '': del comps[i] elif '.' in comps[i]: ! comp = comps[i].split('.') comps[i] = comp[0][:8] + '.' + comp[1][:3] i = i+1 elif len(comps[i]) > 8: *************** *** 318,324 **** # If the path is now empty, substitute '.' if not prefix and not comps: comps.append('.') ! return prefix + string.joinfields(comps, os.sep) --- 318,324 ---- # If the path is now empty, substitute '.' if not prefix and not comps: comps.append('.') ! return prefix + os.sep.join(comps) Index: Lib/formatter.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/formatter.py,v retrieving revision 1.15 diff -c -r1.15 formatter.py *** formatter.py 2000/02/04 15:39:29 1.15 --- formatter.py 2000/04/11 11:56:42 *************** *** 157,175 **** label = s + label index = index + 1 if case == 'I': ! return string.upper(label) return label def add_flowing_data(self, data, # These are only here to load them into locals: ! whitespace = string.whitespace, ! join = string.join, split = string.split): if not data: return # The following looks a bit convoluted but is a great improvement over # data = regsub.gsub('[' + string.whitespace + ']+', ' ', data) prespace = data[:1] in whitespace postspace = data[-1:] in whitespace ! data = join(split(data)) if self.nospace and not data: return elif prespace or self.softspace: --- 157,174 ---- label = s + label index = index + 1 if case == 'I': ! return label.upper() return label def add_flowing_data(self, data, # These are only here to load them into locals: ! whitespace = string.whitespace): if not data: return # The following looks a bit convoluted but is a great improvement over # data = regsub.gsub('[' + string.whitespace + ']+', ' ', data) prespace = data[:1] in whitespace postspace = data[-1:] in whitespace ! data = ' '.join (data.split()) if self.nospace and not data: return elif prespace or self.softspace: *************** *** 369,379 **** def send_literal_data(self, data): self.file.write(data) ! i = string.rfind(data, '\n') if i >= 0: self.col = 0 data = data[i+1:] ! data = string.expandtabs(data) self.col = self.col + len(data) self.atbreak = 0 --- 368,378 ---- def send_literal_data(self, data): self.file.write(data) ! i = data.rfind('\n') if i >= 0: self.col = 0 data = data[i+1:] ! data = data.expandtabs() self.col = self.col + len(data) self.atbreak = 0 *************** *** 383,389 **** col = self.col maxcol = self.maxcol write = self.file.write ! for word in string.split(data): if atbreak: if col + len(word) >= maxcol: write('\n') --- 382,388 ---- col = self.col maxcol = self.maxcol write = self.file.write ! for word in data.split(): if atbreak: if col + len(word) >= maxcol: write('\n') Index: Lib/ftplib.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/ftplib.py,v retrieving revision 1.42 diff -c -r1.42 ftplib.py *** ftplib.py 2000/03/28 21:45:45 1.42 --- ftplib.py 2000/04/11 11:56:42 *************** *** 37,43 **** import os import sys - import string # Import SOCKS module if it exists, else standard socket module socket try: --- 37,42 ---- *************** *** 235,244 **** def sendport(self, host, port): '''Send a PORT command with the current host and the given port number.''' ! hbytes = string.splitfields(host, '.') pbytes = [`port/256`, `port%256`] bytes = hbytes + pbytes ! cmd = 'PORT ' + string.joinfields(bytes, ',') return self.voidcmd(cmd) def makeport(self): --- 234,243 ---- def sendport(self, host, port): '''Send a PORT command with the current host and the given port number.''' ! hbytes = host.split('.') pbytes = [`port/256`, `port%256`] bytes = hbytes + pbytes ! cmd = 'PORT ' + ','.join(bytes) return self.voidcmd(cmd) def makeport(self): *************** *** 448,454 **** # Note that the RFC doesn't say anything about 'SIZE' resp = self.sendcmd('SIZE ' + filename) if resp[:3] == '213': ! return string.atoi(string.strip(resp[3:])) def mkd(self, dirname): '''Make a directory, return its full pathname.''' --- 447,453 ---- # Note that the RFC doesn't say anything about 'SIZE' resp = self.sendcmd('SIZE ' + filename) if resp[:3] == '213': ! return int(resp[3:].strip()) def mkd(self, dirname): '''Make a directory, return its full pathname.''' *************** *** 492,498 **** _150_re = re.compile("150 .* \((\d+) bytes\)", re.IGNORECASE) m = _150_re.match(resp) if m: ! return string.atoi(m.group(1)) return None --- 491,497 ---- _150_re = re.compile("150 .* \((\d+) bytes\)", re.IGNORECASE) m = _150_re.match(resp) if m: ! return int(m.group(1)) return None *************** *** 503,518 **** if resp[:3] <> '227': raise error_reply, resp ! left = string.find(resp, '(') if left < 0: raise error_proto, resp ! right = string.find(resp, ')', left + 1) if right < 0: raise error_proto, resp # should contain '(h1,h2,h3,h4,p1,p2)' ! numbers = string.split(resp[left+1:right], ',') if len(numbers) <> 6: raise error_proto, resp ! host = string.join(numbers[:4], '.') ! port = (string.atoi(numbers[4]) << 8) + string.atoi(numbers[5]) return host, port --- 502,517 ---- if resp[:3] <> '227': raise error_reply, resp ! left = resp.find('(') if left < 0: raise error_proto, resp ! right = resp.find(')', left + 1) if right < 0: raise error_proto, resp # should contain '(h1,h2,h3,h4,p1,p2)' ! numbers = resp[left+1:right].split(',') if len(numbers) <> 6: raise error_proto, resp ! host = '.'.join(numbers[:4]) ! port = (int(numbers[4]) << 8) + int(numbers[5]) return host, port *************** *** 590,602 **** while 1: line = fp.readline() if not line: break ! if in_macro and string.strip(line): macro_lines.append(line) continue elif in_macro: self.__macros[macro_name] = tuple(macro_lines) in_macro = 0 ! words = string.split(line) host = user = passwd = acct = None default = 0 i = 0 --- 589,601 ---- while 1: line = fp.readline() if not line: break ! if in_macro and line.strip(): macro_lines.append(line) continue elif in_macro: self.__macros[macro_name] = tuple(macro_lines) in_macro = 0 ! words = line.split() host = user = passwd = acct = None default = 0 i = 0 *************** *** 609,615 **** if w1 == 'default': default = 1 elif w1 == 'machine' and w2: ! host = string.lower(w2) i = i + 1 elif w1 == 'login' and w2: user = w2 --- 608,614 ---- if w1 == 'default': default = 1 elif w1 == 'machine' and w2: ! host = w2.lower() i = i + 1 elif w1 == 'login' and w2: user = w2 *************** *** 651,657 **** password, and the accounting field. """ ! host = string.lower(host) user = passwd = acct = None if self.__hosts.has_key(host): user, passwd, acct = self.__hosts[host] --- 650,656 ---- password, and the accounting field. """ ! host = host.lower() user = passwd = acct = None if self.__hosts.has_key(host): user, passwd, acct = self.__hosts[host] Index: Lib/gopherlib.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/gopherlib.py,v retrieving revision 1.7 diff -c -r1.7 gopherlib.py *** gopherlib.py 2000/03/28 21:45:45 1.7 --- gopherlib.py 2000/04/11 11:56:42 *************** *** 1,7 **** """Gopher protocol client interface.""" - import string - # Default selector, host and port DEF_SELECTOR = '1/' DEF_HOST = 'gopher.micro.umn.edu' --- 1,5 ---- *************** *** 56,70 **** def send_selector(selector, host, port = 0): """Send a selector to a given host and port, return a file with the reply.""" import socket - import string if not port: ! i = string.find(host, ':') if i >= 0: ! host, port = host[:i], string.atoi(host[i+1:]) if not port: port = DEF_PORT elif type(port) == type(''): ! port = string.atoi(port) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) s.send(selector + CRLF) --- 54,67 ---- def send_selector(selector, host, port = 0): """Send a selector to a given host and port, return a file with the reply.""" import socket if not port: ! i = host.find(':') if i >= 0: ! host, port = host[:i], int(host[i+1:]) if not port: port = DEF_PORT elif type(port) == type(''): ! port = int(port) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) s.send(selector + CRLF) *************** *** 96,102 **** def get_directory(f): """Get a directory in the form of a list of entries.""" - import string list = [] while 1: line = f.readline() --- 93,98 ---- *************** *** 113,119 **** print '(Empty line from server)' continue gtype = line[0] ! parts = string.splitfields(line[1:], TAB) if len(parts) < 4: print '(Bad line from server:', `line`, ')' continue --- 109,115 ---- print '(Empty line from server)' continue gtype = line[0] ! parts = line[1:].split(TAB) if len(parts) < 4: print '(Bad line from server:', `line`, ')' continue Index: Lib/gzip.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/gzip.py,v retrieving revision 1.17 diff -c -r1.17 gzip.py *** gzip.py 2000/02/04 15:39:29 1.17 --- gzip.py 2000/04/11 11:56:42 *************** *** 6,12 **** # based on Andrew Kuchling's minigzip.py distributed with the zlib module import time - import string import zlib import struct import __builtin__ --- 6,11 ---- *************** *** 138,144 **** self.fileobj.write( self.compress.compress(data) ) def writelines(self,lines): ! self.write(string.join(lines)) def read(self, size=-1): if self.extrasize <= 0 and self.fileobj is None: --- 137,143 ---- self.fileobj.write( self.compress.compress(data) ) def writelines(self,lines): ! self.write(' '.join (lines)) def read(self, size=-1): if self.extrasize <= 0 and self.fileobj is None: *************** *** 274,290 **** readsize = 100 while 1: c = self.read(readsize) ! i = string.find(c, '\n') if i >= 0 or c == '': bufs.append(c[:i+1]) self._unread(c[i+1:]) ! return string.join(bufs, '') bufs.append(c) readsize = readsize * 2 def readlines(self, ignored=None): buf = self.read() ! lines = string.split(buf, '\n') for i in range(len(lines)-1): lines[i] = lines[i] + '\n' if lines and not lines[-1]: --- 273,289 ---- readsize = 100 while 1: c = self.read(readsize) ! i = c.find('\n') if i >= 0 or c == '': bufs.append(c[:i+1]) self._unread(c[i+1:]) ! return ''.join(bufs) bufs.append(c) readsize = readsize * 2 def readlines(self, ignored=None): buf = self.read() ! lines = buf.split('\n') for i in range(len(lines)-1): lines[i] = lines[i] + '\n' if lines and not lines[-1]: Index: Lib/htmllib.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/htmllib.py,v retrieving revision 1.14 diff -c -r1.14 htmllib.py *** htmllib.py 1999/05/03 18:10:15 1.14 --- htmllib.py 2000/04/11 11:56:42 *************** *** 5,11 **** """ - import string from sgmllib import SGMLParser from formatter import AS_IS --- 5,10 ---- *************** *** 49,55 **** data = self.savedata self.savedata = None if not self.nofill: ! data = string.join(string.split(data)) return data # --- Hooks for anchors; should probably be overridden --- 48,54 ---- data = self.savedata self.savedata = None if not self.nofill: ! data = ''.join(data.split()) return data # --- Hooks for anchors; should probably be overridden *************** *** 320,332 **** name = '' type = '' for attrname, value in attrs: ! value = string.strip(value) if attrname == 'href': href = value if attrname == 'name': name = value if attrname == 'type': ! type = string.lower(value) self.anchor_bgn(href, name, type) def end_a(self): --- 319,331 ---- name = '' type = '' for attrname, value in attrs: ! value = value.strip() if attrname == 'href': href = value if attrname == 'name': name = value if attrname == 'type': ! type = value.lower() self.anchor_bgn(href, name, type) def end_a(self): *************** *** 361,370 **** if attrname == 'src': src = value if attrname == 'width': ! try: width = string.atoi(value) except: pass if attrname == 'height': ! try: height = string.atoi(value) except: pass self.handle_image(src, alt, ismap, align, width, height) --- 360,369 ---- if attrname == 'src': src = value if attrname == 'width': ! try: width = int(value) except: pass if attrname == 'height': ! try: height = int(value) except: pass self.handle_image(src, alt, ismap, align, width, height) Index: Lib/httplib.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/httplib.py,v retrieving revision 1.15 diff -c -r1.15 httplib.py *** httplib.py 2000/03/28 21:45:45 1.15 --- httplib.py 2000/04/11 11:56:43 *************** *** 30,36 **** import os import socket - import string import mimetools try: --- 30,35 ---- *************** *** 100,110 **** """ if not port: ! i = string.find(host, ':') if i >= 0: host, port = host[:i], host[i+1:] ! try: port = string.atoi(port) ! except string.atoi_error: raise socket.error, "nonnumeric port" if not port: port = HTTP_PORT self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) --- 99,109 ---- """ if not port: ! i = host.find(':') if i >= 0: host, port = host[:i], host[i+1:] ! try: port = int(port) ! except ValueError: raise socket.error, "nonnumeric port" if not port: port = HTTP_PORT self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) *************** *** 134,140 **** For example: h.putheader('Accept', 'text/html') """ ! str = '%s: %s\r\n' % (header, string.joinfields(args,'\r\n\t')) self.send(str) def endheaders(self): --- 133,139 ---- For example: h.putheader('Accept', 'text/html') """ ! str = '%s: %s\r\n' % (header, '\r\n\t'.join(args)) self.send(str) def endheaders(self): *************** *** 154,163 **** line = self.file.readline() if self.debuglevel > 0: print 'reply:', `line` try: ! [ver, code, msg] = string.split(line, None, 2) except ValueError: try: ! [ver, code] = string.split(line, None, 1) msg = "" except ValueError: self.headers = None --- 153,162 ---- line = self.file.readline() if self.debuglevel > 0: print 'reply:', `line` try: ! [ver, code, msg] = line.split(None, 2) except ValueError: try: ! [ver, code] = line.split(None, 1) msg = "" except ValueError: self.headers = None *************** *** 165,172 **** if ver[:5] != 'HTTP/': self.headers = None return -1, line, self.headers ! errcode = string.atoi(code) ! errmsg = string.strip(msg) self.headers = mimetools.Message(self.file, 0) return errcode, errmsg, self.headers --- 164,171 ---- if ver[:5] != 'HTTP/': self.headers = None return -1, line, self.headers ! errcode = int(code) ! errmsg = msg.strip() self.headers = mimetools.Message(self.file, 0) return errcode, errmsg, self.headers *************** *** 200,210 **** """ if not port: ! i = string.find(host, ':') if i >= 0: host, port = host[:i], host[i+1:] ! try: port = string.atoi(port) ! except string.atoi_error: raise socket.error, "nonnumeric port" if not port: port = HTTPS_PORT sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) --- 199,209 ---- """ if not port: ! i = host.find(':') if i >= 0: host, port = host[:i], host[i+1:] ! try: port = int(port) ! except ValueError: raise socket.error, "nonnumeric port" if not port: port = HTTPS_PORT sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) *************** *** 243,249 **** print 'errmsg =', errmsg print if headers: ! for header in headers.headers: print string.strip(header) print print h.getfile().read() if hasattr(socket, "ssl"): --- 242,248 ---- print 'errmsg =', errmsg print if headers: ! for header in headers.headers: print header.strip() print print h.getfile().read() if hasattr(socket, "ssl"): *************** *** 263,269 **** print 'errmsg =', errmsg print if headers: ! for header in headers.headers: print string.strip(header) print print h.getfile().read() --- 262,268 ---- print 'errmsg =', errmsg print if headers: ! for header in headers.headers: print header.strip() print print h.getfile().read() Index: Lib/ihooks.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/ihooks.py,v retrieving revision 1.9 diff -c -r1.9 ihooks.py *** ihooks.py 1998/06/29 20:31:16 1.9 --- ihooks.py 2000/04/11 11:56:43 *************** *** 55,61 **** import imp import os import sys - import string VERBOSE = 0 --- 55,60 ---- *************** *** 410,416 **** assert globals is parent.__dict__ return parent if '.' in pname: ! i = string.rfind(pname, '.') pname = pname[:i] parent = self.modules[pname] assert parent.__name__ == pname --- 409,415 ---- assert globals is parent.__dict__ return parent if '.' in pname: ! i = pname.rfind('.') pname = pname[:i] parent = self.modules[pname] assert parent.__name__ == pname *************** *** 419,425 **** def find_head_package(self, parent, name): if '.' in name: ! i = string.find(name, '.') head = name[:i] tail = name[i+1:] else: --- 418,424 ---- def find_head_package(self, parent, name): if '.' in name: ! i = name.find('.') head = name[:i] tail = name[i+1:] else: *************** *** 441,447 **** def load_tail(self, q, tail): m = q while tail: ! i = string.find(tail, '.') if i < 0: i = len(tail) head, tail = tail[:i], tail[i+1:] mname = "%s.%s" % (m.__name__, head) --- 440,446 ---- def load_tail(self, q, tail): m = q while tail: ! i = tail.find('.') if i < 0: i = len(tail) head, tail = tail[:i], tail[i+1:] mname = "%s.%s" % (m.__name__, head) *************** *** 490,496 **** name = module.__name__ if '.' not in name: return self.import_it(name, name, None) ! i = string.rfind(name, '.') pname = name[:i] parent = self.modules[pname] return self.import_it(name[i+1:], name, parent) --- 489,495 ---- name = module.__name__ if '.' not in name: return self.import_it(name, name, None) ! i = name.rfind('.') pname = name[:i] parent = self.modules[pname] return self.import_it(name[i+1:], name, parent) Index: Lib/imaplib.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/imaplib.py,v retrieving revision 1.20 diff -c -r1.20 imaplib.py *** imaplib.py 2000/03/28 21:45:46 1.20 --- imaplib.py 2000/04/11 11:56:43 *************** *** 17,23 **** __version__ = "2.36" ! import binascii, re, socket, string, time, random, sys # Globals --- 17,23 ---- __version__ = "2.36" ! import binascii, re, socket, time, random, sys # Globals *************** *** 162,168 **** self._simple_command(cap) if not self.untagged_responses.has_key(cap): raise self.error('no CAPABILITY response from server') ! self.capabilities = tuple(string.split(string.upper(self.untagged_responses[cap][-1]))) if __debug__: if self.debug >= 3: --- 162,168 ---- self._simple_command(cap) if not self.untagged_responses.has_key(cap): raise self.error('no CAPABILITY response from server') ! self.capabilities = tuple(self.untagged_responses[cap][-1].upper().split()) if __debug__: if self.debug >= 3: *************** *** 180,186 **** def __getattr__(self, attr): # Allow UPPERCASE variants of IMAP4 command methods. if Commands.has_key(attr): ! return eval("self.%s" % string.lower(attr)) raise AttributeError("Unknown IMAP4 command: '%s'" % attr) --- 180,186 ---- def __getattr__(self, attr): # Allow UPPERCASE variants of IMAP4 command methods. if Commands.has_key(attr): ! return eval("self.%s" % attr.lower()) raise AttributeError("Unknown IMAP4 command: '%s'" % attr) *************** *** 219,225 **** (code, [data]) = .response(code) """ ! return self._untagged_response(code, [None], string.upper(code)) def socket(self): --- 219,225 ---- (code, [data]) = .response(code) """ ! return self._untagged_response(code, [None], code.upper()) def socket(self): *************** *** 273,279 **** It should return None if the client abort response '*' should be sent instead. """ ! mech = string.upper(mechanism) cap = 'AUTH=%s' % mech if not cap in self.capabilities: raise self.error("Server doesn't allow %s authentication." % mech) --- 273,279 ---- It should return None if the client abort response '*' should be sent instead. """ ! mech = mechanism.upper() cap = 'AUTH=%s' % mech if not cap in self.capabilities: raise self.error("Server doesn't allow %s authentication." % mech) *************** *** 527,533 **** Returns response appropriate to 'command'. """ ! command = string.upper(command) if not Commands.has_key(command): raise self.error("Unknown IMAP4 UID command: %s" % command) if self.state not in Commands[command]: --- 527,533 ---- Returns response appropriate to 'command'. """ ! command = command.upper() if not Commands.has_key(command): raise self.error("Unknown IMAP4 UID command: %s" % command) if self.state not in Commands[command]: *************** *** 719,725 **** # Read literal direct from connection. ! size = string.atoi(self.mo.group('size')) if __debug__: if self.debug >= 4: _mesg('read literal size %s' % size) --- 719,725 ---- # Read literal direct from connection. ! size = int(self.mo.group('size')) if __debug__: if self.debug >= 4: _mesg('read literal size %s' % size) *************** *** 822,829 **** def _quote(self, arg): ! arg = string.replace(arg, '\\', '\\\\') ! arg = string.replace(arg, '"', '\\"') return '"%s"' % arg --- 822,828 ---- def _quote(self, arg): ! arg = arg.replace('\\', '\\\\').replace('"', '\\"') return '"%s"' % arg *************** *** 910,916 **** zonen = mo.group('zonen') for name in ('day', 'year', 'hour', 'min', 'sec', 'zoneh', 'zonem'): ! exec "%s = string.atoi(mo.group('%s'))" % (name, name) # INTERNALDATE timezone must be subtracted to get UT --- 909,915 ---- zonen = mo.group('zonen') for name in ('day', 'year', 'hour', 'min', 'sec', 'zoneh', 'zonem'): ! exec "%s = int(mo.group('%s'))" % (name, name) # INTERNALDATE timezone must be subtracted to get UT *************** *** 956,962 **** if not mo: return () ! return tuple(string.split(mo.group('flags'))) def Time2Internaldate(date_time): --- 955,961 ---- if not mo: return () ! return tuple(mo.group('flags').split()) def Time2Internaldate(date_time): *************** *** 1000,1008 **** l = dict.items() if not l: return t = '\n\t\t' ! j = string.join ! l = map(lambda x,j=j:'%s: "%s"' % (x[0], x[1][0] and j(x[1], '" "') or ''), l) ! _mesg('untagged responses dump:%s%s' % (t, j(l, t))) _cmd_log = [] # Last `_cmd_log_len' interactions _cmd_log_len = 10 --- 999,1006 ---- l = dict.items() if not l: return t = '\n\t\t' ! l = map(lambda x:'%s: "%s"' % (x[0], x[1][0] and '" "'.join (x[1]) or ''), l) ! _mesg('untagged responses dump:%s%s' % (t, t.join(l))) _cmd_log = [] # Last `_cmd_log_len' interactions _cmd_log_len = 10 *************** *** 1083,1089 **** for ml in run('list', ('/tmp/', 'yy%')): mo = re.match(r'.*"([^"]+)"$', ml) if mo: path = mo.group(1) ! else: path = string.split(ml)[-1] run('delete', (path,)) for cmd,args in test_seq2: --- 1081,1087 ---- for ml in run('list', ('/tmp/', 'yy%')): mo = re.match(r'.*"([^"]+)"$', ml) if mo: path = mo.group(1) ! else: path = ml.split()[-1] run('delete', (path,)) for cmd,args in test_seq2: *************** *** 1092,1098 **** if (cmd,args) != ('uid', ('SEARCH', 'ALL')): continue ! uid = string.split(dat[-1]) if not uid: continue run('uid', ('FETCH', '%s' % uid[-1], '(FLAGS INTERNALDATE RFC822.SIZE RFC822.HEADER RFC822.TEXT)')) --- 1090,1096 ---- if (cmd,args) != ('uid', ('SEARCH', 'ALL')): continue ! uid = dat[-1].split() if not uid: continue run('uid', ('FETCH', '%s' % uid[-1], '(FLAGS INTERNALDATE RFC822.SIZE RFC822.HEADER RFC822.TEXT)')) Index: Lib/keyword.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/keyword.py,v retrieving revision 1.8 diff -c -r1.8 keyword.py *** keyword.py 2000/02/04 15:10:33 1.8 --- keyword.py 2000/04/11 11:56:43 *************** *** 50,56 **** iskeyword = kwdict.has_key def main(): ! import sys, re, string args = sys.argv[1:] iptfile = args and args[0] or "Python/graminit.c" --- 50,56 ---- iskeyword = kwdict.has_key def main(): ! import sys, re args = sys.argv[1:] iptfile = args and args[0] or "Python/graminit.c" *************** *** 64,70 **** while 1: line = fp.readline() if not line: break ! if string.find(line, '{1, "') > -1: match = strprog.search(line) if match: lines.append(" '" + match.group(1) + "',\n") --- 64,70 ---- while 1: line = fp.readline() if not line: break ! if line.find('{1, "') > -1: match = strprog.search(line) if match: lines.append(" '" + match.group(1) + "',\n") *************** *** 87,93 **** # write the output file fp = open(optfile, 'w') ! fp.write(string.join(format, '')) fp.close() if __name__ == "__main__": --- 87,93 ---- # write the output file fp = open(optfile, 'w') ! fp.write(''.join(format)) fp.close() if __name__ == "__main__": Index: Lib/knee.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/knee.py,v retrieving revision 1.4 diff -c -r1.4 knee.py *** knee.py 1998/03/26 21:12:20 1.4 --- knee.py 2000/04/11 11:56:44 *************** *** 7,13 **** """ ! import sys, imp, __builtin__, string # Replacement for __import__() --- 7,13 ---- """ ! import sys, imp, __builtin__ # Replacement for __import__() *************** *** 30,36 **** assert globals is parent.__dict__ return parent if '.' in pname: ! i = string.rfind(pname, '.') pname = pname[:i] parent = sys.modules[pname] assert parent.__name__ == pname --- 30,36 ---- assert globals is parent.__dict__ return parent if '.' in pname: ! i = pname.rfind('.') pname = pname[:i] parent = sys.modules[pname] assert parent.__name__ == pname *************** *** 39,45 **** def find_head_package(parent, name): if '.' in name: ! i = string.find(name, '.') head = name[:i] tail = name[i+1:] else: --- 39,45 ---- def find_head_package(parent, name): if '.' in name: ! i = name.find('.') head = name[:i] tail = name[i+1:] else: *************** *** 61,67 **** def load_tail(q, tail): m = q while tail: ! i = string.find(tail, '.') if i < 0: i = len(tail) head, tail = tail[:i], tail[i+1:] mname = "%s.%s" % (m.__name__, head) --- 61,67 ---- def load_tail(q, tail): m = q while tail: ! i = tail.find('.') if i < 0: i = len(tail) head, tail = tail[:i], tail[i+1:] mname = "%s.%s" % (m.__name__, head) *************** *** 111,117 **** name = module.__name__ if '.' not in name: return import_module(name, name, None) ! i = string.rfind(name, '.') pname = name[:i] parent = sys.modules[pname] return import_module(name[i+1:], name, parent) --- 111,117 ---- name = module.__name__ if '.' not in name: return import_module(name, name, None) ! i = name.rfind('.') pname = name[:i] parent = sys.modules[pname] return import_module(name[i+1:], name, parent) Index: Lib/locale.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/locale.py,v retrieving revision 1.4 diff -c -r1.4 locale.py *** locale.py 2000/02/04 15:39:29 1.4 --- locale.py 2000/04/11 11:56:44 *************** *** 3,9 **** # Author: Martin von Loewis from _locale import * - import string #perform the grouping from right to left def _group(s): --- 3,8 ---- *************** *** 34,40 **** but takes the current locale into account. Grouping is applied if the third parameter is true.""" result = f % val ! fields = string.splitfields(result,".") if grouping: fields[0]=_group(fields[0]) if len(fields)==2: --- 33,39 ---- but takes the current locale into account. Grouping is applied if the third parameter is true.""" result = f % val ! fields = result.split(".") if grouping: fields[0]=_group(fields[0]) if len(fields)==2: *************** *** 48,67 **** """Convert float to integer, taking the locale into account.""" return format("%.12g",val) ! def atof(str,func=string.atof): "Parses a string as a float according to the locale settings." #First, get rid of the grouping ! s=string.splitfields(str,localeconv()['thousands_sep']) ! str=string.join(s,"") #next, replace the decimal point with a dot ! s=string.splitfields(str,localeconv()['decimal_point']) ! str=string.join(s,'.') #finally, parse the string return func(str) def atoi(str): "Converts a string to an integer according to the locale settings." ! return atof(str,string.atoi) def test(): setlocale(LC_ALL,"") --- 47,64 ---- """Convert float to integer, taking the locale into account.""" return format("%.12g",val) ! def atof(str,func=float): "Parses a string as a float according to the locale settings." #First, get rid of the grouping ! str=str.replace(localeconv()['thousands_sep'], '') #next, replace the decimal point with a dot ! str=str.replace(localeconv()['decimal_point'], '.') #finally, parse the string return func(str) def atoi(str): "Converts a string to an integer according to the locale settings." ! return atof(str,int) def test(): setlocale(LC_ALL,"") Index: Lib/macpath.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/macpath.py,v retrieving revision 1.21 diff -c -r1.21 macpath.py *** macpath.py 2000/02/04 15:10:33 1.21 --- macpath.py 2000/04/11 11:56:44 *************** *** 1,15 **** """Pathname and path-related operations for the Macintosh.""" - import string import os from stat import * # Normalize the case of a pathname. Dummy in Posix, but string.lower here. ! normcase = string.lower - def isabs(s): """Return true if a path is absolute. On the Mac, relative paths begin with a colon, --- 1,14 ---- """Pathname and path-related operations for the Macintosh.""" import os from stat import * # Normalize the case of a pathname. Dummy in Posix, but string.lower here. ! def normcase(path): ! return path.lower () def isabs(s): """Return true if a path is absolute. On the Mac, relative paths begin with a colon, *************** *** 163,172 **** # XXX The Unix version doesn't raise an exception but simply # returns an unnormalized path. Should do so here too. - import string if ':' not in s: return ':' + s ! f = string.splitfields(s, ':') pre = [] post = [] if not f[0]: --- 162,170 ---- # XXX The Unix version doesn't raise an exception but simply # returns an unnormalized path. Should do so here too. if ':' not in s: return ':' + s ! f = s.split(':') pre = [] post = [] if not f[0]: Index: Lib/macurl2path.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/macurl2path.py,v retrieving revision 1.7 diff -c -r1.7 macurl2path.py *** macurl2path.py 2000/02/04 15:39:29 1.7 --- macurl2path.py 2000/04/11 11:56:44 *************** *** 2,8 **** Do not import directly; use urllib instead.""" - import string import urllib import os --- 2,7 ---- *************** *** 19,25 **** pathname = pathname[2:] elif pathname[:2] == '//': raise RuntimeError, 'Cannot convert non-local URL to pathname' ! components = string.split(pathname, '/') # Remove . and embedded .. i = 0 while i < len(components): --- 18,24 ---- pathname = pathname[2:] elif pathname[:2] == '//': raise RuntimeError, 'Cannot convert non-local URL to pathname' ! components = pathname.split('/') # Remove . and embedded .. i = 0 while i < len(components): *************** *** 35,41 **** i = i+1 if not components[0]: # Absolute unix path, don't start with colon ! rv = string.join(components[1:], ':') else: # relative unix path, start with colon. First replace # leading .. by empty strings (giving ::file) --- 34,40 ---- i = i+1 if not components[0]: # Absolute unix path, don't start with colon ! rv = ':'.join(components[1:]) else: # relative unix path, start with colon. First replace # leading .. by empty strings (giving ::file) *************** *** 43,49 **** while i < len(components) and components[i] == '..': components[i] = '' i = i + 1 ! rv = ':' + string.join(components, ':') # and finally unquote slashes and other funny characters return urllib.unquote(rv) --- 42,48 ---- while i < len(components) and components[i] == '..': components[i] = '' i = i + 1 ! rv = ':' + ':'.join(components) # and finally unquote slashes and other funny characters return urllib.unquote(rv) *************** *** 51,57 **** "convert mac pathname to /-delimited pathname" if '/' in pathname: raise RuntimeError, "Cannot convert pathname containing slashes" ! components = string.split(pathname, ':') # Remove empty first and/or last component if components[0] == '': del components[0] --- 50,56 ---- "convert mac pathname to /-delimited pathname" if '/' in pathname: raise RuntimeError, "Cannot convert pathname containing slashes" ! components = pathname.split(':') # Remove empty first and/or last component if components[0] == '': del components[0] *************** *** 65,73 **** components = map(_pncomp2url, components) if os.path.isabs(pathname): ! return '/' + string.join(components, '/') else: ! return string.join(components, '/') def _pncomp2url(component): component = urllib.quote(component[:31], safe='') # We want to quote slashes --- 64,72 ---- components = map(_pncomp2url, components) if os.path.isabs(pathname): ! return '/' + '/'.join(components) else: ! return '/'.join(components) def _pncomp2url(component): component = urllib.quote(component[:31], safe='') # We want to quote slashes Index: Lib/mailbox.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/mailbox.py,v retrieving revision 1.19 diff -c -r1.19 mailbox.py *** mailbox.py 2000/04/04 03:31:39 1.19 --- mailbox.py 2000/04/11 11:56:44 *************** *** 177,196 **** # Qmail directory mailbox def __init__(self, dirname): - import string self.dirname = dirname self.boxes = [] # check for new mail newdir = os.path.join(self.dirname, 'new') for file in os.listdir(newdir): ! if len(string.split(file, '.')) > 2: self.boxes.append(os.path.join(newdir, file)) # Now check for current mail in this maildir curdir = os.path.join(self.dirname, 'cur') for file in os.listdir(curdir): ! if len(string.split(file, '.')) > 2: self.boxes.append(os.path.join(curdir, file)) def next(self): --- 177,195 ---- # Qmail directory mailbox def __init__(self, dirname): self.dirname = dirname self.boxes = [] # check for new mail newdir = os.path.join(self.dirname, 'new') for file in os.listdir(newdir): ! if len(file.split('.')) > 2: self.boxes.append(os.path.join(newdir, file)) # Now check for current mail in this maildir curdir = os.path.join(self.dirname, 'cur') for file in os.listdir(curdir): ! if len(file.split('.')) > 2: self.boxes.append(os.path.join(curdir, file)) def next(self): *************** *** 225,231 **** def _test(): import time import sys - import string import os args = sys.argv[1:] --- 224,229 ---- *************** *** 261,267 **** if len(args) <= 1: msg.fp = None if len(args) > 1: ! num = string.atoi(args[1]) print 'Message %d body:'%num msg = msgs[num-1] msg.rewindbody() --- 259,265 ---- if len(args) <= 1: msg.fp = None if len(args) > 1: ! num = int(args[1]) print 'Message %d body:'%num msg = msgs[num-1] msg.rewindbody() Index: Lib/mailcap.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/mailcap.py,v retrieving revision 1.5 diff -c -r1.5 mailcap.py *** mailcap.py 2000/02/04 15:10:33 1.5 --- mailcap.py 2000/04/11 11:56:44 *************** *** 1,7 **** """Mailcap file handling. See RFC 1524.""" import os - import string # Part 1: top-level interface. --- 1,6 ---- *************** *** 36,42 **** # XXX Actually, this is Unix-specific if os.environ.has_key('MAILCAPS'): str = os.environ['MAILCAPS'] ! mailcaps = string.splitfields(str, ':') else: if os.environ.has_key('HOME'): home = os.environ['HOME'] --- 35,41 ---- # XXX Actually, this is Unix-specific if os.environ.has_key('MAILCAPS'): str = os.environ['MAILCAPS'] ! mailcaps = str.split(':') else: if os.environ.has_key('HOME'): home = os.environ['HOME'] *************** *** 64,70 **** line = fp.readline() if not line: break # Ignore comments and blank lines ! if line[0] == '#' or string.strip(line) == '': continue nextline = line # Join continuation lines --- 63,69 ---- line = fp.readline() if not line: break # Ignore comments and blank lines ! if line[0] == '#' or line.strip() == '': continue nextline = line # Join continuation lines *************** *** 77,86 **** if not (key and fields): continue # Normalize the key ! types = string.splitfields(key, '/') for j in range(len(types)): ! types[j] = string.strip(types[j]) ! key = string.lower(string.joinfields(types, '/')) # Update the database if caps.has_key(key): caps[key].append(fields) --- 76,85 ---- if not (key and fields): continue # Normalize the key ! types = key.split('/') for j in range(len(types)): ! types[j] = types[j].strip() ! key = '/'.join(types).lower() # Update the database if caps.has_key(key): caps[key].append(fields) *************** *** 105,117 **** key, view, rest = fields[0], fields[1], fields[2:] fields = {'view': view} for field in rest: ! i = string.find(field, '=') if i < 0: fkey = field fvalue = "" else: ! fkey = string.strip(field[:i]) ! fvalue = string.strip(field[i+1:]) if fields.has_key(fkey): # Ignore it pass --- 104,116 ---- key, view, rest = fields[0], fields[1], fields[2:] fields = {'view': view} for field in rest: ! i = field.find('=') if i < 0: fkey = field fvalue = "" else: ! fkey = field[:i].strip() ! fvalue = field[i+1:].strip() if fields.has_key(fkey): # Ignore it pass *************** *** 130,136 **** i = i+2 else: i = i+1 ! return string.strip(line[start:i]), i # Part 3: using the database. --- 129,135 ---- i = i+2 else: i = i+1 ! return line[start:i].strip(), i # Part 3: using the database. *************** *** 159,165 **** entries = [] if caps.has_key(MIMEtype): entries = entries + caps[MIMEtype] ! MIMEtypes = string.splitfields(MIMEtype, '/') MIMEtype = MIMEtypes[0] + '/*' if caps.has_key(MIMEtype): entries = entries + caps[MIMEtype] --- 158,164 ---- entries = [] if caps.has_key(MIMEtype): entries = entries + caps[MIMEtype] ! MIMEtypes = MIMEtype.split('/') MIMEtype = MIMEtypes[0] + '/*' if caps.has_key(MIMEtype): entries = entries + caps[MIMEtype] *************** *** 200,209 **** return res def findparam(name, plist): ! name = string.lower(name) + '=' n = len(name) for p in plist: ! if string.lower(p[:n]) == name: return p[n:] return '' --- 199,208 ---- return res def findparam(name, plist): ! name = name.lower() + '=' n = len(name) for p in plist: ! if p[:n].lower() == name: return p[n:] return '' Index: Lib/mhlib.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/mhlib.py,v retrieving revision 1.19 diff -c -r1.19 mhlib.py *** mhlib.py 2000/02/04 15:10:33 1.19 --- mhlib.py 2000/04/11 11:56:45 *************** *** 214,220 **** """Create a new folder (or raise os.error if it cannot be created).""" protect = pickline(self.profile, 'Folder-Protect') if protect and isnumeric(protect): ! mode = string.atoi(protect, 8) else: mode = FOLDER_PROTECT os.mkdir(os.path.join(self.getpath(), name), mode) --- 214,220 ---- """Create a new folder (or raise os.error if it cannot be created).""" protect = pickline(self.profile, 'Folder-Protect') if protect and isnumeric(protect): ! mode = int(protect, 8) else: mode = FOLDER_PROTECT os.mkdir(os.path.join(self.getpath(), name), mode) *************** *** 284,290 **** for name in os.listdir(self.getfullname()): if match(name): append(name) ! messages = map(string.atoi, messages) messages.sort() if messages: self.last = messages[-1] --- 284,290 ---- for name in os.listdir(self.getfullname()): if match(name): append(name) ! messages = map(int, messages) messages.sort() if messages: self.last = messages[-1] *************** *** 303,314 **** while 1: line = f.readline() if not line: break ! fields = string.splitfields(line, ':') if len(fields) <> 2: self.error('bad sequence in %s: %s' % ! (fullname, string.strip(line))) ! key = string.strip(fields[0]) ! value = IntSet(string.strip(fields[1]), ' ').tolist() sequences[key] = value return sequences --- 303,314 ---- while 1: line = f.readline() if not line: break ! fields = line.split(':') if len(fields) <> 2: self.error('bad sequence in %s: %s' % ! (fullname, line.strip())) ! key = fields[0].strip() ! value = IntSet(fields[1].strip(), ' ').tolist() sequences[key] = value return sequences *************** *** 358,364 **** if seq == 'all': return all # Test for X:Y before X-Y because 'seq:-n' matches both ! i = string.find(seq, ':') if i >= 0: head, dir, tail = seq[:i], '', seq[i+1:] if tail[:1] in '-+': --- 358,364 ---- if seq == 'all': return all # Test for X:Y before X-Y because 'seq:-n' matches both ! i = seq.find(':') if i >= 0: head, dir, tail = seq[:i], '', seq[i+1:] if tail[:1] in '-+': *************** *** 366,372 **** if not isnumeric(tail): raise Error, "bad message list %s" % seq try: ! count = string.atoi(tail) except (ValueError, OverflowError): # Can't use sys.maxint because of i+count below count = len(all) --- 366,372 ---- if not isnumeric(tail): raise Error, "bad message list %s" % seq try: ! count = int(tail) except (ValueError, OverflowError): # Can't use sys.maxint because of i+count below count = len(all) *************** *** 396,402 **** i = bisect(all, anchor-1) return all[i:i+count] # Test for X-Y next ! i = string.find(seq, '-') if i >= 0: begin = self._parseindex(seq[:i], all) end = self._parseindex(seq[i+1:], all) --- 396,402 ---- i = bisect(all, anchor-1) return all[i:i+count] # Test for X-Y next ! i = seq.find('-') if i >= 0: begin = self._parseindex(seq[:i], all) end = self._parseindex(seq[i+1:], all) *************** *** 429,435 **** """Internal: parse a message number (or cur, first, etc.).""" if isnumeric(seq): try: ! return string.atoi(seq) except (OverflowError, ValueError): return sys.maxint if seq in ('cur', '.'): --- 429,435 ---- """Internal: parse a message number (or cur, first, etc.).""" if isnumeric(seq): try: ! return int(seq) except (OverflowError, ValueError): return sys.maxint if seq in ('cur', '.'): *************** *** 679,694 **** decide which headers to return (its argument is the header name converted to lower case).""" if not pred: ! return string.joinfields(self.headers, '') headers = [] hit = 0 for line in self.headers: if line[0] not in string.whitespace: ! i = string.find(line, ':') if i > 0: ! hit = pred(string.lower(line[:i])) if hit: headers.append(line) ! return string.joinfields(headers, '') def getbodytext(self, decode = 1): """Return the message's body text as string. This undoes a --- 679,694 ---- decide which headers to return (its argument is the header name converted to lower case).""" if not pred: ! return ''.join(self.headers) headers = [] hit = 0 for line in self.headers: if line[0] not in string.whitespace: ! i = line.find(':') if i > 0: ! hit = pred(line[:i].lower()) if hit: headers.append(line) ! return ''.join(headers) def getbodytext(self, decode = 1): """Return the message's body text as string. This undoes a *************** *** 883,895 **** self.normalize() def fromstring(self, data): - import string new = [] ! for part in string.splitfields(data, self.sep): list = [] ! for subp in string.splitfields(part, self.rng): ! s = string.strip(subp) ! list.append(string.atoi(s)) if len(list) == 1: new.append((list[0], list[0])) elif len(list) == 2 and list[0] <= list[1]: --- 883,894 ---- self.normalize() def fromstring(self, data): new = [] ! for part in data.split(self.sep): list = [] ! for subp in part.split(self.rng): ! s = subp.strip() ! list.append(int(s)) if len(list) == 1: new.append((list[0], list[0])) elif len(list) == 2 and list[0] <= list[1]: *************** *** 919,925 **** if not line or line[0] not in string.whitespace: break text = text + line ! return string.strip(text) return None def updateline(file, key, value, casefold = 1): --- 918,924 ---- if not line or line[0] not in string.whitespace: break text = text + line ! return text.strip() return None def updateline(file, key, value, casefold = 1): *************** *** 994,1000 **** except Error, msg: print "Error:", msg stuff = os.popen("pick %s 2>/dev/null" % `seq`).read() ! list = map(string.atoi, string.split(stuff)) print list, "<-- pick" do('f.listmessages()') --- 993,999 ---- except Error, msg: print "Error:", msg stuff = os.popen("pick %s 2>/dev/null" % `seq`).read() ! list = map(int, stuff.split()) print list, "<-- pick" do('f.listmessages()') Index: Lib/mimetools.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/mimetools.py,v retrieving revision 1.17 diff -c -r1.17 mimetools.py *** mimetools.py 2000/04/04 20:53:07 1.17 --- mimetools.py 2000/04/11 11:56:45 *************** *** 3,9 **** import os import rfc822 - import string import tempfile --- 3,8 ---- *************** *** 25,41 **** if str == None: str = 'text/plain' if ';' in str: ! i = string.index(str, ';') self.plisttext = str[i:] str = str[:i] else: self.plisttext = '' ! fields = string.splitfields(str, '/') for i in range(len(fields)): ! fields[i] = string.lower(string.strip(fields[i])) ! self.type = string.joinfields(fields, '/') self.maintype = fields[0] ! self.subtype = string.joinfields(fields[1:], '/') def parseplist(self): str = self.plisttext --- 24,40 ---- if str == None: str = 'text/plain' if ';' in str: ! i = str.index(';') self.plisttext = str[i:] str = str[:i] else: self.plisttext = '' ! fields = str.split('/') for i in range(len(fields)): ! fields[i] = fields[i].strip().lower() ! self.type = '/'.join(fields) self.maintype = fields[0] ! self.subtype = '/'.join(fields[1:]) def parseplist(self): str = self.plisttext *************** *** 44,65 **** str = str[1:] if ';' in str: # XXX Should parse quotes! ! end = string.index(str, ';') else: end = len(str) f = str[:end] if '=' in f: ! i = string.index(f, '=') ! f = string.lower(string.strip(f[:i])) + \ ! '=' + string.strip(f[i+1:]) ! self.plist.append(string.strip(f)) str = str[end:] def getplist(self): return self.plist def getparam(self, name): ! name = string.lower(name) + '=' n = len(name) for p in self.plist: if p[:n] == name: --- 43,64 ---- str = str[1:] if ';' in str: # XXX Should parse quotes! ! end = str.index(';') else: end = len(str) f = str[:end] if '=' in f: ! i = f.index('=') ! f = f[:i].strip().lower() + \ ! '=' + f[i+1:].strip() ! self.plist.append(f.strip()) str = str[end:] def getplist(self): return self.plist def getparam(self, name): ! name = name.lower() + '=' n = len(name) for p in self.plist: if p[:n] == name: *************** *** 69,83 **** def getparamnames(self): result = [] for p in self.plist: ! i = string.find(p, '=') if i >= 0: ! result.append(string.lower(p[:i])) return result def getencoding(self): if self.encodingheader == None: return '7bit' ! return string.lower(self.encodingheader) def gettype(self): return self.type --- 68,82 ---- def getparamnames(self): result = [] for p in self.plist: ! i = p.find('=') if i >= 0: ! result.append(p[:i].lower()) return result def getencoding(self): if self.encodingheader == None: return '7bit' ! return self.encodingheader.lower() def gettype(self): return self.type Index: Lib/mimetypes.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/mimetypes.py,v retrieving revision 1.11 diff -c -r1.11 mimetypes.py *** mimetypes.py 2000/02/10 17:17:13 1.11 --- mimetypes.py 2000/04/11 11:56:45 *************** *** 23,29 **** """ - import string import posixpath import urllib --- 23,28 ---- *************** *** 62,72 **** # data := *urlchar # parameter := attribute "=" value # type/subtype defaults to "text/plain" ! comma = string.find(url, ',') if comma < 0: # bad data URL return None, None ! semi = string.find(url, ';', 0, comma) if semi >= 0: type = url[:semi] else: --- 61,71 ---- # data := *urlchar # parameter := attribute "=" value # type/subtype defaults to "text/plain" ! comma = url.find(',') if comma < 0: # bad data URL return None, None ! semi = url.find(';', 0, comma) if semi >= 0: type = url[:semi] else: *************** *** 84,91 **** encoding = None if types_map.has_key(ext): return types_map[ext], encoding ! elif types_map.has_key(string.lower(ext)): ! return types_map[string.lower(ext)], encoding else: return None, encoding --- 83,90 ---- encoding = None if types_map.has_key(ext): return types_map[ext], encoding ! elif types_map.has_key(ext.lower()): ! return types_map[ext.lower()], encoding else: return None, encoding *************** *** 101,107 **** global inited if not inited: init() ! type = string.lower(type) for ext, stype in types_map.items(): if type == stype: return ext --- 100,106 ---- global inited if not inited: init() ! type = type.lower() for ext, stype in types_map.items(): if type == stype: return ext *************** *** 125,131 **** while 1: line = f.readline() if not line: break ! words = string.split(line) for i in range(len(words)): if words[i][0] == '#': del words[i:] --- 124,130 ---- while 1: line = f.readline() if not line: break ! words = line.split() for i in range(len(words)): if words[i][0] == '#': del words[i:] Index: Lib/mimify.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/mimify.py,v retrieving revision 1.15 diff -c -r1.15 mimify.py *** mimify.py 2000/02/04 15:39:29 1.15 --- mimify.py 2000/04/11 11:56:45 *************** *** 27,33 **** QUOTE = '> ' # string replies are quoted with # End configure ! import re, string qp = re.compile('^content-transfer-encoding:\\s*quoted-printable', re.I) base64_re = re.compile('^content-transfer-encoding:\\s*base64', re.I) --- 27,33 ---- QUOTE = '> ' # string replies are quoted with # End configure ! import re qp = re.compile('^content-transfer-encoding:\\s*quoted-printable', re.I) base64_re = re.compile('^content-transfer-encoding:\\s*base64', re.I) *************** *** 94,100 **** if res is None: break newline = newline + line[pos:res.start(0)] + \ ! chr(string.atoi(res.group(1), 16)) pos = res.end(0) return newline + line[pos:] --- 94,100 ---- if res is None: break newline = newline + line[pos:res.start(0)] + \ ! chr(int(res.group(1), 16)) pos = res.end(0) return newline + line[pos:] *************** *** 108,114 **** break match = res.group(1) # convert underscores to spaces (before =XX conversion!) ! match = string.join(string.split(match, '_'), ' ') newline = newline + line[pos:res.start(0)] + mime_decode(match) pos = res.end(0) return newline + line[pos:] --- 108,114 ---- break match = res.group(1) # convert underscores to spaces (before =XX conversion!) ! match = match.replace('_', ' ') newline = newline + line[pos:res.start(0)] + mime_decode(match) pos = res.end(0) return newline + line[pos:] *************** *** 230,243 **** pos = 0 if len(line) >= 5 and line[:5] == 'From ': # quote 'From ' at the start of a line for stupid mailers ! newline = string.upper('=%02x' % ord('F')) pos = 1 while 1: res = reg.search(line, pos) if res is None: break newline = newline + line[pos:res.start(0)] + \ ! string.upper('=%02x' % ord(res.group(0))) pos = res.end(0) line = newline + line[pos:] --- 230,243 ---- pos = 0 if len(line) >= 5 and line[:5] == 'From ': # quote 'From ' at the start of a line for stupid mailers ! newline = str('=%02x' % ord('F')).upper() pos = 1 while 1: res = reg.search(line, pos) if res is None: break newline = newline + line[pos:res.start(0)] + \ ! str('=%02x' % ord(res.group(0))).upper() pos = res.end(0) line = newline + line[pos:] *************** *** 344,350 **** if chrset_res: if has_iso_chars: # change us-ascii into iso-8859-1 ! if string.lower(chrset_res.group(2)) == 'us-ascii': line = '%s%s%s' % (chrset_res.group(1), CHARSET, chrset_res.group(3)) --- 344,350 ---- if chrset_res: if has_iso_chars: # change us-ascii into iso-8859-1 ! if chrset_res.group(2).lower() == 'us-ascii': line = '%s%s%s' % (chrset_res.group(1), CHARSET, chrset_res.group(3)) *************** *** 445,451 **** encode = unmimify elif o == '-l': try: ! MAXLEN = string.atoi(a) except: print usage sys.exit(1) --- 445,451 ---- encode = unmimify elif o == '-l': try: ! MAXLEN = int(a) except: print usage sys.exit(1) Index: Lib/multifile.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/multifile.py,v retrieving revision 1.9 diff -c -r1.9 multifile.py *** multifile.py 2000/02/04 15:10:33 1.9 --- multifile.py 2000/04/11 11:56:46 *************** *** 118,124 **** return list def read(self): # Note: no size argument -- read until EOF only! ! return string.joinfields(self.readlines(), '') def next(self): while self.readline(): pass --- 118,124 ---- return list def read(self): # Note: no size argument -- read until EOF only! ! return ''.join(self.readlines()) def next(self): while self.readline(): pass Index: Lib/nntplib.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/nntplib.py,v retrieving revision 1.19 diff -c -r1.19 nntplib.py *** nntplib.py 2000/03/28 21:45:46 1.19 --- nntplib.py 2000/04/11 11:56:46 *************** *** 31,37 **** # Imports import re import socket - import string --- 31,36 ---- *************** *** 244,250 **** resp, list = self.longcmd('LIST') for i in range(len(list)): # Parse lines into "group last first flag" ! list[i] = tuple(string.split(list[i])) return resp, list def group(self, name): --- 243,249 ---- resp, list = self.longcmd('LIST') for i in range(len(list)): # Parse lines into "group last first flag" ! list[i] = tuple(list[i].split()) return resp, list def group(self, name): *************** *** 260,266 **** resp = self.shortcmd('GROUP ' + name) if resp[:3] <> '211': raise NNTPReplyError(resp) ! words = string.split(resp) count = first = last = 0 n = len(words) if n > 1: --- 259,265 ---- resp = self.shortcmd('GROUP ' + name) if resp[:3] <> '211': raise NNTPReplyError(resp) ! words = resp.split() count = first = last = 0 n = len(words) if n > 1: *************** *** 270,276 **** if n > 3: last = words[3] if n > 4: ! name = string.lower(words[4]) return resp, count, first, last, name def help(self): --- 269,275 ---- if n > 3: last = words[3] if n > 4: ! name = words[4].lower() return resp, count, first, last, name def help(self): *************** *** 284,290 **** """Internal: parse the response of a STAT, NEXT or LAST command.""" if resp[:2] <> '22': raise NNTPReplyError(resp) ! words = string.split(resp) nr = 0 id = '' n = len(words) --- 283,289 ---- """Internal: parse the response of a STAT, NEXT or LAST command.""" if resp[:2] <> '22': raise NNTPReplyError(resp) ! words = resp.split() nr = 0 id = '' n = len(words) *************** *** 391,404 **** resp, lines = self.longcmd('XOVER ' + start + '-' + end) xover_lines = [] for line in lines: ! elem = string.splitfields(line,"\t") try: xover_lines.append((elem[0], elem[1], elem[2], elem[3], elem[4], ! string.split(elem[5]), elem[6], elem[7])) except IndexError: --- 390,403 ---- resp, lines = self.longcmd('XOVER ' + start + '-' + end) xover_lines = [] for line in lines: ! elem = line.split("\t") try: xover_lines.append((elem[0], elem[1], elem[2], elem[3], elem[4], ! elem[5].split(), elem[6], elem[7])) except IndexError: *************** *** 416,422 **** resp, raw_lines = self.longcmd('XGTITLE ' + group) lines = [] for raw_line in raw_lines: ! match = line_pat.search(string.strip(raw_line)) if match: lines.append(match.group(1, 2)) return resp, lines --- 415,421 ---- resp, raw_lines = self.longcmd('XGTITLE ' + group) lines = [] for raw_line in raw_lines: ! match = line_pat.search(raw_line.strip()) if match: lines.append(match.group(1, 2)) return resp, lines *************** *** 432,438 **** if resp[:3] <> '223': raise NNTPReplyError(resp) try: ! [resp_num, path] = string.split(resp) except ValueError: raise NNTPReplyError(resp) else: --- 431,437 ---- if resp[:3] <> '223': raise NNTPReplyError(resp) try: ! [resp_num, path] = resp.split() except ValueError: raise NNTPReplyError(resp) else: *************** *** 449,455 **** resp = self.shortcmd("DATE") if resp[:3] <> '111': raise NNTPReplyError(resp) ! elem = string.split(resp) if len(elem) != 2: raise NNTPDataError(resp) date = elem[1][2:8] --- 448,454 ---- resp = self.shortcmd("DATE") if resp[:3] <> '111': raise NNTPReplyError(resp) ! elem = resp.split() if len(elem) != 2: raise NNTPDataError(resp) date = elem[1][2:8] Index: Lib/ntpath.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/ntpath.py,v retrieving revision 1.23 diff -c -r1.23 ntpath.py *** ntpath.py 2000/02/17 17:30:40 1.23 --- ntpath.py 2000/04/11 11:56:46 *************** *** 18,24 **** """Normalize case of pathname. Makes all characters lowercase and all slashes into backslashes.""" ! return string.lower(string.replace(s, "/", "\\")) # Return whether a path is absolute. --- 18,24 ---- """Normalize case of pathname. Makes all characters lowercase and all slashes into backslashes.""" ! return s.replace("/", "\\").lower() # Return whether a path is absolute. *************** *** 77,87 **** # \\machine\mountpoint\directories... # directory ^^^^^^^^^^^^^^^ normp = normcase(p) ! index = string.find(normp, '\\', 2) if index == -1: ##raise RuntimeError, 'illegal UNC path: "' + p + '"' return ("", p) ! index = string.find(normp, '\\', index + 1) if index == -1: index = len(p) return p[:index], p[index:] --- 77,87 ---- # \\machine\mountpoint\directories... # directory ^^^^^^^^^^^^^^^ normp = normcase(p) ! index = normp.find('\\', 2) if index == -1: ##raise RuntimeError, 'illegal UNC path: "' + p + '"' return ("", p) ! index = normp.find('\\', index + 1) if index == -1: index = len(p) return p[:index], p[index:] *************** *** 331,339 **** path = path[index + 1:] pathlen = len(path) try: ! index = string.index(path, '\'') res = res + '\'' + path[:index + 1] ! except string.index_error: res = res + path index = pathlen -1 elif c == '$': # variable or '$$' --- 331,339 ---- path = path[index + 1:] pathlen = len(path) try: ! index = path.index('\'') res = res + '\'' + path[:index + 1] ! except ValueError: res = res + path index = pathlen -1 elif c == '$': # variable or '$$' *************** *** 344,354 **** path = path[index+2:] pathlen = len(path) try: ! index = string.index(path, '}') var = path[:index] if os.environ.has_key(var): res = res + os.environ[var] ! except string.index_error: res = res + path index = pathlen - 1 else: --- 344,354 ---- path = path[index+2:] pathlen = len(path) try: ! index = path.index('}') var = path[:index] if os.environ.has_key(var): res = res + os.environ[var] ! except ValueError: res = res + path index = pathlen - 1 else: *************** *** 375,386 **** def normpath(path): """Normalize path, eliminating double slashes, etc.""" ! path = string.replace(path, "/", "\\") prefix, path = splitdrive(path) while path[:1] == os.sep: prefix = prefix + os.sep path = path[1:] ! comps = string.splitfields(path, os.sep) i = 0 while i < len(comps): if comps[i] == '.': --- 375,386 ---- def normpath(path): """Normalize path, eliminating double slashes, etc.""" ! path = path.replace("/", "\\") prefix, path = splitdrive(path) while path[:1] == os.sep: prefix = prefix + os.sep path = path[1:] ! comps = path.split(os.sep) i = 0 while i < len(comps): if comps[i] == '.': *************** *** 395,401 **** # If the path is now empty, substitute '.' if not prefix and not comps: comps.append('.') ! return prefix + string.joinfields(comps, os.sep) # Return an absolute path. --- 395,401 ---- # If the path is now empty, substitute '.' if not prefix and not comps: comps.append('.') ! return prefix + os.sep.join(comps) # Return an absolute path. Index: Lib/nturl2path.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/nturl2path.py,v retrieving revision 1.5 diff -c -r1.5 nturl2path.py *** nturl2path.py 2000/02/04 15:10:33 1.5 --- nturl2path.py 2000/04/11 11:56:46 *************** *** 16,30 **** # convert this to \\host\path\on\remote\host # (notice halving of slashes at the start of the path) url = url[2:] ! components = string.split(url, '/') # make sure not to convert quoted slashes :-) ! return urllib.unquote(string.join(components, '\\')) ! comp = string.split(url, '|') if len(comp) != 2 or comp[0][-1] not in string.letters: error = 'Bad URL: ' + url raise IOError, error ! drive = string.upper(comp[0][-1]) ! components = string.split(comp[1], '/') path = drive + ':' for comp in components: if comp: --- 16,30 ---- # convert this to \\host\path\on\remote\host # (notice halving of slashes at the start of the path) url = url[2:] ! components = url.split('/') # make sure not to convert quoted slashes :-) ! return urllib.unquote('\\'.join(components)) ! comp = url.split('|') if len(comp) != 2 or comp[0][-1] not in string.letters: error = 'Bad URL: ' + url raise IOError, error ! drive = comp[0][-1].upper() ! components = comp[1].split('/') path = drive + ':' for comp in components: if comp: *************** *** 40,46 **** ///C|/foo/bar/spam.foo """ ! import string, urllib if not ':' in p: # No drive specifier, just convert slashes and quote the name if p[:2] == '\\\\': --- 40,46 ---- ///C|/foo/bar/spam.foo """ ! import urllib if not ':' in p: # No drive specifier, just convert slashes and quote the name if p[:2] == '\\\\': *************** *** 48,62 **** # convert this to ////host/path/on/remote/host # (notice doubling of slashes at the start of the path) p = '\\\\' + p ! components = string.split(p, '\\') ! return urllib.quote(string.join(components, '/')) ! comp = string.split(p, ':') if len(comp) != 2 or len(comp[0]) > 1: error = 'Bad path: ' + p raise IOError, error ! drive = urllib.quote(string.upper(comp[0])) ! components = string.split(comp[1], '\\') path = '///' + drive + '|' for comp in components: if comp: --- 48,62 ---- # convert this to ////host/path/on/remote/host # (notice doubling of slashes at the start of the path) p = '\\\\' + p ! components = p.split('\\') ! return urllib.quote('/'.join(components)) ! comp = p.split(':') if len(comp) != 2 or len(comp[0]) > 1: error = 'Bad path: ' + p raise IOError, error ! drive = urllib.quote(comp[0].upper()) ! components = comp[1].split('\\') path = '///' + drive + '|' for comp in components: if comp: Index: Lib/pdb.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/pdb.py,v retrieving revision 1.43 diff -c -r1.43 pdb.py *** pdb.py 2000/03/06 20:39:59 1.43 --- pdb.py 2000/04/11 11:56:47 *************** *** 4,10 **** # (See pdb.doc for documentation.) - import string import sys import linecache import cmd --- 4,9 ---- *************** *** 151,176 **** """Handle alias expansion and ';;' separator.""" if not line: return line ! args = string.split(line) while self.aliases.has_key(args[0]): line = self.aliases[args[0]] ii = 1 for tmpArg in args[1:]: ! line = string.replace(line, "%" + str(ii), ! tmpArg) ii = ii + 1 ! line = string.replace(line, "%*", ! string.join(args[1:], ' ')) ! args = string.split(line) # split into ';;' separated commands # unless it's an alias command if args[0] != 'alias': ! marker = string.find(line, ';;') if marker >= 0: # queue up everything after marker ! next = string.lstrip(line[marker+2:]) self.cmdqueue.append(next) ! line = string.rstrip(line[:marker]) return line # Command definitions, called by cmdloop() --- 150,173 ---- """Handle alias expansion and ';;' separator.""" if not line: return line ! args = line.split() while self.aliases.has_key(args[0]): line = self.aliases[args[0]] ii = 1 for tmpArg in args[1:]: ! line = line.replace("%" + str(ii), tmpArg) ii = ii + 1 ! line = line.replace("%*", ' '.join(args[1:])) ! args = line.split() # split into ';;' separated commands # unless it's an alias command if args[0] != 'alias': ! marker = line.find(';;') if marker >= 0: # queue up everything after marker ! next = line[marker+2:].lstrip() self.cmdqueue.append(next) ! line = line[:marker].rstrip() return line # Command definitions, called by cmdloop() *************** *** 196,210 **** filename = None lineno = None cond = None ! comma = string.find(arg, ',') if comma > 0: # parse stuff after comma: "condition" ! cond = string.lstrip(arg[comma+1:]) ! arg = string.rstrip(arg[:comma]) # parse stuff before comma: [filename:]lineno | function ! colon = string.rfind(arg, ':') if colon >= 0: ! filename = string.rstrip(arg[:colon]) f = self.lookupmodule(filename) if not f: print '*** ', `filename`, --- 193,207 ---- filename = None lineno = None cond = None ! comma = arg.find(',') if comma > 0: # parse stuff after comma: "condition" ! cond = arg[comma+1:].lstrip() ! arg = arg[:comma].rstrip() # parse stuff before comma: [filename:]lineno | function ! colon = arg.rfind(':') if colon >= 0: ! filename = arg[:colon].rstrip() f = self.lookupmodule(filename) if not f: print '*** ', `filename`, *************** *** 212,218 **** return else: filename = f ! arg = string.lstrip(arg[colon+1:]) try: lineno = int(arg) except ValueError, msg: --- 209,215 ---- return else: filename = f ! arg = arg[colon+1:].lstrip() try: lineno = int(arg) except ValueError, msg: *************** *** 276,292 **** def lineinfo(self, identifier): failed = (None, None, None) # Input is identifier, may be in single quotes ! idstring = string.split(identifier, "'") if len(idstring) == 1: # not in single quotes ! id = string.strip(idstring[0]) elif len(idstring) == 3: # quoted ! id = string.strip(idstring[1]) else: return failed if id == '': return failed ! parts = string.split(id, '.') # Protection for derived debuggers if parts[0] == 'self': del parts[0] --- 273,289 ---- def lineinfo(self, identifier): failed = (None, None, None) # Input is identifier, may be in single quotes ! idstring = identifier.split("'") if len(idstring) == 1: # not in single quotes ! id = idstring[0].strip() elif len(idstring) == 3: # quoted ! id = idstring[1].strip() else: return failed if id == '': return failed ! parts = id.split('.') # Protection for derived debuggers if parts[0] == 'self': del parts[0] *************** *** 318,324 **** if not line: print 'End of file' return 0 ! line = string.strip(line) # Don't allow setting breakpoint at a blank line if ( not line or (line[0] == '#') or (line[:3] == '"""') or line[:3] == "'''" ): --- 315,321 ---- if not line: print 'End of file' return 0 ! line = line.strip() # Don't allow setting breakpoint at a blank line if ( not line or (line[0] == '#') or (line[:3] == '"""') or line[:3] == "'''" ): *************** *** 354,374 **** if not line: print 'end of file' return 0 ! line = string.strip(line) if not line: continue # Blank line if brackets <= 0 and line[0] not in ('#','"',"'"): break return lineno def do_enable(self, arg): ! args = string.split(arg) for i in args: bp = bdb.Breakpoint.bpbynumber[int(i)] if bp: bp.enable() def do_disable(self, arg): ! args = string.split(arg) for i in args: bp = bdb.Breakpoint.bpbynumber[int(i)] if bp: --- 351,371 ---- if not line: print 'end of file' return 0 ! line = line.strip() if not line: continue # Blank line if brackets <= 0 and line[0] not in ('#','"',"'"): break return lineno def do_enable(self, arg): ! args = arg.split() for i in args: bp = bdb.Breakpoint.bpbynumber[int(i)] if bp: bp.enable() def do_disable(self, arg): ! args = arg.split() for i in args: bp = bdb.Breakpoint.bpbynumber[int(i)] if bp: *************** *** 376,383 **** def do_condition(self, arg): # arg is breakpoint number and condition ! args = string.split(arg, ' ', 1) ! bpnum = int(string.strip(args[0])) try: cond = args[1] except: --- 373,380 ---- def do_condition(self, arg): # arg is breakpoint number and condition ! args = arg.split(' ', 1) ! bpnum = int(args[0].strip()) try: cond = args[1] except: *************** *** 391,400 **** def do_ignore(self,arg): """arg is bp number followed by ignore count.""" ! args = string.split(arg) ! bpnum = int(string.strip(args[0])) try: ! count = int(string.strip(args[1])) except: count = 0 bp = bdb.Breakpoint.bpbynumber[bpnum] --- 388,397 ---- def do_ignore(self,arg): """arg is bp number followed by ignore count.""" ! args = arg.split() ! bpnum = int(args[0].strip()) try: ! count = int(args[1].strip()) except: count = 0 bp = bdb.Breakpoint.bpbynumber[bpnum] *************** *** 421,433 **** reply = raw_input('Clear all breaks? ') except EOFError: reply = 'no' ! reply = string.lower(string.strip(reply)) if reply in ('y', 'yes'): self.clear_all_breaks() return if ':' in arg: # Make sure it works for "clear C:\foo\bar.py:12" ! i = string.rfind(arg, ':') filename = arg[:i] arg = arg[i+1:] try: --- 418,430 ---- reply = raw_input('Clear all breaks? ') except EOFError: reply = 'no' ! reply = reply.strip().lower() if reply in ('y', 'yes'): self.clear_all_breaks() return if ':' in arg: # Make sure it works for "clear C:\foo\bar.py:12" ! i = arg.rfind(':') filename = arg[:i] arg = arg[i+1:] try: *************** *** 438,444 **** err = self.clear_break(filename, lineno) if err: print '***', err return ! numberlist = string.split(arg) for i in numberlist: err = self.clear_bpbynumber(i) if err: --- 435,441 ---- err = self.clear_break(filename, lineno) if err: print '***', err return ! numberlist = arg.split() for i in numberlist: err = self.clear_bpbynumber(i) if err: *************** *** 564,570 **** print '[EOF]' break else: ! s = string.rjust(`lineno`, 3) if len(s) < 4: s = s + ' ' if lineno in breaklist: s = s + 'B' else: s = s + ' ' --- 561,567 ---- print '[EOF]' break else: ! s = `lineno`.rjust(3) if len(s) < 4: s = s + ' ' if lineno in breaklist: s = s + 'B' else: s = s + ' ' *************** *** 604,610 **** print type(value) def do_alias(self, arg): ! args = string.split (arg) if len(args) == 0: keys = self.aliases.keys() keys.sort() --- 601,607 ---- print type(value) def do_alias(self, arg): ! args = arg.split () if len(args) == 0: keys = self.aliases.keys() keys.sort() *************** *** 614,623 **** if self.aliases.has_key(args[0]) and len (args) == 1: print "%s = %s" % (args[0], self.aliases[args[0]]) else: ! self.aliases[args[0]] = string.join(args[1:], ' ') def do_unalias(self, arg): ! args = string.split (arg) if len(args) == 0: return if self.aliases.has_key(args[0]): del self.aliases[args[0]] --- 611,620 ---- if self.aliases.has_key(args[0]) and len (args) == 1: print "%s = %s" % (args[0], self.aliases[args[0]]) else: ! self.aliases[args[0]] = ' '.join(args[1:]) def do_unalias(self, arg): ! args = arg.split () if len(args) == 0: return if self.aliases.has_key(args[0]): del self.aliases[args[0]] Index: Lib/pickle.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/pickle.py,v retrieving revision 1.37 diff -c -r1.37 pickle.py *** pickle.py 2000/03/10 23:20:09 1.37 --- pickle.py 2000/04/11 11:56:48 *************** *** 27,33 **** from types import * from copy_reg import dispatch_table, safe_constructors - import string import marshal import sys import struct --- 27,32 ---- *************** *** 548,554 **** dispatch[NONE] = load_none def load_int(self): ! self.append(string.atoi(self.readline()[:-1])) dispatch[INT] = load_int def load_binint(self): --- 547,553 ---- dispatch[NONE] = load_none def load_int(self): ! self.append(int(self.readline()[:-1])) dispatch[INT] = load_int def load_binint(self): *************** *** 564,574 **** dispatch[BININT2] = load_binint2 def load_long(self): ! self.append(string.atol(self.readline()[:-1], 0)) dispatch[LONG] = load_long def load_float(self): ! self.append(string.atof(self.readline()[:-1])) dispatch[FLOAT] = load_float def load_binfloat(self, unpack=struct.unpack): --- 563,573 ---- dispatch[BININT2] = load_binint2 def load_long(self): ! self.append(long(self.readline()[:-1], 0)) dispatch[LONG] = load_long def load_float(self): ! self.append(float(self.readline()[:-1])) dispatch[FLOAT] = load_float def load_binfloat(self, unpack=struct.unpack): Index: Lib/popen2.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/popen2.py,v retrieving revision 1.9 diff -c -r1.9 popen2.py *** popen2.py 2000/02/04 15:10:34 1.9 --- popen2.py 2000/04/11 11:56:48 *************** *** 8,14 **** import os import sys - import string MAXFD = 256 # Max number of file descriptors (os.getdtablesize()???) --- 8,13 ---- Index: Lib/poplib.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/poplib.py,v retrieving revision 1.8 diff -c -r1.8 poplib.py *** poplib.py 2000/03/28 21:45:46 1.8 --- poplib.py 2000/04/11 11:56:48 *************** *** 15,21 **** # Imports ! import regex, socket, string # Exception raised when an error or invalid response is received: --- 15,21 ---- # Imports ! import regex, socket # Exception raised when an error or invalid response is received: *************** *** 189,198 **** Result is tuple of 2 ints (message count, mailbox size) """ retval = self._shortcmd('STAT') ! rets = string.split(retval) #if self._debugging: print '*stat*', `rets` ! numMessages = string.atoi(rets[1]) ! sizeMessages = string.atoi(rets[2]) return (numMessages, sizeMessages) --- 189,198 ---- Result is tuple of 2 ints (message count, mailbox size) """ retval = self._shortcmd('STAT') ! rets = retval.split() #if self._debugging: print '*stat*', `rets` ! numMessages = int(rets[1]) ! sizeMessages = int(rets[2]) return (numMessages, sizeMessages) *************** *** 277,283 **** raise error_proto('-ERR APOP not supported by server') import md5 digest = md5.new(self.timestamp.group(1)+secret).digest() ! digest = string.join(map(lambda x:'%02x'%ord(x), digest), '') return self._shortcmd('APOP %s %s' % (user, digest)) --- 277,283 ---- raise error_proto('-ERR APOP not supported by server') import md5 digest = md5.new(self.timestamp.group(1)+secret).digest() ! digest = ''.join(map(lambda x:'%02x'%ord(x), digest)) return self._shortcmd('APOP %s %s' % (user, digest)) Index: Lib/posixpath.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/posixpath.py,v retrieving revision 1.30 diff -c -r1.30 posixpath.py *** posixpath.py 2000/02/29 13:31:16 1.30 --- posixpath.py 2000/04/11 11:56:48 *************** *** 57,64 **** def split(p): """Split a pathname. Returns tuple "(head, tail)" where "tail" is everything after the final slash. Either part may be empty""" ! import string ! i = string.rfind(p, '/') + 1 head, tail = p[:i], p[i:] if head and head <> '/'*len(head): while head[-1] == '/': --- 57,63 ---- def split(p): """Split a pathname. Returns tuple "(head, tail)" where "tail" is everything after the final slash. Either part may be empty""" ! i = p.rfind('/') + 1 head, tail = p[:i], p[i:] if head and head <> '/'*len(head): while head[-1] == '/': *************** *** 342,354 **** def normpath(path): """Normalize path, eliminating double slashes, etc.""" - import string # Treat initial slashes specially slashes = '' while path[:1] == '/': slashes = slashes + '/' path = path[1:] ! comps = string.splitfields(path, '/') i = 0 while i < len(comps): if comps[i] == '.': --- 341,352 ---- def normpath(path): """Normalize path, eliminating double slashes, etc.""" # Treat initial slashes specially slashes = '' while path[:1] == '/': slashes = slashes + '/' path = path[1:] ! comps = path.split('/') i = 0 while i < len(comps): if comps[i] == '.': *************** *** 365,371 **** # If the path is now empty, substitute '.' if not comps and not slashes: comps.append('.') ! return slashes + string.joinfields(comps, '/') def abspath(path): --- 363,369 ---- # If the path is now empty, substitute '.' if not comps and not slashes: comps.append('.') ! return slashes + '/'.join(comps) def abspath(path): Index: Lib/pstats.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/pstats.py,v retrieving revision 1.7 diff -c -r1.7 pstats.py *** pstats.py 2000/02/04 15:10:34 1.7 --- pstats.py 2000/04/11 11:56:49 *************** *** 34,40 **** import os import time - import string import marshal import re --- 34,39 ---- *************** *** 392,402 **** return self def print_call_heading(self, name_size, column_title): ! print string.ljust("Function ", name_size) + column_title def print_call_line(self, name_size, source, call_dict): ! print string.ljust(func_std_string(source), name_size), if not call_dict: print "--" return --- 391,401 ---- return self def print_call_heading(self, name_size, column_title): ! print "Function ".ljust(name_size) + column_title def print_call_line(self, name_size, source, call_dict): ! print func_std_string(source).ljust(name_size), if not call_dict: print "--" return *************** *** 414,424 **** def print_title(self): ! print string.rjust('ncalls', 9), ! print string.rjust('tottime', 8), ! print string.rjust('percall', 8), ! print string.rjust('cumtime', 8), ! print string.rjust('percall', 8), print 'filename:lineno(function)' --- 413,423 ---- def print_title(self): ! print 'ncalls'.rjust(9), ! print 'tottime'.rjust(8), ! print 'percall'.rjust(8), ! print 'cumtime'.rjust(8), ! print 'percall'.rjust(8), print 'filename:lineno(function)' *************** *** 427,433 **** c = `nc` if nc != cc: c = c + '/' + `cc` ! print string.rjust(c, 9), print f8(tt), if nc == 0: print ' '*8, --- 426,432 ---- c = `nc` if nc != cc: c = c + '/' + `cc` ! print c.rjust(9), print f8(tt), if nc == 0: print ' '*8, *************** *** 522,526 **** #************************************************************************** def f8(x): ! return string.rjust(fpformat.fix(x, 3), 8) --- 521,525 ---- #************************************************************************** def f8(x): ! return fpformat.fix(x, 3).rjust(8) Index: Lib/py_compile.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/py_compile.py,v retrieving revision 1.15 diff -c -r1.15 py_compile.py *** py_compile.py 2000/02/04 15:10:34 1.15 --- py_compile.py 2000/04/11 11:56:49 *************** *** 54,63 **** try: codeobject = __builtin__.compile(codestring, dfile or file, 'exec') except SyntaxError, detail: ! import traceback, sys, string lines = traceback.format_exception_only(SyntaxError, detail) for line in lines: ! sys.stderr.write(string.replace(line, 'File ""', 'File "%s"' % (dfile or file))) return if not cfile: --- 54,63 ---- try: codeobject = __builtin__.compile(codestring, dfile or file, 'exec') except SyntaxError, detail: ! import traceback, sys lines = traceback.format_exception_only(SyntaxError, detail) for line in lines: ! sys.stderr.write(line.replace('File ""', 'File "%s"' % (dfile or file))) return if not cfile: Index: Lib/pyclbr.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/pyclbr.py,v retrieving revision 1.15 diff -c -r1.15 pyclbr.py *** pyclbr.py 2000/02/04 15:39:30 1.15 --- pyclbr.py 2000/04/11 11:56:49 *************** *** 57,63 **** import sys import imp import re - import string TABWIDTH = 8 --- 57,62 ---- *************** *** 160,170 **** dict = {} ! i = string.rfind(module, '.') if i >= 0: # Dotted module name ! package = string.strip(module[:i]) ! submodule = string.strip(module[i+1:]) parent = readmodule(package, path, inpackage) child = readmodule(submodule, parent['__path__'], 1) return child --- 159,169 ---- dict = {} ! i = module.rfind('.') if i >= 0: # Dotted module name ! package = module[:i].strip() ! submodule = module[i+1:].strip() parent = readmodule(package, path, inpackage) child = readmodule(submodule, parent['__path__'], 1) return child *************** *** 210,218 **** # when we need a line number we simply string.count the number of # newlines in the string since the last time we did this; i.e., # lineno = lineno + \ ! # string.count(src, '\n', last_lineno_pos, here) # last_lineno_pos = here - countnl = string.count lineno, last_lineno_pos = 1, 0 i = 0 while 1: --- 209,216 ---- # when we need a line number we simply string.count the number of # newlines in the string since the last time we did this; i.e., # lineno = lineno + \ ! # src.count('\n', last_lineno_pos, here) # last_lineno_pos = here lineno, last_lineno_pos = 1, 0 i = 0 while 1: *************** *** 226,233 **** thisindent = _indent(m.group("MethodIndent")) meth_name = m.group("MethodName") lineno = lineno + \ ! countnl(src, '\n', ! last_lineno_pos, start) last_lineno_pos = start # close all classes indented at least as much while classstack and \ --- 224,230 ---- thisindent = _indent(m.group("MethodIndent")) meth_name = m.group("MethodName") lineno = lineno + \ ! src.count('\n', last_lineno_pos, start) last_lineno_pos = start # close all classes indented at least as much while classstack and \ *************** *** 254,274 **** classstack[-1][1] >= thisindent: del classstack[-1] lineno = lineno + \ ! countnl(src, '\n', last_lineno_pos, start) last_lineno_pos = start class_name = m.group("ClassName") inherit = m.group("ClassSupers") if inherit: # the class inherits from other classes ! inherit = string.strip(inherit[1:-1]) names = [] ! for n in string.splitfields(inherit, ','): ! n = string.strip(n) if dict.has_key(n): # we know this super class n = dict[n] else: ! c = string.splitfields(n, '.') if len(c) > 1: # super class # is of the --- 251,271 ---- classstack[-1][1] >= thisindent: del classstack[-1] lineno = lineno + \ ! src.count('\n', last_lineno_pos, start) last_lineno_pos = start class_name = m.group("ClassName") inherit = m.group("ClassSupers") if inherit: # the class inherits from other classes ! inherit = inherit[1:-1].strip() names = [] ! for n in inherit.split(','): ! n = n.strip() if dict.has_key(n): # we know this super class n = dict[n] else: ! c = n.split('.') if len(c) > 1: # super class # is of the *************** *** 291,298 **** elif m.start("Import") >= 0: # import module ! for n in string.split(m.group("ImportList"), ','): ! n = string.strip(n) try: # recursively read the imported module d = readmodule(n, path, inpackage) --- 288,295 ---- elif m.start("Import") >= 0: # import module ! for n in m.group("ImportList").split(','): ! n = n.strip() try: # recursively read the imported module d = readmodule(n, path, inpackage) *************** *** 303,309 **** elif m.start("ImportFrom") >= 0: # from module import stuff mod = m.group("ImportFromPath") ! names = string.split(m.group("ImportFromList"), ',') try: # recursively read the imported module d = readmodule(mod, path, inpackage) --- 300,306 ---- elif m.start("ImportFrom") >= 0: # from module import stuff mod = m.group("ImportFromPath") ! names = m.group("ImportFromList").split(',') try: # recursively read the imported module d = readmodule(mod, path, inpackage) *************** *** 314,320 **** # imported module to our name space if they # were mentioned in the list for n in names: ! n = string.strip(n) if d.has_key(n): dict[n] = d[n] elif n == '*': --- 311,317 ---- # imported module to our name space if they # were mentioned in the list for n in names: ! n = n.strip() if d.has_key(n): dict[n] = d[n] elif n == '*': *************** *** 332,336 **** return dict ! def _indent(ws, _expandtabs=string.expandtabs): ! return len(_expandtabs(ws, TABWIDTH)) --- 329,333 ---- return dict ! def _indent(ws): ! return len(ws.expandtabs(TABWIDTH)) Index: Lib/re.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/re.py,v retrieving revision 1.35 diff -c -r1.35 re.py *** re.py 1999/11/15 14:19:15 1.35 --- re.py 2000/04/11 11:56:49 *************** *** 229,235 **** if char not in alphanum: if char=='\000': result[i] = '\\000' else: result[i] = '\\'+char ! return string.join(result, '') def compile(pattern, flags=0): """compile(pattern[, flags]) -> RegexObject --- 229,235 ---- if char not in alphanum: if char=='\000': result[i] = '\\000' else: result[i] = '\\'+char ! return ''.join(result) def compile(pattern, flags=0): """compile(pattern[, flags]) -> RegexObject *************** *** 398,404 **** append(source[lastmatch:pos]) n = n + 1 append(source[pos:]) ! return (string.join(results, ''), n) def split(self, source, maxsplit=0): """split(source[, maxsplit=0]) -> list of strings --- 398,404 ---- append(source[lastmatch:pos]) n = n + 1 append(source[pos:]) ! return (''.join(results), n) def split(self, source, maxsplit=0): """split(source[, maxsplit=0]) -> list of strings Index: Lib/regsub.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/regsub.py,v retrieving revision 1.7 diff -c -r1.7 regsub.py *** regsub.py 2000/02/04 15:28:40 1.7 --- regsub.py 2000/04/11 11:56:49 *************** *** 100,110 **** # Capitalize words split using a pattern def capwords(str, pat='[^a-zA-Z0-9_]+'): - import string words = splitx(str, pat) for i in range(0, len(words), 2): ! words[i] = string.capitalize(words[i]) ! return string.joinfields(words, "") # Internal subroutines: --- 100,109 ---- # Capitalize words split using a pattern def capwords(str, pat='[^a-zA-Z0-9_]+'): words = splitx(str, pat) for i in range(0, len(words), 2): ! words[i] = words[i].capitalize() ! return "".join(words) # Internal subroutines: Index: Lib/repr.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/repr.py,v retrieving revision 1.6 diff -c -r1.6 repr.py *** repr.py 2000/02/04 15:28:40 1.6 --- repr.py 2000/04/11 11:56:50 *************** *** 1,7 **** """Redo the `...` (representation) but with limits on most sizes.""" - import string - class Repr: def __init__(self): self.maxlevel = 6 --- 1,5 ---- *************** *** 16,23 **** def repr1(self, x, level): typename = `type(x)`[7:-2] # "" if ' ' in typename: ! parts = string.split(typename) ! typename = string.joinfields(parts, '_') if hasattr(self, 'repr_' + typename): return getattr(self, 'repr_' + typename)(x, level) else: --- 14,21 ---- def repr1(self, x, level): typename = `type(x)`[7:-2] # "" if ' ' in typename: ! parts = typename.split() ! typename = '_'.join(parts) if hasattr(self, 'repr_' + typename): return getattr(self, 'repr_' + typename)(x, level) else: Index: Lib/rfc822.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/rfc822.py,v retrieving revision 1.46 diff -c -r1.46 rfc822.py *** rfc822.py 2000/02/10 17:17:14 1.46 --- rfc822.py 2000/04/11 11:56:50 *************** *** 145,152 **** if headerseen and line[0] in ' \t': # It's a continuation line. list.append(line) ! x = (self.dict[headerseen] + "\n " + string.strip(line)) ! self.dict[headerseen] = string.strip(x) continue elif self.iscomment(line): # It's a comment. Ignore it. --- 145,152 ---- if headerseen and line[0] in ' \t': # It's a continuation line. list.append(line) ! x = (self.dict[headerseen] + "\n " + line.strip()) ! self.dict[headerseen] = x.strip() continue elif self.iscomment(line): # It's a comment. Ignore it. *************** *** 158,164 **** if headerseen: # It's a legal header line, save it. list.append(line) ! self.dict[headerseen] = string.strip(line[len(headerseen)+1:]) continue else: # It's not a header line; throw it back and stop here. --- 158,164 ---- if headerseen: # It's a legal header line, save it. list.append(line) ! self.dict[headerseen] = line[len(headerseen)+1:].strip() continue else: # It's not a header line; throw it back and stop here. *************** *** 182,190 **** You may override this method in order to use Message parsing on tagged data in RFC822-like formats with special header formats. """ ! i = string.find(line, ':') if i > 0: ! return string.lower(line[:i]) else: return None --- 182,190 ---- You may override this method in order to use Message parsing on tagged data in RFC822-like formats with special header formats. """ ! i = line.find(':') if i > 0: ! return line[:i].lower() else: return None *************** *** 219,230 **** times, all occurrences are returned. Case is not important in the header name. """ ! name = string.lower(name) + ':' n = len(name) list = [] hit = 0 for line in self.headers: ! if string.lower(line[:n]) == name: hit = 1 elif line[:1] not in string.whitespace: hit = 0 --- 219,230 ---- times, all occurrences are returned. Case is not important in the header name. """ ! name = name.lower() + ':' n = len(name) list = [] hit = 0 for line in self.headers: ! if line[:n].lower() == name: hit = 1 elif line[:1] not in string.whitespace: hit = 0 *************** *** 239,245 **** only the first matching header (and its continuation lines). """ ! name = string.lower(name) + ':' n = len(name) list = [] hit = 0 --- 239,245 ---- only the first matching header (and its continuation lines). """ ! name = name.lower() + ':' n = len(name) list = [] hit = 0 *************** *** 247,253 **** if hit: if line[:1] not in string.whitespace: break ! elif string.lower(line[:n]) == name: hit = 1 if hit: list.append(line) --- 247,253 ---- if hit: if line[:1] not in string.whitespace: break ! elif line[:n].lower() == name: hit = 1 if hit: list.append(line) *************** *** 267,273 **** if not list: return None list[0] = list[0][len(name) + 1:] ! return string.joinfields(list, '') def getheader(self, name, default=None): """Get the header value for a name. --- 267,273 ---- if not list: return None list[0] = list[0][len(name) + 1:] ! return ''.join(list) def getheader(self, name, default=None): """Get the header value for a name. *************** *** 278,284 **** version which finds the *last* such header. """ try: ! return self.dict[string.lower(name)] except KeyError: return default get = getheader --- 278,284 ---- version which finds the *last* such header. """ try: ! return self.dict[name.lower()] except KeyError: return default get = getheader *************** *** 297,309 **** for s in self.getallmatchingheaders(name): if s[0] in string.whitespace: if current: ! current = "%s\n %s" % (current, string.strip(s)) else: ! current = string.strip(s) else: if have_header: result.append(current) ! current = string.strip(s[string.find(s, ":") + 1:]) have_header = 1 if have_header: result.append(current) --- 297,309 ---- for s in self.getallmatchingheaders(name): if s[0] in string.whitespace: if current: ! current = "%s\n %s" % (current, s.strip()) else: ! current = s.strip() else: if have_header: result.append(current) ! current = s[s.find(":") + 1:].strip() have_header = 1 if have_header: result.append(current) *************** *** 337,347 **** else: if raw: raw.append(', ') ! i = string.find(h, ':') if i > 0: addr = h[i+1:] raw.append(addr) ! alladdrs = string.join(raw, '') a = AddrlistClass(alladdrs) return a.getaddrlist() --- 337,347 ---- else: if raw: raw.append(', ') ! i = h.find(':') if i > 0: addr = h[i+1:] raw.append(addr) ! alladdrs = ''.join(raw) a = AddrlistClass(alladdrs) return a.getaddrlist() *************** *** 379,385 **** def __getitem__(self, name): """Get a specific header, as from a dictionary.""" ! return self.dict[string.lower(name)] def __setitem__(self, name, value): """Set the value of a header. --- 379,385 ---- def __getitem__(self, name): """Get a specific header, as from a dictionary.""" ! return self.dict[name.lower()] def __setitem__(self, name, value): """Set the value of a header. *************** *** 389,403 **** rather than where the altered header was. """ del self[name] # Won't fail if it doesn't exist ! self.dict[string.lower(name)] = value text = name + ": " + value ! lines = string.split(text, "\n") for line in lines: self.headers.append(line + "\n") def __delitem__(self, name): """Delete all occurrences of a specific header, if it is present.""" ! name = string.lower(name) if not self.dict.has_key(name): return del self.dict[name] --- 389,403 ---- rather than where the altered header was. """ del self[name] # Won't fail if it doesn't exist ! self.dict[name.lower()] = value text = name + ": " + value ! lines = text.split("\n") for line in lines: self.headers.append(line + "\n") def __delitem__(self, name): """Delete all occurrences of a specific header, if it is present.""" ! name = name.lower() if not self.dict.has_key(name): return del self.dict[name] *************** *** 407,413 **** hit = 0 for i in range(len(self.headers)): line = self.headers[i] ! if string.lower(line[:n]) == name: hit = 1 elif line[:1] not in string.whitespace: hit = 0 --- 407,413 ---- hit = 0 for i in range(len(self.headers)): line = self.headers[i] ! if line[:n].lower() == name: hit = 1 elif line[:1] not in string.whitespace: hit = 0 *************** *** 419,425 **** def has_key(self, name): """Determine whether a message contains the named header.""" ! return self.dict.has_key(string.lower(name)) def keys(self): """Get all of a message's header field names.""" --- 419,425 ---- def has_key(self, name): """Determine whether a message contains the named header.""" ! return self.dict.has_key(name.lower()) def keys(self): """Get all of a message's header field names.""" *************** *** 462,476 **** def quote(str): """Add quotes around a string.""" ! return '"%s"' % string.join( ! string.split( ! string.join( ! string.split(str, '\\'), ! '\\\\'), ! '"'), ! '\\"') - def parseaddr(address): """Parse an address into a (realname, mailaddr) tuple.""" a = AddrlistClass(address) --- 462,469 ---- def quote(str): """Add quotes around a string.""" ! return '"%s"' % str.replace ('\\', '\\\\').replace ('"', '\\"') def parseaddr(address): """Parse an address into a (realname, mailaddr) tuple.""" a = AddrlistClass(address) *************** *** 539,545 **** if self.pos >= len(self.field): # Bad email address technically, no domain. if plist: ! returnlist = [(string.join(self.commentlist), plist[0])] elif self.field[self.pos] in '.@': # email address is just an addrspec --- 532,538 ---- if self.pos >= len(self.field): # Bad email address technically, no domain. if plist: ! returnlist = [(' '.join(self.commentlist), plist[0])] elif self.field[self.pos] in '.@': # email address is just an addrspec *************** *** 547,553 **** self.pos = oldpos self.commentlist = oldcl addrspec = self.getaddrspec() ! returnlist = [(string.join(self.commentlist), addrspec)] elif self.field[self.pos] == ':': # address is a group --- 540,546 ---- self.pos = oldpos self.commentlist = oldcl addrspec = self.getaddrspec() ! returnlist = [(' '.join(self.commentlist), addrspec)] elif self.field[self.pos] == ':': # address is a group *************** *** 567,579 **** routeaddr = self.getrouteaddr() if self.commentlist: ! returnlist = [(string.join(plist) + ' (' + \ ! string.join(self.commentlist) + ')', routeaddr)] ! else: returnlist = [(string.join(plist), routeaddr)] else: if plist: ! returnlist = [(string.join(self.commentlist), plist[0])] elif self.field[self.pos] in self.specials: self.pos = self.pos + 1 --- 560,572 ---- routeaddr = self.getrouteaddr() if self.commentlist: ! returnlist = [(' '.join(plist) + ' (' + \ ! ' '.join(self.commentlist) + ')', routeaddr)] ! else: returnlist = [(' '.join(plist), routeaddr)] else: if plist: ! returnlist = [(' '.join(self.commentlist), plist[0])] elif self.field[self.pos] in self.specials: self.pos = self.pos + 1 *************** *** 632,643 **** self.gotonext() if self.pos >= len(self.field) or self.field[self.pos] != '@': ! return string.join(aslist, '') aslist.append('@') self.pos = self.pos + 1 self.gotonext() ! return string.join(aslist, '') + self.getdomain() def getdomain(self): """Get the complete domain name from an address.""" --- 625,636 ---- self.gotonext() if self.pos >= len(self.field) or self.field[self.pos] != '@': ! return ''.join(aslist) aslist.append('@') self.pos = self.pos + 1 self.gotonext() ! return ''.join(aslist) + self.getdomain() def getdomain(self): """Get the complete domain name from an address.""" *************** *** 655,661 **** elif self.field[self.pos] in self.atomends: break else: sdlist.append(self.getatom()) ! return string.join(sdlist, '') def getdelimited(self, beginchar, endchars, allowcomments = 1): """Parse a header fragment delimited by special characters. --- 648,654 ---- elif self.field[self.pos] in self.atomends: break else: sdlist.append(self.getatom()) ! return ''.join(sdlist) def getdelimited(self, beginchar, endchars, allowcomments = 1): """Parse a header fragment delimited by special characters. *************** *** 691,697 **** slist.append(self.field[self.pos]) self.pos = self.pos + 1 ! return string.join(slist, '') def getquote(self): """Get a quote-delimited fragment from self's field.""" --- 684,690 ---- slist.append(self.field[self.pos]) self.pos = self.pos + 1 ! return ''.join(slist) def getquote(self): """Get a quote-delimited fragment from self's field.""" *************** *** 715,721 **** else: atomlist.append(self.field[self.pos]) self.pos = self.pos + 1 ! return string.join(atomlist, '') def getphraselist(self): """Parse a sequence of RFC-822 phrases. --- 708,714 ---- else: atomlist.append(self.field[self.pos]) self.pos = self.pos + 1 ! return ''.join(atomlist) def getphraselist(self): """Parse a sequence of RFC-822 phrases. *************** *** 752,758 **** return len(self.addresslist) def __str__(self): ! return string.joinfields(map(dump_address_pair, self.addresslist),", ") def __add__(self, other): # Set union --- 745,751 ---- return len(self.addresslist) def __str__(self): ! return ", ".join(map(dump_address_pair, self.addresslist)) def __add__(self, other): # Set union *************** *** 810,826 **** Accounts for military timezones. """ ! data = string.split(data) ! if data[0][-1] in (',', '.') or string.lower(data[0]) in _daynames: # There's a dayname here. Skip it del data[0] if len(data) == 3: # RFC 850 date, deprecated ! stuff = string.split(data[0], '-') if len(stuff) == 3: data = stuff + data[1:] if len(data) == 4: s = data[3] ! i = string.find(s, '+') if i > 0: data[3:] = [s[:i], s[i+1:]] else: --- 803,819 ---- Accounts for military timezones. """ ! data = data.split() ! if data[0][-1] in (',', '.') or data[0].lower() in _daynames: # There's a dayname here. Skip it del data[0] if len(data) == 3: # RFC 850 date, deprecated ! stuff = data[0].split('-') if len(stuff) == 3: data = stuff + data[1:] if len(data) == 4: s = data[3] ! i = s.find('+') if i > 0: data[3:] = [s[:i], s[i+1:]] else: *************** *** 829,844 **** return None data = data[:5] [dd, mm, yy, tm, tz] = data ! mm = string.lower(mm) if not mm in _monthnames: ! dd, mm = mm, string.lower(dd) if not mm in _monthnames: return None mm = _monthnames.index(mm)+1 if mm > 12: mm = mm - 12 if dd[-1] == ',': dd = dd[:-1] ! i = string.find(yy, ':') if i > 0: yy, tm = tm, yy if yy[-1] == ',': --- 822,837 ---- return None data = data[:5] [dd, mm, yy, tm, tz] = data ! mm = mm.lower() if not mm in _monthnames: ! dd, mm = mm, dd.lower() if not mm in _monthnames: return None mm = _monthnames.index(mm)+1 if mm > 12: mm = mm - 12 if dd[-1] == ',': dd = dd[:-1] ! i = yy.find(':') if i > 0: yy, tm = tm, yy if yy[-1] == ',': *************** *** 847,853 **** yy, tz = tz, yy if tm[-1] == ',': tm = tm[:-1] ! tm = string.splitfields(tm, ':') if len(tm) == 2: [thh, tmm] = tm tss = '0' --- 840,846 ---- yy, tz = tz, yy if tm[-1] == ',': tm = tm[:-1] ! tm = tm.split(':') if len(tm) == 2: [thh, tmm] = tm tss = '0' *************** *** 856,876 **** else: return None try: ! yy = string.atoi(yy) ! dd = string.atoi(dd) ! thh = string.atoi(thh) ! tmm = string.atoi(tmm) ! tss = string.atoi(tss) ! except string.atoi_error: return None tzoffset=None ! tz=string.upper(tz) if _timezones.has_key(tz): tzoffset=_timezones[tz] else: try: ! tzoffset=string.atoi(tz) ! except string.atoi_error: pass # Convert a timezone offset into seconds ; -0500 -> -18000 if tzoffset: --- 849,869 ---- else: return None try: ! yy = int(yy) ! dd = int(dd) ! thh = int(thh) ! tmm = int(tmm) ! tss = int(tss) ! except ValueError: return None tzoffset=None ! tz=tz.upper() if _timezones.has_key(tz): tzoffset=_timezones[tz] else: try: ! tzoffset=int(tz) ! except ValueError: pass # Convert a timezone offset into seconds ; -0500 -> -18000 if tzoffset: Index: Lib/robotparser.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/robotparser.py,v retrieving revision 1.3 diff -c -r1.3 robotparser.py *** robotparser.py 2000/03/27 19:29:31 1.3 --- robotparser.py 2000/04/11 11:56:50 *************** *** 30,36 **** def parse(self, lines): """parse the input lines from a robot.txt file""" ! import string, re active = [] for line in lines: if self.debug: print '>', line, --- 30,36 ---- def parse(self, lines): """parse the input lines from a robot.txt file""" ! import re active = [] for line in lines: if self.debug: print '>', line, *************** *** 39,50 **** active = [] continue # remove optional comment and strip line ! line = string.strip(line[:string.find(line, '#')]) if not line: continue line = re.split(' *: *', line) if len(line) == 2: ! line[0] = string.lower(line[0]) if line[0] == 'user-agent': # this record applies to this user agent if self.debug: print '>> user-agent:', line[1] --- 39,50 ---- active = [] continue # remove optional comment and strip line ! line = line[:line.find('#')].strip() if not line: continue line = re.split(' *: *', line) if len(line) == 2: ! line[0] = line[0].lower() if line[0] == 'user-agent': # this record applies to this user agent if self.debug: print '>> user-agent:', line[1] Index: Lib/sgmllib.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/sgmllib.py,v retrieving revision 1.19 diff -c -r1.19 sgmllib.py *** sgmllib.py 2000/02/04 15:28:40 1.19 --- sgmllib.py 2000/04/11 11:56:51 *************** *** 220,226 **** if not match: return -1 tag, data = match.group(1, 2) ! tag = string.lower(tag) self.finish_shorttag(tag, data) k = match.end(0) return k --- 220,226 ---- if not match: return -1 tag, data = match.group(1, 2) ! tag = tag.lower() self.finish_shorttag(tag, data) k = match.end(0) return k *************** *** 240,246 **** if not match: raise RuntimeError, 'unexpected call to parse_starttag' k = match.end(0) ! tag = string.lower(rawdata[i+1:k]) self.lasttag = tag while k < j: match = attrfind.match(rawdata, k) --- 240,246 ---- if not match: raise RuntimeError, 'unexpected call to parse_starttag' k = match.end(0) ! tag = rawdata[i+1:k].lower() self.lasttag = tag while k < j: match = attrfind.match(rawdata, k) *************** *** 251,257 **** elif attrvalue[:1] == '\'' == attrvalue[-1:] or \ attrvalue[:1] == '"' == attrvalue[-1:]: attrvalue = attrvalue[1:-1] ! attrs.append((string.lower(attrname), attrvalue)) k = match.end(0) if rawdata[j] == '>': j = j+1 --- 251,257 ---- elif attrvalue[:1] == '\'' == attrvalue[-1:] or \ attrvalue[:1] == '"' == attrvalue[-1:]: attrvalue = attrvalue[1:-1] ! attrs.append((attrname.lower(), attrvalue)) k = match.end(0) if rawdata[j] == '>': j = j+1 *************** *** 265,271 **** if not match: return -1 j = match.start(0) ! tag = string.lower(string.strip(rawdata[i+2:j])) if rawdata[j] == '>': j = j+1 self.finish_endtag(tag) --- 265,271 ---- if not match: return -1 j = match.start(0) ! tag = rawdata[i+2:j].strip().lower() if rawdata[j] == '>': j = j+1 self.finish_endtag(tag) *************** *** 344,351 **** # Example -- handle character reference, no need to override def handle_charref(self, name): try: ! n = string.atoi(name) ! except string.atoi_error: self.unknown_charref(name) return if not 0 <= n <= 255: --- 344,351 ---- # Example -- handle character reference, no need to override def handle_charref(self, name): try: ! n = int(name) ! except ValueError: self.unknown_charref(name) return if not 0 <= n <= 255: Index: Lib/smtplib.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/smtplib.py,v retrieving revision 1.23 diff -c -r1.23 smtplib.py *** smtplib.py 2000/03/28 21:45:46 1.23 --- smtplib.py 2000/04/11 11:56:51 *************** *** 40,46 **** # This was modified from the Python 1.5 library HTTP lib. import socket - import string import re import rfc822 import types --- 40,45 ---- *************** *** 204,214 **** """ if not port: ! i = string.find(host, ':') if i >= 0: host, port = host[:i], host[i+1:] ! try: port = string.atoi(port) ! except string.atoi_error: raise socket.error, "nonnumeric port" if not port: port = SMTP_PORT self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) --- 203,213 ---- """ if not port: ! i = host.find(':') if i >= 0: host, port = host[:i], host[i+1:] ! try: port = int(port) ! except ValueError: raise socket.error, "nonnumeric port" if not port: port = SMTP_PORT self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) *************** *** 259,270 **** self.close() raise SMTPServerDisconnected("Connection unexpectedly closed") if self.debuglevel > 0: print 'reply:', `line` ! resp.append(string.strip(line[4:])) code=line[:3] # Check that the error code is syntactically correct. # Don't attempt to read a continuation line if it is broken. try: ! errcode = string.atoi(code) except ValueError: errcode = -1 break --- 258,269 ---- self.close() raise SMTPServerDisconnected("Connection unexpectedly closed") if self.debuglevel > 0: print 'reply:', `line` ! resp.append(line[4:].strip()) code=line[:3] # Check that the error code is syntactically correct. # Don't attempt to read a continuation line if it is broken. try: ! errcode = int(code) except ValueError: errcode = -1 break *************** *** 272,278 **** if line[3:4]!="-": break ! errmsg = string.join(resp,"\n") if self.debuglevel > 0: print 'reply: retcode (%s); Msg: %s' % (errcode,errmsg) return errcode, errmsg --- 271,277 ---- if line[3:4]!="-": break ! errmsg = "\n".join(resp) if self.debuglevel > 0: print 'reply: retcode (%s); Msg: %s' % (errcode,errmsg) return errcode, errmsg *************** *** 288,294 **** Hostname to send for this command defaults to the FQDN of the local host. """ ! name=string.strip(name) if len(name)==0: name = socket.gethostname() try: --- 287,293 ---- Hostname to send for this command defaults to the FQDN of the local host. """ ! name=name.strip() if len(name)==0: name = socket.gethostname() try: *************** *** 305,311 **** Hostname to send for this command defaults to the FQDN of the local host. """ ! name=string.strip(name) if len(name)==0: name = socket.gethostname() try: --- 304,310 ---- Hostname to send for this command defaults to the FQDN of the local host. """ ! name=name.strip() if len(name)==0: name = socket.gethostname() try: *************** *** 324,342 **** return (code,msg) self.does_esmtp=1 #parse the ehlo responce -ddm ! resp=string.split(self.ehlo_resp,'\n') del resp[0] for each in resp: m=re.match(r'(?P[A-Za-z0-9][A-Za-z0-9\-]*)',each) if m: ! feature=string.lower(m.group("feature")) ! params=string.strip(m.string[m.end("feature"):]) self.esmtp_features[feature]=params return (code,msg) def has_extn(self, opt): """Does the server support a given SMTP service extension?""" ! return self.esmtp_features.has_key(string.lower(opt)) def help(self, args=''): """SMTP 'help' command. --- 323,341 ---- return (code,msg) self.does_esmtp=1 #parse the ehlo responce -ddm ! resp=self.ehlo_resp.split('\n') del resp[0] for each in resp: m=re.match(r'(?P[A-Za-z0-9][A-Za-z0-9\-]*)',each) if m: ! feature=m.group("feature").lower() ! params=m.string[m.end("feature"):].strip() self.esmtp_features[feature]=params return (code,msg) def has_extn(self, opt): """Does the server support a given SMTP service extension?""" ! return self.esmtp_features.has_key(opt.lower()) def help(self, args=''): """SMTP 'help' command. *************** *** 356,362 **** """SMTP 'mail' command -- begins mail xfer session.""" optionlist = '' if options and self.does_esmtp: ! optionlist = ' ' + string.join(options, ' ') self.putcmd("mail", "FROM:%s%s" % (quoteaddr(sender) ,optionlist)) return self.getreply() --- 355,361 ---- """SMTP 'mail' command -- begins mail xfer session.""" optionlist = '' if options and self.does_esmtp: ! optionlist = ' ' + ' '.join(options) self.putcmd("mail", "FROM:%s%s" % (quoteaddr(sender) ,optionlist)) return self.getreply() *************** *** 364,370 **** """SMTP 'rcpt' command -- indicates 1 recipient for this mail.""" optionlist = '' if options and self.does_esmtp: ! optionlist = ' ' + string.join(options, ' ') self.putcmd("rcpt","TO:%s%s" % (quoteaddr(recip),optionlist)) return self.getreply() --- 363,369 ---- """SMTP 'rcpt' command -- indicates 1 recipient for this mail.""" optionlist = '' if options and self.does_esmtp: ! optionlist = ' ' + ' '.join(options) self.putcmd("rcpt","TO:%s%s" % (quoteaddr(recip),optionlist)) return self.getreply() *************** *** 521,530 **** def prompt(prompt): sys.stdout.write(prompt + ": ") ! return string.strip(sys.stdin.readline()) fromaddr = prompt("From") ! toaddrs = string.splitfields(prompt("To"), ',') print "Enter message, end with ^D:" msg = '' while 1: --- 520,529 ---- def prompt(prompt): sys.stdout.write(prompt + ": ") ! return sys.stdin.readline().strip() fromaddr = prompt("From") ! toaddrs = prompt("To").split(',') print "Enter message, end with ^D:" msg = '' while 1: Index: Lib/sre_compile.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/sre_compile.py,v retrieving revision 1.3 diff -c -r1.3 sre_compile.py *** sre_compile.py 2000/04/10 17:10:48 1.3 --- sre_compile.py 2000/04/11 11:56:51 *************** *** 17,23 **** # FIXME: formalize (objectify?) and document the compiler code # format, so that other frontends can use this compiler ! import array, string, sys import _sre --- 17,23 ---- # FIXME: formalize (objectify?) and document the compiler code # format, so that other frontends can use this compiler ! import array, sys import _sre *************** *** 49,55 **** def _lower(literal): # return _sre._lower(literal) # FIXME ! return string.lower(literal) def _compile(code, pattern, flags): append = code.append --- 49,55 ---- def _lower(literal): # return _sre._lower(literal) # FIXME ! return literal.lower() def _compile(code, pattern, flags): append = code.append Index: Lib/sre_constants.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/sre_constants.py,v retrieving revision 1.3 diff -c -r1.3 sre_constants.py *** sre_constants.py 2000/04/10 17:10:48 1.3 --- sre_constants.py 2000/04/11 11:56:51 *************** *** 120,131 **** } if __name__ == "__main__": - import string items = CODES.items() items.sort(lambda a, b: cmp(a[1], b[1])) f = open("sre_constants.h", "w") f.write("/* generated by sre_constants.py */\n") for k, v in items: ! f.write("#define SRE_OP_" + string.upper(k) + " " + str(v) + "\n") f.close() print "done" --- 120,130 ---- } if __name__ == "__main__": items = CODES.items() items.sort(lambda a, b: cmp(a[1], b[1])) f = open("sre_constants.h", "w") f.write("/* generated by sre_constants.py */\n") for k, v in items: ! f.write("#define SRE_OP_" + k.upper() + " " + str(v) + "\n") f.close() print "done" Index: Lib/tabnanny.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/tabnanny.py,v retrieving revision 1.10 diff -c -r1.10 tabnanny.py *** tabnanny.py 2000/02/23 15:32:19 1.10 --- tabnanny.py 2000/04/11 11:56:52 *************** *** 12,18 **** import os import sys - import string import getopt import tokenize --- 12,17 ---- *************** *** 236,247 **** return a def format_witnesses(w): - import string firsts = map(lambda tup: str(tup[0]), w) prefix = "at tab size" if len(w) > 1: prefix = prefix + "s" ! return prefix + " " + string.join(firsts, ', ') # The collection of globals, the reset_globals() function, and the # tokeneater() function, depend on which version of tokenize is --- 235,245 ---- return a def format_witnesses(w): firsts = map(lambda tup: str(tup[0]), w) prefix = "at tab size" if len(w) > 1: prefix = prefix + "s" ! return prefix + " " + ', '.join(firsts) # The collection of globals, the reset_globals() function, and the # tokeneater() function, depend on which version of tokenize is Index: Lib/telnetlib.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/telnetlib.py,v retrieving revision 1.7 diff -c -r1.7 telnetlib.py *** telnetlib.py 1998/12/23 23:04:17 1.7 --- telnetlib.py 2000/04/11 11:56:52 *************** *** 40,46 **** import sys import socket import select - import string # Tunable parameters DEBUGLEVEL = 0 --- 40,45 ---- *************** *** 187,193 **** """ if IAC in buffer: ! buffer = string.replace(buffer, IAC, IAC+IAC) self.msg("send %s", `buffer`) self.sock.send(buffer) --- 186,192 ---- """ if IAC in buffer: ! buffer = buffer.replace(IAC, IAC+IAC) self.msg("send %s", `buffer`) self.sock.send(buffer) *************** *** 201,207 **** """ n = len(match) self.process_rawq() ! i = string.find(self.cookedq, match) if i >= 0: i = i+n buf = self.cookedq[:i] --- 200,206 ---- """ n = len(match) self.process_rawq() ! i = self.cookedq.find(match) if i >= 0: i = i+n buf = self.cookedq[:i] *************** *** 215,221 **** i = max(0, len(self.cookedq)-n) self.fill_rawq() self.process_rawq() ! i = string.find(self.cookedq, match, i) if i >= 0: i = i+n buf = self.cookedq[:i] --- 214,220 ---- i = max(0, len(self.cookedq)-n) self.fill_rawq() self.process_rawq() ! i = self.cookedq.find(match, i) if i >= 0: i = i+n buf = self.cookedq[:i] Index: Lib/token.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/token.py,v retrieving revision 1.7 diff -c -r1.7 token.py *** token.py 2000/02/04 15:28:41 1.7 --- token.py 2000/04/11 11:56:52 *************** *** 71,77 **** def main(): import re - import string import sys args = sys.argv[1:] inFileName = args and args[0] or "Include/token.h" --- 71,76 ---- *************** *** 83,89 **** except IOError, err: sys.stdout.write("I/O error: %s\n" % str(err)) sys.exit(1) ! lines = string.splitfields(fp.read(), "\n") fp.close() prog = re.compile( "#define[ \t][ \t]*([A-Z][A-Z_]*)[ \t][ \t]*([0-9][0-9]*)", --- 82,88 ---- except IOError, err: sys.stdout.write("I/O error: %s\n" % str(err)) sys.exit(1) ! lines = fp.read().split("\n") fp.close() prog = re.compile( "#define[ \t][ \t]*([A-Z][A-Z_]*)[ \t][ \t]*([0-9][0-9]*)", *************** *** 93,99 **** match = prog.match(line) if match: name, val = match.group(1, 2) ! val = string.atoi(val) tokens[val] = name # reverse so we can sort them... keys = tokens.keys() keys.sort() --- 92,98 ---- match = prog.match(line) if match: name, val = match.group(1, 2) ! val = int(val) tokens[val] = name # reverse so we can sort them... keys = tokens.keys() keys.sort() *************** *** 103,109 **** except IOError, err: sys.stderr.write("I/O error: %s\n" % str(err)) sys.exit(2) ! format = string.splitfields(fp.read(), "\n") fp.close() try: start = format.index("#--start constants--") + 1 --- 102,108 ---- except IOError, err: sys.stderr.write("I/O error: %s\n" % str(err)) sys.exit(2) ! format = fp.read().split("\n") fp.close() try: start = format.index("#--start constants--") + 1 *************** *** 120,126 **** except IOError, err: sys.stderr.write("I/O error: %s\n" % str(err)) sys.exit(4) ! fp.write(string.joinfields(format, "\n")) fp.close() --- 119,125 ---- except IOError, err: sys.stderr.write("I/O error: %s\n" % str(err)) sys.exit(4) ! fp.write("\n".join(format)) fp.close() Index: Lib/tokenize.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/tokenize.py,v retrieving revision 1.12 diff -c -r1.12 tokenize.py *** tokenize.py 1998/04/03 16:05:38 1.12 --- tokenize.py 2000/04/11 11:56:52 *************** *** 26,32 **** # Imagnumber is new. Expfloat is corrected to reject '0e4'. # Note: to quote a backslash in a regex, it must be doubled in a r'aw' string. ! def group(*choices): return '(' + string.join(choices, '|') + ')' def any(*choices): return apply(group, choices) + '*' def maybe(*choices): return apply(group, choices) + '?' --- 26,32 ---- # Imagnumber is new. Expfloat is corrected to reject '0e4'. # Note: to quote a backslash in a regex, it must be doubled in a r'aw' string. ! def group(*choices): return '(' + '|'.join(choices) + ')' def any(*choices): return apply(group, choices) + '*' def maybe(*choices): return apply(group, choices) + '?' Index: Lib/traceback.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/traceback.py,v retrieving revision 1.15 diff -c -r1.15 traceback.py *** traceback.py 2000/04/10 16:29:29 1.15 --- traceback.py 2000/04/11 11:56:53 *************** *** 18,24 **** _print(file, ' File "%s", line %d, in %s' % (filename,lineno,name)) if line: ! _print(file, ' %s' % string.strip(line)) def format_list(extracted_list): """Given a list of tuples as returned by extract_tb() or --- 18,24 ---- _print(file, ' File "%s", line %d, in %s' % (filename,lineno,name)) if line: ! _print(file, ' %s' % line.strip()) def format_list(extracted_list): """Given a list of tuples as returned by extract_tb() or *************** *** 31,37 **** for filename, lineno, name, line in extracted_list: item = ' File "%s", line %d, in %s\n' % (filename,lineno,name) if line: ! item = item + ' %s\n' % string.strip(line) list.append(item) return list --- 31,37 ---- for filename, lineno, name, line in extracted_list: item = ' File "%s", line %d, in %s\n' % (filename,lineno,name) if line: ! item = item + ' %s\n' % line.strip() list.append(item) return list *************** *** 56,62 **** _print(file, ' File "%s", line %d, in %s' % (filename,lineno,name)) line = linecache.getline(filename, lineno) ! if line: _print(file, ' ' + string.strip(line)) tb = tb.tb_next n = n+1 --- 56,62 ---- _print(file, ' File "%s", line %d, in %s' % (filename,lineno,name)) line = linecache.getline(filename, lineno) ! if line: _print(file, ' ' + line.strip()) tb = tb.tb_next n = n+1 *************** *** 85,91 **** filename = co.co_filename name = co.co_name line = linecache.getline(filename, lineno) ! if line: line = string.strip(line) else: line = None list.append((filename, lineno, name, line)) tb = tb.tb_next --- 85,91 ---- filename = co.co_filename name = co.co_name line = linecache.getline(filename, lineno) ! if line: line = line.strip() else: line = None list.append((filename, lineno, name, line)) tb = tb.tb_next *************** *** 157,163 **** while i < len(line) and \ line[i] in string.whitespace: i = i+1 ! list.append(' %s\n' % string.strip(line)) s = ' ' for c in line[i:offset-1]: if c in string.whitespace: --- 157,163 ---- while i < len(line) and \ line[i] in string.whitespace: i = i+1 ! list.append(' %s\n' % line.strip()) s = ' ' for c in line[i:offset-1]: if c in string.whitespace: *************** *** 236,242 **** filename = co.co_filename name = co.co_name line = linecache.getline(filename, lineno) ! if line: line = string.strip(line) else: line = None list.append((filename, lineno, name, line)) f = f.f_back --- 236,242 ---- filename = co.co_filename name = co.co_name line = linecache.getline(filename, lineno) ! if line: line = line.strip() else: line = None list.append((filename, lineno, name, line)) f = f.f_back Index: Lib/urllib.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/urllib.py,v retrieving revision 1.91 diff -c -r1.91 urllib.py *** urllib.py 2000/02/04 15:28:41 1.91 --- urllib.py 2000/04/11 11:56:53 *************** *** 150,156 **** self.type = type if '-' in name: # replace - with _ ! name = string.join(string.split(name, '-'), '_') if not hasattr(self, name): if data is None: return self.open_unknown(fullurl) --- 150,156 ---- self.type = type if '-' in name: # replace - with _ ! name = name.replace ('-', '_') if not hasattr(self, name): if data is None: return self.open_unknown(fullurl) *************** *** 239,245 **** urltype, rest = splittype(selector) url = rest user_passwd = None ! if string.lower(urltype) != 'http': realhost = None else: realhost, rest = splithost(rest) --- 239,245 ---- urltype, rest = splittype(selector) url = rest user_passwd = None ! if urltype.lower() != 'http': realhost = None else: realhost, rest = splithost(rest) *************** *** 251,257 **** if not host: raise IOError, ('http error', 'no host given') if user_passwd: import base64 ! auth = string.strip(base64.encodestring(user_passwd)) else: auth = None h = httplib.HTTP(host) --- 251,257 ---- if not host: raise IOError, ('http error', 'no host given') if user_passwd: import base64 ! auth = base64.encodestring(user_passwd).strip() else: auth = None h = httplib.HTTP(host) *************** *** 308,314 **** else: host, selector = url urltype, rest = splittype(selector) ! if string.lower(urltype) == 'https': realhost, rest = splithost(rest) user_passwd, realhost = splituser(realhost) if user_passwd: --- 308,314 ---- else: host, selector = url urltype, rest = splittype(selector) ! if urltype.lower() == 'https': realhost, rest = splithost(rest) user_passwd, realhost = splituser(realhost) if user_passwd: *************** *** 317,323 **** if not host: raise IOError, ('https error', 'no host given') if user_passwd: import base64 ! auth = string.strip(base64.encodestring(user_passwd)) else: auth = None h = httplib.HTTPS(host, 0, --- 317,323 ---- if not host: raise IOError, ('https error', 'no host given') if user_passwd: import base64 ! auth = base64.encodestring(user_passwd).strip() else: auth = None h = httplib.HTTPS(host, 0, *************** *** 399,409 **** port = int(port) path, attrs = splitattr(path) path = unquote(path) ! dirs = string.splitfields(path, '/') dirs, file = dirs[:-1], dirs[-1] if dirs and not dirs[0]: dirs = dirs[1:] if dirs and not dirs[0]: dirs[0] = '/' ! key = (user, host, port, string.joinfields(dirs, '/')) # XXX thread unsafe! if len(self.ftpcache) > MAXFTPCACHE: # Prune the cache, rather arbitrarily --- 399,409 ---- port = int(port) path, attrs = splitattr(path) path = unquote(path) ! dirs = path.split('/') dirs, file = dirs[:-1], dirs[-1] if dirs and not dirs[0]: dirs = dirs[1:] if dirs and not dirs[0]: dirs[0] = '/' ! key = (user, host, port, '/'.join(dirs)) # XXX thread unsafe! if len(self.ftpcache) > MAXFTPCACHE: # Prune the cache, rather arbitrarily *************** *** 420,428 **** else: type = 'I' for attr in attrs: attr, value = splitvalue(attr) ! if string.lower(attr) == 'type' and \ value in ('a', 'A', 'i', 'I', 'd', 'D'): ! type = string.upper(value) (fp, retrlen) = self.ftpcache[key].retrfile(file, type) if retrlen is not None and retrlen >= 0: import mimetools, StringIO --- 420,428 ---- else: type = 'I' for attr in attrs: attr, value = splitvalue(attr) ! if attr.lower() == 'type' and \ value in ('a', 'A', 'i', 'I', 'd', 'D'): ! type = value.upper() (fp, retrlen) = self.ftpcache[key].retrfile(file, type) if retrlen is not None and retrlen >= 0: import mimetools, StringIO *************** *** 445,456 **** # parameter := attribute "=" value import StringIO, mimetools, time try: ! [type, data] = string.split(url, ',', 1) except ValueError: raise IOError, ('data error', 'bad data URL') if not type: type = 'text/plain;charset=US-ASCII' ! semi = string.rfind(type, ';') if semi >= 0 and '=' not in type[semi:]: encoding = type[semi+1:] type = type[:semi] --- 445,456 ---- # parameter := attribute "=" value import StringIO, mimetools, time try: ! [type, data] = url.split(',', 1) except ValueError: raise IOError, ('data error', 'bad data URL') if not type: type = 'text/plain;charset=US-ASCII' ! semi = type.rfind(';') if semi >= 0 and '=' not in type[semi:]: encoding = type[semi+1:] type = type[:semi] *************** *** 468,474 **** msg.append('Content-length: %d' % len(data)) msg.append('') msg.append(data) ! msg = string.join(msg, '\n') f = StringIO.StringIO(msg) headers = mimetools.Message(f, 0) f.fileno = None # needed for addinfourl --- 468,474 ---- msg.append('Content-length: %d' % len(data)) msg.append('') msg.append(data) ! msg = '\n'.join(msg) f = StringIO.StringIO(msg) headers = mimetools.Message(f, 0) f.fileno = None # needed for addinfourl *************** *** 518,524 **** match = re.match('[ \t]*([^ \t]+)[ \t]+realm="([^"]*)"', stuff) if match: scheme, realm = match.groups() ! if string.lower(scheme) == 'basic': name = 'retry_' + self.type + '_basic_auth' if data is None: return getattr(self,name)(url, realm) --- 518,524 ---- match = re.match('[ \t]*([^ \t]+)[ \t]+realm="([^"]*)"', stuff) if match: scheme, realm = match.groups() ! if scheme.lower() == 'basic': name = 'retry_' + self.type + '_basic_auth' if data is None: return getattr(self,name)(url, realm) *************** *** 527,533 **** def retry_http_basic_auth(self, url, realm, data=None): host, selector = splithost(url) ! i = string.find(host, '@') + 1 host = host[i:] user, passwd = self.get_user_passwd(host, realm, i) if not (user or passwd): return None --- 527,533 ---- def retry_http_basic_auth(self, url, realm, data=None): host, selector = splithost(url) ! i = host.find('@') + 1 host = host[i:] user, passwd = self.get_user_passwd(host, realm, i) if not (user or passwd): return None *************** *** 540,546 **** def retry_https_basic_auth(self, url, realm, data=None): host, selector = splithost(url) ! i = string.find(host, '@') + 1 host = host[i:] user, passwd = self.get_user_passwd(host, realm, i) if not (user or passwd): return None --- 540,546 ---- def retry_https_basic_auth(self, url, realm, data=None): host, selector = splithost(url) ! i = host.find('@') + 1 host = host[i:] user, passwd = self.get_user_passwd(host, realm, i) if not (user or passwd): return None *************** *** 549,555 **** return self.open_https(newurl) def get_user_passwd(self, host, realm, clear_cache = 0): ! key = realm + '@' + string.lower(host) if self.auth_cache.has_key(key): if clear_cache: del self.auth_cache[key] --- 549,555 ---- return self.open_https(newurl) def get_user_passwd(self, host, realm, clear_cache = 0): ! key = realm + '@' + host.lower() if self.auth_cache.has_key(key): if clear_cache: del self.auth_cache[key] *************** *** 774,780 **** i = len(basepath) else: # else replace last component ! i = string.rfind(basepath, '/') if i < 0: # basepath not absolute if host: --- 774,780 ---- i = len(basepath) else: # else replace last component ! i = basepath.rfind('/') if i < 0: # basepath not absolute if host: *************** *** 789,795 **** # Interpret ../ (important because of symlinks) while basepath and path[:3] == '../': path = path[3:] ! i = string.rfind(basepath[:-1], '/') if i > 0: basepath = basepath[:i+1] elif i == 0: --- 789,795 ---- # Interpret ../ (important because of symlinks) while basepath and path[:3] == '../': path = path[3:] ! i = basepath[:-1].rfind('/') if i > 0: basepath = basepath[:i+1] elif i == 0: *************** *** 823,832 **** def unwrap(url): """unwrap('') --> 'type://host/path'.""" ! url = string.strip(url) if url[:1] == '<' and url[-1:] == '>': ! url = string.strip(url[1:-1]) ! if url[:4] == 'URL:': url = string.strip(url[4:]) return url _typeprog = None --- 823,832 ---- def unwrap(url): """unwrap('') --> 'type://host/path'.""" ! url = url.strip() if url[:1] == '<' and url[-1:] == '>': ! url = url[1:-1].strip() ! if url[:4] == 'URL:': url = url[4:].strip() return url _typeprog = None *************** *** 907,915 **** if match: host, port = match.group(1, 2) try: ! if not port: raise string.atoi_error, "no digits" ! nport = string.atoi(port) ! except string.atoi_error: nport = None return host, nport return host, defport --- 907,915 ---- if match: host, port = match.group(1, 2) try: ! if not port: raise ValueError, "no digits" ! nport = int(port) ! except ValueError: nport = None return host, nport return host, defport *************** *** 941,947 **** def splitattr(url): """splitattr('/path;attr1=value1;attr2=value2;...') -> '/path', ['attr1=value1', 'attr2=value2', ...].""" ! words = string.splitfields(url, ';') return words[0], words[1:] _valueprog = None --- 941,947 ---- def splitattr(url): """splitattr('/path;attr1=value1;attr2=value2;...') -> '/path', ['attr1=value1', 'attr2=value2', ...].""" ! words = url.split(';') return words[0], words[1:] _valueprog = None *************** *** 965,972 **** def unquote(s): """unquote('abc%20def') -> 'abc def'.""" mychr = chr ! myatoi = string.atoi ! list = string.split(s, '%') res = [list[0]] myappend = res.append del list[0] --- 965,972 ---- def unquote(s): """unquote('abc%20def') -> 'abc def'.""" mychr = chr ! myatoi = int ! list = s.split('%') res = [list[0]] myappend = res.append del list[0] *************** *** 979,990 **** myappend('%' + item) else: myappend('%' + item) ! return string.join(res, "") def unquote_plus(s): if '+' in s: # replace '+' with ' ' ! s = string.join(string.split(s, '+'), ' ') return unquote(s) always_safe = string.letters + string.digits + '_,.-' --- 979,990 ---- myappend('%' + item) else: myappend('%' + item) ! return "".join(res) def unquote_plus(s): if '+' in s: # replace '+' with ' ' ! s = s.replace('+', ' ') return unquote(s) always_safe = string.letters + string.digits + '_,.-' *************** *** 997,1012 **** c = res[i] if c not in safe: res[i] = '%%%02x' % ord(c) ! return string.joinfields(res, '') def quote_plus(s, safe = '/'): # XXX Can speed this up an order of magnitude if ' ' in s: # replace ' ' with '+' ! l = string.split(s, ' ') for i in range(len(l)): l[i] = quote(l[i], safe) ! return string.join(l, '+') else: return quote(s, safe) --- 997,1012 ---- c = res[i] if c not in safe: res[i] = '%%%02x' % ord(c) ! return ''.join(res) def quote_plus(s, safe = '/'): # XXX Can speed this up an order of magnitude if ' ' in s: # replace ' ' with '+' ! l = s.split(' ') for i in range(len(l)): l[i] = quote(l[i], safe) ! return '+'.join(l) else: return quote(s, safe) *************** *** 1017,1023 **** k = quote_plus(str(k)) v = quote_plus(str(v)) l.append(k + '=' + v) ! return string.join(l, '&') # Proxy handling --- 1017,1023 ---- k = quote_plus(str(k)) v = quote_plus(str(v)) l.append(k + '=' + v) ! return '&'.join(l) # Proxy handling *************** *** 1064,1070 **** """ proxies = {} for name, value in os.environ.items(): ! name = string.lower(name) if value and name[-6:] == '_proxy': proxies[name[:-6]] = value return proxies --- 1064,1070 ---- """ proxies = {} for name, value in os.environ.items(): ! name = name.lower() if value and name[-6:] == '_proxy': proxies[name[:-6]] = value return proxies *************** *** 1119,1125 **** del fp if '\r' in data: table = string.maketrans("", "") ! data = string.translate(data, table, "\r") print data fn, h = None, None print '-'*40 --- 1119,1125 ---- del fp if '\r' in data: table = string.maketrans("", "") ! data = data.translate(table, "\r") print data fn, h = None, None print '-'*40 Index: Lib/urllib2.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/urllib2.py,v retrieving revision 1.3 diff -c -r1.3 urllib2.py *** urllib2.py 2000/02/10 17:17:14 1.3 --- urllib2.py 2000/04/11 11:56:54 *************** *** 85,91 **** # gopher can return a socket.error # check digest against correct (i.e. non-apache) implementation - import string import socket import UserDict import httplib --- 85,90 ---- *************** *** 262,274 **** self.handle_open[protocol] = [handler] added = 1 continue ! i = string.find(meth, '_') ! j = string.find(meth[i+1:], '_') + i + 1 if j != -1 and meth[i+1:j] == 'error': proto = meth[:i] kind = meth[j+1:] try: ! kind = string.atoi(kind) except ValueError: pass dict = self.handle_error.get(proto, {}) --- 261,273 ---- self.handle_open[protocol] = [handler] added = 1 continue ! i = meth.find('_') ! j = meth[i+1:].find('_') + i + 1 if j != -1 and meth[i+1:j] == 'error': proto = meth[:i] kind = meth[j+1:] try: ! kind = int(kind) except ValueError: pass dict = self.handle_error.get(proto, {}) *************** *** 593,599 **** mo = HTTPBasicAuthHandler.rx.match(authreq) if mo: scheme, realm = mo.groups() ! if string.lower(scheme) == 'basic': return self.retry_http_basic_auth(req, realm) def retry_http_basic_auth(self, req, realm): --- 592,598 ---- mo = HTTPBasicAuthHandler.rx.match(authreq) if mo: scheme, realm = mo.groups() ! if scheme.lower() == 'basic': return self.retry_http_basic_auth(req, realm) def retry_http_basic_auth(self, req, realm): *************** *** 607,613 **** user,pw = self.passwd.find_user_password(realm, host) if pw: raw = "%s:%s" % (user, pw) ! auth = string.strip(base64.encodestring(raw)) req.add_header('Authorization', 'Basic %s' % auth) resp = self.parent.open(req) self.__current_realm = None --- 606,612 ---- user,pw = self.passwd.find_user_password(realm, host) if pw: raw = "%s:%s" % (user, pw) ! auth = base64.encodestring(raw).strip() req.add_header('Authorization', 'Basic %s' % auth) resp = self.parent.open(req) self.__current_realm = None *************** *** 632,643 **** # XXX could be mult. headers authreq = headers.get('www-authenticate', None) if authreq: ! kind = string.split(authreq)[0] if kind == 'Digest': return self.retry_http_digest_auth(req, authreq) def retry_http_digest_auth(self, req, auth): ! token, challenge = string.split(auth, ' ', 1) chal = parse_keqv_list(parse_http_list(challenge)) auth = self.get_authorization(req, chal) if auth: --- 631,642 ---- # XXX could be mult. headers authreq = headers.get('www-authenticate', None) if authreq: ! kind = authreq.split()[0] if kind == 'Digest': return self.retry_http_digest_auth(req, authreq) def retry_http_digest_auth(self, req, auth): ! token, challenge = auth.split(' ', 1) chal = parse_keqv_list(parse_http_list(challenge)) auth = self.get_authorization(req, chal) if auth: *************** *** 717,723 **** hexrep.append(hex(n)[-1]) n = ord(c) & 0xf hexrep.append(hex(n)[-1]) ! return string.join(hexrep, '') class HTTPHandler(BaseHandler): --- 716,722 ---- hexrep.append(hex(n)[-1]) n = ord(c) & 0xf hexrep.append(hex(n)[-1]) ! return ''.join(hexrep) class HTTPHandler(BaseHandler): *************** *** 768,774 **** """Parse list of key=value strings where keys are not duplicated.""" parsed = {} for elt in l: ! k, v = string.split(elt, '=', 1) if v[0] == '"' and v[-1] == '"': v = v[1:-1] parsed[k] = v --- 767,773 ---- """Parse list of key=value strings where keys are not duplicated.""" parsed = {} for elt in l: ! k, v = elt.split('=', 1) if v[0] == '"' and v[-1] == '"': v = v[1:-1] parsed[k] = v *************** *** 790,797 **** start = 0 while i < end: cur = s[i:] ! c = string.find(cur, ',') ! q = string.find(cur, '"') if c == -1: list.append(s[start:]) break --- 789,796 ---- start = 0 while i < end: cur = s[i:] ! c = cur.find(',') ! q = cur.find('"') if c == -1: list.append(s[start:]) break *************** *** 818,824 **** else: inquote = 1 i = i + q + 1 ! return map(string.strip, list) class FileHandler(BaseHandler): # Use local file or FTP depending on form of URL --- 817,823 ---- else: inquote = 1 i = i + q + 1 ! return map(lambda s: s.strip(), list) class FileHandler(BaseHandler): # Use local file or FTP depending on form of URL *************** *** 865,871 **** port = ftplib.FTP_PORT path, attrs = splitattr(req.get_selector()) path = unquote(path) ! dirs = string.splitfields(path, '/') dirs, file = dirs[:-1], dirs[-1] if dirs and not dirs[0]: dirs = dirs[1:] --- 864,870 ---- port = ftplib.FTP_PORT path, attrs = splitattr(req.get_selector()) path = unquote(path) ! dirs = path.split('/') dirs, file = dirs[:-1], dirs[-1] if dirs and not dirs[0]: dirs = dirs[1:] *************** *** 875,883 **** type = file and 'I' or 'D' for attr in attrs: attr, value = splitattr(attr) ! if string.lower(attr) == 'type' and \ value in ('a', 'A', 'i', 'I', 'd', 'D'): ! type = string.upper(value) fp, retrlen = fw.retrfile(file, type) if retrlen is not None and retrlen >= 0: sf = StringIO('Content-Length: %d\n' % retrlen) --- 874,882 ---- type = file and 'I' or 'D' for attr in attrs: attr, value = splitattr(attr) ! if attr.lower() == 'type' and \ value in ('a', 'A', 'i', 'I', 'd', 'D'): ! type = value.upper() fp, retrlen = fw.retrfile(file, type) if retrlen is not None and retrlen >= 0: sf = StringIO('Content-Length: %d\n' % retrlen) Index: Lib/urlparse.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/urlparse.py,v retrieving revision 1.23 diff -c -r1.23 urlparse.py *** urlparse.py 2000/04/10 17:02:46 1.23 --- urlparse.py 2000/04/11 11:56:54 *************** *** 6,12 **** # Standard/builtin Python modules import string - from string import join, split, rfind # A classification of schemes ('' means apply by default) uses_relative = ['ftp', 'http', 'gopher', 'nntp', 'wais', 'file', --- 6,11 ---- *************** *** 54,82 **** return cached if len(_parse_cache) >= MAX_CACHE_SIZE: # avoid runaway growth clear_cache() - find = string.find netloc = path = params = query = fragment = '' ! i = find(url, ':') if i > 0: if url[:i] == 'http': # optimize the common case ! scheme = string.lower(url[:i]) url = url[i+1:] if url[:2] == '//': ! i = find(url, '/', 2) if i < 0: i = len(url) netloc = url[2:i] url = url[i:] if allow_fragments: ! i = string.rfind(url, '#') if i >= 0: fragment = url[i+1:] url = url[:i] ! i = find(url, '?') if i >= 0: query = url[i+1:] url = url[:i] ! i = find(url, ';') if i >= 0: params = url[i+1:] url = url[:i] --- 53,80 ---- return cached if len(_parse_cache) >= MAX_CACHE_SIZE: # avoid runaway growth clear_cache() netloc = path = params = query = fragment = '' ! i = url.find(':') if i > 0: if url[:i] == 'http': # optimize the common case ! scheme = url[:i].lower() url = url[i+1:] if url[:2] == '//': ! i = url.find('/', 2) if i < 0: i = len(url) netloc = url[2:i] url = url[i:] if allow_fragments: ! i = url.rfind('#') if i >= 0: fragment = url[i+1:] url = url[:i] ! i = url.find('?') if i >= 0: query = url[i+1:] url = url[:i] ! i = url.find(';') if i >= 0: params = url[i+1:] url = url[:i] *************** *** 87,109 **** if c not in scheme_chars: break else: ! scheme, url = string.lower(url[:i]), url[i+1:] if scheme in uses_netloc: if url[:2] == '//': ! i = find(url, '/', 2) if i < 0: i = len(url) netloc, url = url[2:i], url[i:] if allow_fragments and scheme in uses_fragment: ! i = string.rfind(url, '#') if i >= 0: url, fragment = url[:i], url[i+1:] if scheme in uses_query: ! i = find(url, '?') if i >= 0: url, query = url[:i], url[i+1:] if scheme in uses_params: ! i = find(url, ';') if i >= 0: url, params = url[:i], url[i+1:] tuple = scheme, netloc, url, params, query, fragment --- 85,107 ---- if c not in scheme_chars: break else: ! scheme, url = url[:i].lower(), url[i+1:] if scheme in uses_netloc: if url[:2] == '//': ! i = url.find('/', 2) if i < 0: i = len(url) netloc, url = url[2:i], url[i:] if allow_fragments and scheme in uses_fragment: ! i = url.rfind('#') if i >= 0: url, fragment = url[:i], url[i+1:] if scheme in uses_query: ! i = url.find('?') if i >= 0: url, query = url[:i], url[i+1:] if scheme in uses_params: ! i = url.find(';') if i >= 0: url, params = url[:i], url[i+1:] tuple = scheme, netloc, url, params, query, fragment *************** *** 151,157 **** if not path: return urlunparse((scheme, netloc, bpath, params, query or bquery, fragment)) ! segments = split(bpath, '/')[:-1] + split(path, '/') # XXX The stuff below is bogus in various ways... if segments[-1] == '.': segments[-1] = '' --- 149,155 ---- if not path: return urlunparse((scheme, netloc, bpath, params, query or bquery, fragment)) ! segments = bpath.split('/')[:-1] + path.split('/') # XXX The stuff below is bogus in various ways... if segments[-1] == '.': segments[-1] = '' *************** *** 171,177 **** segments[-1] = '' elif len(segments) >= 2 and segments[-1] == '..': segments[-2:] = [''] ! return urlunparse((scheme, netloc, join(segments, '/'), params, query, fragment)) def urldefrag(url): --- 169,175 ---- segments[-1] = '' elif len(segments) >= 2 and segments[-1] == '..': segments[-2:] = [''] ! return urlunparse((scheme, netloc, '/'.join(segments), params, query, fragment)) def urldefrag(url): *************** *** 236,242 **** while 1: line = fp.readline() if not line: break ! words = string.split(line) if not words: continue url = words[0] --- 234,240 ---- while 1: line = fp.readline() if not line: break ! words = line.split() if not words: continue url = words[0] Index: Lib/uu.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/uu.py,v retrieving revision 1.11 diff -c -r1.11 uu.py *** uu.py 2000/02/04 15:28:42 1.11 --- uu.py 2000/04/11 11:56:54 *************** *** 32,38 **** import binascii import os - import string import sys Error = 'uu.Error' --- 32,37 ---- *************** *** 96,112 **** raise Error, 'No valid begin line found in input file' if hdr[:5] != 'begin': continue ! hdrfields = string.split(hdr) if len(hdrfields) == 3 and hdrfields[0] == 'begin': try: ! string.atoi(hdrfields[1], 8) break except ValueError: pass if out_file == None: out_file = hdrfields[2] if mode == None: ! mode = string.atoi(hdrfields[1], 8) # # Open the output file # --- 95,111 ---- raise Error, 'No valid begin line found in input file' if hdr[:5] != 'begin': continue ! hdrfields = hdr.split() if len(hdrfields) == 3 and hdrfields[0] == 'begin': try: ! int(hdrfields[1], 8) break except ValueError: pass if out_file == None: out_file = hdrfields[2] if mode == None: ! mode = int(hdrfields[1], 8) # # Open the output file # Index: Lib/xmllib.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/xmllib.py,v retrieving revision 1.17 diff -c -r1.17 xmllib.py *** xmllib.py 2000/02/04 15:39:30 1.17 --- xmllib.py 2000/04/11 11:56:55 *************** *** 190,198 **** post = data[i:] if str[0] == '#': if str[1] == 'x': ! str = chr(string.atoi(str[2:], 16)) else: ! str = chr(string.atoi(str[1:])) data = pre + str + post i = res.start(0)+len(str) elif all: --- 190,198 ---- post = data[i:] if str[0] == '#': if str[1] == 'x': ! str = chr(int(str[2:], 16)) else: ! str = chr(int(str[1:])) data = pre + str + post i = res.start(0)+len(str) elif all: *************** *** 221,227 **** if self.nomoretags: data = rawdata[i:n] self.handle_data(data) ! self.lineno = self.lineno + string.count(data, '\n') i = n break res = interesting.search(rawdata, i) --- 221,227 ---- if self.nomoretags: data = rawdata[i:n] self.handle_data(data) ! self.lineno = self.lineno + data.count('\n') i = n break res = interesting.search(rawdata, i) *************** *** 239,245 **** if not self.__accept_utf8 and illegal.search(data): self.syntax_error('illegal character in content') self.handle_data(data) ! self.lineno = self.lineno + string.count(data, '\n') i = j if i == n: break if rawdata[i] == '<': --- 239,245 ---- if not self.__accept_utf8 and illegal.search(data): self.syntax_error('illegal character in content') self.handle_data(data) ! self.lineno = self.lineno + data.count('\n') i = j if i == n: break if rawdata[i] == '<': *************** *** 247,283 **** if self.literal: data = rawdata[i] self.handle_data(data) ! self.lineno = self.lineno + string.count(data, '\n') i = i+1 continue k = self.parse_starttag(i) if k < 0: break self.__seen_starttag = 1 ! self.lineno = self.lineno + string.count(rawdata[i:k], '\n') i = k continue if endtagopen.match(rawdata, i): k = self.parse_endtag(i) if k < 0: break ! self.lineno = self.lineno + string.count(rawdata[i:k], '\n') i = k continue if commentopen.match(rawdata, i): if self.literal: data = rawdata[i] self.handle_data(data) ! self.lineno = self.lineno + string.count(data, '\n') i = i+1 continue k = self.parse_comment(i) if k < 0: break ! self.lineno = self.lineno + string.count(rawdata[i:k], '\n') i = k continue if cdataopen.match(rawdata, i): k = self.parse_cdata(i) if k < 0: break ! self.lineno = self.lineno + string.count(rawdata[i:i], '\n') i = k continue res = xmldecl.match(rawdata, i) --- 247,283 ---- if self.literal: data = rawdata[i] self.handle_data(data) ! self.lineno = self.lineno + data.count('\n') i = i+1 continue k = self.parse_starttag(i) if k < 0: break self.__seen_starttag = 1 ! self.lineno = self.lineno + rawdata[i:k].count('\n') i = k continue if endtagopen.match(rawdata, i): k = self.parse_endtag(i) if k < 0: break ! self.lineno = self.lineno + rawdata[i:k].count('\n') i = k continue if commentopen.match(rawdata, i): if self.literal: data = rawdata[i] self.handle_data(data) ! self.lineno = self.lineno + data.count('\n') i = i+1 continue k = self.parse_comment(i) if k < 0: break ! self.lineno = self.lineno + rawdata[i:k].count('\n') i = k continue if cdataopen.match(rawdata, i): k = self.parse_cdata(i) if k < 0: break ! self.lineno = self.lineno + rawdata[i:i].count('\n') i = k continue res = xmldecl.match(rawdata, i) *************** *** 298,304 **** if res: k = self.parse_proc(i) if k < 0: break ! self.lineno = self.lineno + string.count(rawdata[i:k], '\n') i = k continue res = doctype.match(rawdata, i) --- 298,304 ---- if res: k = self.parse_proc(i) if k < 0: break ! self.lineno = self.lineno + rawdata[i:k].count('\n') i = k continue res = doctype.match(rawdata, i) *************** *** 306,312 **** if self.literal: data = rawdata[i] self.handle_data(data) ! self.lineno = self.lineno + string.count(data, '\n') i = i+1 continue if self.__seen_doctype: --- 306,312 ---- if self.literal: data = rawdata[i] self.handle_data(data) ! self.lineno = self.lineno + data.count('\n') i = i+1 continue if self.__seen_doctype: *************** *** 317,324 **** if k < 0: break self.__seen_doctype = res.group('name') if self.__map_case: ! self.__seen_doctype = string.lower(self.__seen_doctype) ! self.lineno = self.lineno + string.count(rawdata[i:k], '\n') i = k continue elif rawdata[i] == '&': --- 317,324 ---- if k < 0: break self.__seen_doctype = res.group('name') if self.__map_case: ! self.__seen_doctype = self.__seen_doctype.lower() ! self.lineno = self.lineno + rawdata[i:k].count('\n') i = k continue elif rawdata[i] == '&': *************** *** 336,342 **** if not self.stack: self.syntax_error('data not in content') self.handle_charref(res.group('char')[:-1]) ! self.lineno = self.lineno + string.count(res.group(0), '\n') continue res = entityref.match(rawdata, i) if res is not None: --- 336,342 ---- if not self.stack: self.syntax_error('data not in content') self.handle_charref(res.group('char')[:-1]) ! self.lineno = self.lineno + res.group(0).count('\n') continue res = entityref.match(rawdata, i) if res is not None: *************** *** 346,359 **** i = i-1 name = res.group('name') if self.__map_case: ! name = string.lower(name) if self.entitydefs.has_key(name): self.rawdata = rawdata = rawdata[:res.start(0)] + self.entitydefs[name] + rawdata[i:] n = len(rawdata) i = res.start(0) else: self.unknown_entityref(name) ! self.lineno = self.lineno + string.count(res.group(0), '\n') continue elif rawdata[i] == ']': if self.literal: --- 346,359 ---- i = i-1 name = res.group('name') if self.__map_case: ! name = name.lower() if self.entitydefs.has_key(name): self.rawdata = rawdata = rawdata[:res.start(0)] + self.entitydefs[name] + rawdata[i:] n = len(rawdata) i = res.start(0) else: self.unknown_entityref(name) ! self.lineno = self.lineno + res.group(0).count('\n') continue elif rawdata[i] == ']': if self.literal: *************** *** 382,388 **** if not self.__accept_utf8 and illegal.search(data): self.syntax_error('illegal character in content') self.handle_data(data) ! self.lineno = self.lineno + string.count(data, '\n') self.rawdata = rawdata[i+1:] return self.goahead(end) self.rawdata = rawdata[i:] --- 382,388 ---- if not self.__accept_utf8 and illegal.search(data): self.syntax_error('illegal character in content') self.handle_data(data) ! self.lineno = self.lineno + data.count('\n') self.rawdata = rawdata[i+1:] return self.goahead(end) self.rawdata = rawdata[i:] *************** *** 418,428 **** n = len(rawdata) name = res.group('name') if self.__map_case: ! name = string.lower(name) pubid, syslit = res.group('pubid', 'syslit') if pubid is not None: pubid = pubid[1:-1] # remove quotes ! pubid = string.join(string.split(pubid)) # normalize if syslit is not None: syslit = syslit[1:-1] # remove quotes j = k = res.end(0) if k >= n: --- 418,428 ---- n = len(rawdata) name = res.group('name') if self.__map_case: ! name = name.lower() pubid, syslit = res.group('pubid', 'syslit') if pubid is not None: pubid = pubid[1:-1] # remove quotes ! pubid = ' '.join(pubid.split()) # normalize if syslit is not None: syslit = syslit[1:-1] # remove quotes j = k = res.end(0) if k >= n: *************** *** 492,498 **** k = res.end(0) name = res.group(0) if self.__map_case: ! name = string.lower(name) if name == 'xml:namespace': self.syntax_error('old-fashioned namespace declaration') self.__use_namespaces = -1 --- 492,498 ---- k = res.end(0) name = res.group(0) if self.__map_case: ! name = name.lower() if name == 'xml:namespace': self.syntax_error('old-fashioned namespace declaration') self.__use_namespaces = -1 *************** *** 517,523 **** self.syntax_error('xml:namespace prefix not unique') self.__namespaces[prefix] = attrdict['ns'] else: ! if string.lower(name) == 'xml': self.syntax_error('illegal processing instruction target name') self.handle_proc(name, rawdata[k:j]) return end.end(0) --- 517,523 ---- self.syntax_error('xml:namespace prefix not unique') self.__namespaces[prefix] = attrdict['ns'] else: ! if name.lower() == 'xml': self.syntax_error('illegal processing instruction target name') self.handle_proc(name, rawdata[k:j]) return end.end(0) *************** *** 533,539 **** break attrname, attrvalue = res.group('name', 'value') if self.__map_case: ! attrname = string.lower(attrname) i = res.end(0) if attrvalue is None: self.syntax_error("no value specified for attribute `%s'" % attrname) --- 533,539 ---- break attrname, attrvalue = res.group('name', 'value') if self.__map_case: ! attrname = attrname.lower() i = res.end(0) if attrvalue is None: self.syntax_error("no value specified for attribute `%s'" % attrname) *************** *** 555,561 **** self.syntax_error("`<' illegal in attribute value") if attrdict.has_key(attrname): self.syntax_error("attribute `%s' specified twice" % attrname) ! attrvalue = string.translate(attrvalue, attrtrans) attrdict[attrname] = self.translate_references(attrvalue) return attrdict, namespace, i --- 555,561 ---- self.syntax_error("`<' illegal in attribute value") if attrdict.has_key(attrname): self.syntax_error("attribute `%s' specified twice" % attrname) ! attrvalue = attrvalue.translate(attrtrans) attrdict[attrname] = self.translate_references(attrvalue) return attrdict, namespace, i *************** *** 572,578 **** return end.end(0) nstag = tagname = tag.group('tagname') if self.__map_case: ! nstag = tagname = string.lower(nstag) if not self.__seen_starttag and self.__seen_doctype and \ tagname != self.__seen_doctype: self.syntax_error('starttag does not match DOCTYPE') --- 572,578 ---- return end.end(0) nstag = tagname = tag.group('tagname') if self.__map_case: ! nstag = tagname = nstag.lower() if not self.__seen_starttag and self.__seen_doctype and \ tagname != self.__seen_doctype: self.syntax_error('starttag does not match DOCTYPE') *************** *** 608,614 **** if res is not None: aprefix, key = res.group('prefix', 'local') if self.__map_case: ! key = string.lower(key) if aprefix is None: aprefix = '' ans = None --- 608,614 ---- if res is not None: aprefix, key = res.group('prefix', 'local') if self.__map_case: ! key = key.lower() if aprefix is None: aprefix = '' ans = None *************** *** 657,663 **** else: tag = res.group(0) if self.__map_case: ! tag = string.lower(tag) if self.literal: if not self.stack or tag != self.stack[-1][0]: self.handle_data(rawdata[i]) --- 657,663 ---- else: tag = res.group(0) if self.__map_case: ! tag = tag.lower() if self.literal: if not self.stack or tag != self.stack[-1][0]: self.handle_data(rawdata[i]) *************** *** 730,739 **** def handle_charref(self, name): try: if name[0] == 'x': ! n = string.atoi(name[1:], 16) else: ! n = string.atoi(name) ! except string.atoi_error: self.unknown_charref(name) return if not 0 <= n <= 255: --- 730,739 ---- def handle_charref(self, name): try: if name[0] == 'x': ! n = int(name[1:], 16) else: ! n = int(name) ! except ValueError: self.unknown_charref(name) return if not 0 <= n <= 255: From skip@mojam.com (Skip Montanaro) Tue Apr 11 13:21:59 2000 From: skip@mojam.com (Skip Montanaro) (Skip Montanaro) Date: Tue, 11 Apr 2000 07:21:59 -0500 (CDT) Subject: [Patches] Please review before applying In-Reply-To: <200004111225.OAA31234@localhost.localdomain> References: <200004111225.OAA31234@localhost.localdomain> Message-ID: <14579.6375.601339.630742@beluga.mojam.com> From the changes to Lib/BaseHTTPServer.py: Fred> # The Python system version, truncated to its first component. Fred> ! sys_version = "Python/" + sys.version.split[0] The change here should be to sys.version.split()[0] This suggests to me that the BaseHTTPRequestHandler class isn't tested by 'make test'. -- Skip Montanaro | http://www.mojam.com/ skip@mojam.com | http://www.musi-cal.com/ From akuchlin@mems-exchange.org Tue Apr 11 14:50:45 2000 From: akuchlin@mems-exchange.org (Andrew M. Kuchling) Date: Tue, 11 Apr 2000 09:50:45 -0400 (EDT) Subject: [Patches] add string precisions to PyErr_Format calls In-Reply-To: References: <14577.47506.14149.790979@beluga.mojam.com> Message-ID: <14579.11701.733010.789688@amarok.cnri.reston.va.us> Greg Stein writes: >Wouldn't it be best to simply fix PyErr_Format so that we don't have to >continue to worry about buffer overruns? A while ago I suggested using nsprintf() in PyErr_Format, but that means stealing the implementation from Apache for those platforms where libc doesn't include nsprintf(). Haven't done it yet... --amk From gward@mems-exchange.org Tue Apr 11 17:52:37 2000 From: gward@mems-exchange.org (Greg Ward) Date: Tue, 11 Apr 2000 12:52:37 -0400 Subject: [Patches] fileinput.py argument handling (and suggestion) In-Reply-To: ; from moshez@math.huji.ac.il on Tue, Apr 11, 2000 at 08:43:56AM +0200 References: <20000410151626.A1168@mems-exchange.org> Message-ID: <20000411125236.A1539@mems-exchange.org> On 11 April 2000, Moshe Zadka said: > I really like the text_file.py. Can't it just be in the standard library > and have a__getitem__ method (or is there one already? I only looked at > the doc you sent). This will at least solve the FAQ about reading a file > line-by-line in a nice way. No, there's no __getitem__. I guess I could add one along the lines of FileInput's; I didn't know about that class when I wrote my TextFile class, and the idea of a strictly sequential __getitem__ didn't occur to me independently. The other problem, which I blithely assume is a problem with both the standard FileInput and my TextFile, is performance. Sometimes, you just want to loop over all lines in a text file as quickly as possible, doing something with each line. Personally, I do those tasks using a well-known and popular scripting language that was carefully optimized for that very task. Others in the Python community have expressed distaste for that particular language, but the fact remains that P**l's facilities for looping-over-all-lines-in-a-text-file-quickly are much better than Python's. You can write lovely high-level classes that provide the same functionality as Perl's bag o' tricks, but the performance will, presumably, stink. [...considerable time passes...] OK, I got curious: how bad *is* the performance of Python's regular file input, the FileInput class, and my TextFile class? My test data is the entire Python 1.5.2 standard library, i.e. all 344 *.py files under $prefix/lib/python1.5 (hmm, I guess that includes whatever I happen to have in site-packages right now -- whatever). The basic tasks are: 1. read every line and discard it 2. read all lines in one fell swoop and discard them 3. read every line, stripping comments and whitespace and ignoring blanks... and then discard what's left (ie. we only exercise detecting blank lines) I implemented each basic task in the most obvious and straightforward way with Perl, and implemented task 1 and 3 in a couple of different ways with Python. Here are the results: Script CPU time Elapsed readfile1.pl (4 LoC) 0.27 0.44 "1 while " readfile1.py 6 3.72 4.37 "while 1: readline()" readfile1a.py 4 7.34 8.24 FileInput (one per file) readfile1b.py 3 7.20 8.07 FileInput (one for whole list) readfile1c.py 5 8.50 9.53 TextFile (all options off) readfile2.pl 4 LoC 0.45 0.63 "@lines = " readfile2a.pl 1 0.44 0.73 "@all_lines = <>" readfile2.py 4 0.51 1.11 "lines = readlines()" readfile3.pl 8 LoC 1.01 1.28 chomp, regex tricks to trim readfile3.py 13 7.30 8.10 string.find, string.rstrip readfile3a.py 6 11.09 12.24 TextFile (default options) (Lines-of-code excludes comments, blanks, curly braces, and imports.) Conclusion: FileInput and TextFile are indeed dogs, but TextFile isn't enormously worse than FileInput when it's not doing any input-munging. TextFile is considerably slower than rolling your own munge-every-line code every time. The fastest way to read a file in Python is with ".readlines()"; surprisingly, in Perl it's to read lines individually. Does anybody care? I do -- the reason I wrote TextFile was to process a file that is currently ~450k (~20,000 lines); it currently takes ~30 sec to process using CPython. After this little benchmarking session, I'm starting to wonder if there's a better way. (What?!? Write a C extension to read a text file??! ;-) Greg -- Greg Ward - software developer gward@mems-exchange.org MEMS Exchange / CNRI voice: +1-703-262-5376 Reston, Virginia, USA fax: +1-703-262-5367 From guido@python.org Tue Apr 11 18:31:50 2000 From: guido@python.org (Guido van Rossum) Date: Tue, 11 Apr 2000 13:31:50 -0400 Subject: [Patches] Please review before applying In-Reply-To: Your message of "Tue, 11 Apr 2000 14:25:36 +0200." <200004111225.OAA31234@localhost.localdomain> References: <200004111225.OAA31234@localhost.localdomain> Message-ID: <200004111731.NAA09194@eric.cnri.reston.va.us> > Most of the changes are simple translations, i.e.: > > string.split (s, sep) --> s.split (sep) > > Some of the changes also take the context into account, see: > - cgi.py > - formatter.py > - imaplib.py > > Both 'make test' and 'Lib/compileall.py Lib' produced no error-output > so I'd expect no big problems. > > The following migt go into the csv-log: > ________________________________________________________________________ > This (mega-)patch updates all the modules in the standard-module (all > Lib/*.py files) to use the new string-methods instead of the old string > module. Thanks, Fred! I don't have time to review this before 1.6a2 goes out, but there will be a third alpha (at least) and some betas. I hope others will review parts of your patch! One concern: Greg Ward is trying to keep distutils compatible with Python 1.5.1. So those files should not be touched. I'm not sure if there are similar concerns elsewhere... --Guido van Rossum (home page: http://www.python.org/~guido/) From bwarsaw@python.org Tue Apr 11 23:31:32 2000 From: bwarsaw@python.org (Barry Warsaw) Date: Tue, 11 Apr 2000 18:31:32 -0400 (EDT) Subject: [Patches] posixmodule.c memory leak patch Message-ID: <14579.42948.116873.135215@anthem.cnri.reston.va.us> In the process of mem checking my funcattrs patches, I ran across a memory leak in setup_confname_table() in posixmodule.c. The cause is clear: PyDict_SetItemString() borrows ownership of the value object (i.e. it INCREFs it whether it succeeds or not). Thus both the individual int objects and the conf dictionary are all leaked. This patch fixes the memory leak (according to Purify) and simplifies the logic in the meantime. BTW, Purify reports a bunch of other memory problems which should be nailed before 1.6 final goes out. I'll see what I can do about whacking them. -Barry -------------------- snip snip -------------------- Index: posixmodule.c =================================================================== RCS file: /projects/cvsroot/python/dist/src/Modules/posixmodule.c,v retrieving revision 2.129 diff -c -r2.129 posixmodule.c *** posixmodule.c 2000/03/31 01:26:23 2.129 --- posixmodule.c 2000/04/11 22:21:57 *************** *** 4325,4351 **** PyObject *moddict; { PyObject *d = NULL; qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs); d = PyDict_New(); ! if (d != NULL) { ! PyObject *o; ! size_t i = 0; ! for (; i < tablesize; ++i) { ! o = PyInt_FromLong(table[i].value); ! if (o == NULL ! || PyDict_SetItemString(d, table[i].name, o) == -1) { ! Py_DECREF(d); ! d = NULL; ! return -1; } ! } ! if (PyDict_SetItemString(moddict, tablename, d) == -1) ! return -1; ! return 0; } ! return -1; } /* Return -1 on failure, 0 on success. */ --- 4325,4350 ---- PyObject *moddict; { PyObject *d = NULL; + size_t i; + int status; qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs); d = PyDict_New(); ! if (d == NULL) ! return -1; ! for (i=0; i < tablesize; ++i) { ! PyObject *o = PyInt_FromLong(table[i].value); ! if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) { ! Py_XDECREF(o); ! Py_DECREF(d); ! return -1; } ! Py_DECREF(o); } ! status = PyDict_SetItemString(moddict, tablename, d); ! Py_DECREF(d); ! return status; } /* Return -1 on failure, 0 on success. */ From bwarsaw@cnri.reston.va.us Wed Apr 12 00:22:14 2000 From: bwarsaw@cnri.reston.va.us (Barry A. Warsaw) Date: Tue, 11 Apr 2000 19:22:14 -0400 (EDT) Subject: [Patches] Second round: arbitrary function and method attributes Message-ID: <14579.45990.603625.434317@anthem.cnri.reston.va.us> --HXjrLbAr5v Content-Type: text/plain; charset=us-ascii Content-Description: message body text Content-Transfer-Encoding: 7bit Here's the second go at adding arbitrary attribute support to function and method objects. Note that this time it's illegal (TypeError) to set an attribute on a bound method object; getting an attribute on a bound method object returns the value on the underlying function object. First the diffs, then the test case and test output. Enjoy, -Barry --HXjrLbAr5v Content-Type: text/plain Content-Description: Diff -u to add arbitrary attrs to funcs and meths Content-Disposition: inline; filename="methdiff.txt" Content-Transfer-Encoding: 7bit Index: Include/funcobject.h =================================================================== RCS file: /projects/cvsroot/python/dist/src/Include/funcobject.h,v retrieving revision 2.16 diff -u -r2.16 funcobject.h --- funcobject.h 1998/12/04 18:48:02 2.16 +++ funcobject.h 2000/04/07 21:30:40 @@ -44,6 +44,7 @@ PyObject *func_defaults; PyObject *func_doc; PyObject *func_name; + PyObject *func_dict; } PyFunctionObject; extern DL_IMPORT(PyTypeObject) PyFunction_Type; Index: Objects/classobject.c =================================================================== RCS file: /projects/cvsroot/python/dist/src/Objects/classobject.c,v retrieving revision 2.84 diff -u -r2.84 classobject.c --- classobject.c 2000/04/10 13:03:19 2.84 +++ classobject.c 2000/04/11 22:05:08 @@ -1550,28 +1550,75 @@ /* Dummies that are not handled by getattr() except for __members__ */ {"__doc__", T_INT, 0}, {"__name__", T_INT, 0}, + {"__dict__", T_INT, 0}, {NULL} /* Sentinel */ }; +static int +instancemethod_setattro(im, name, v) + register PyMethodObject *im; + PyObject *name; + PyObject *v; +{ + char* sname = PyString_AsString(name); + if (sname == NULL) + return -1; + + if (PyEval_GetRestricted() || + strcmp(sname, "im_func") == 0 || + strcmp(sname, "im_self") == 0 || + strcmp(sname, "im_class") == 0) + { + PyErr_Format(PyExc_TypeError, "read-only attribute: %s", sname); + return -1; + } + if (im->im_self != NULL) { + PyErr_Format(PyExc_TypeError, + "cannot set bound instance-method attribute: %s", + sname); + return -1; + } + return PyObject_SetAttr(im->im_func, name, v); +} + + static PyObject * -instancemethod_getattr(im, name) +instancemethod_getattro(im, name) register PyMethodObject *im; PyObject *name; { - char *sname = PyString_AsString(name); + PyObject *rtn; + char* sname = PyString_AsString(name); + + if (sname == NULL) + return NULL; + if (sname[0] == '_') { /* Inherit __name__ and __doc__ from the callable object - implementing the method */ - if (strcmp(sname, "__name__") == 0 || - strcmp(sname, "__doc__") == 0) + implementing the method. Can't allow access to __dict__ + here because it should not be readable in restricted + execution mode. + */ + if (strcmp(sname, "__name__") == 0 || + strcmp(sname, "__doc__") == 0) { return PyObject_GetAttr(im->im_func, name); + } } if (PyEval_GetRestricted()) { - PyErr_SetString(PyExc_RuntimeError, - "instance-method attributes not accessible in restricted mode"); + PyErr_Format(PyExc_RuntimeError, + "instance-method attributes not accessible in restricted mode: %s", + sname); return NULL; + } + if (sname[0] == '_' && strcmp(sname, "__dict__") == 0) + return PyObject_GetAttr(im->im_func, name); + + rtn = PyMember_Get((char *)im, instancemethod_memberlist, sname); + if (rtn == NULL) { + PyErr_Clear(); + rtn = PyObject_GetAttr(im->im_func, name); } - return PyMember_Get((char *)im, instancemethod_memberlist, sname); + return rtn; } static void @@ -1672,8 +1719,8 @@ (hashfunc)instancemethod_hash, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ - (getattrofunc)instancemethod_getattr, /*tp_getattro*/ - 0, /*tp_setattro*/ + (getattrofunc)instancemethod_getattro, /*tp_getattro*/ + (setattrofunc)instancemethod_setattro, /*tp_setattro*/ }; /* Clear out the free list */ Index: Objects/funcobject.c =================================================================== RCS file: /projects/cvsroot/python/dist/src/Objects/funcobject.c,v retrieving revision 2.18 diff -u -r2.18 funcobject.c --- funcobject.c 1998/05/22 00:55:34 2.18 +++ funcobject.c 2000/04/11 22:06:12 @@ -62,6 +62,7 @@ doc = Py_None; Py_INCREF(doc); op->func_doc = doc; + op->func_dict = PyDict_New(); } return (PyObject *)op; } @@ -133,6 +134,8 @@ {"__name__", T_OBJECT, OFF(func_name), READONLY}, {"func_defaults",T_OBJECT, OFF(func_defaults)}, {"func_doc", T_OBJECT, OFF(func_doc)}, + {"func_dict", T_OBJECT, OFF(func_dict)}, + {"__dict__", T_OBJECT, OFF(func_dict)}, {"__doc__", T_OBJECT, OFF(func_doc)}, {NULL} /* Sentinel */ }; @@ -142,12 +145,21 @@ PyFunctionObject *op; char *name; { + PyObject* rtn; + if (name[0] != '_' && PyEval_GetRestricted()) { PyErr_SetString(PyExc_RuntimeError, "function attributes not accessible in restricted mode"); return NULL; + } + rtn = PyMember_Get((char *)op, func_memberlist, name); + if (rtn == NULL) { + PyErr_Clear(); + rtn = PyMapping_GetItemString(op->func_dict, name); + if (rtn == NULL) + PyErr_SetString(PyExc_AttributeError, name); } - return PyMember_Get((char *)op, func_memberlist, name); + return rtn; } static int @@ -156,6 +168,8 @@ char *name; PyObject *value; { + int rtn; + if (PyEval_GetRestricted()) { PyErr_SetString(PyExc_RuntimeError, "function attributes not settable in restricted mode"); @@ -178,8 +192,23 @@ } if (value == Py_None) value = NULL; + } + else if (strcmp(name, "func_dict") == 0 || + strcmp(name, "__dict__") == 0) + { + if (value == NULL || !PyMapping_Check(value)) { + PyErr_SetString( + PyExc_TypeError, + "must set func_dict to a mapping object"); + return -1; + } + } + rtn = PyMember_Set((char *)op, func_memberlist, name, value); + if (rtn < 0) { + PyErr_Clear(); + rtn = PyMapping_SetItemString(op->func_dict, name, value); } - return PyMember_Set((char *)op, func_memberlist, name, value); + return rtn; } static void @@ -191,6 +220,7 @@ Py_DECREF(op->func_name); Py_XDECREF(op->func_defaults); Py_XDECREF(op->func_doc); + Py_XDECREF(op->func_dict); PyMem_DEL(op); } --HXjrLbAr5v Content-Type: text/plain Content-Description: Test of func/meth attrs Content-Disposition: inline; filename="test_funcattrs.py" Content-Transfer-Encoding: 7bit from test_support import verbose class F: def a(self): pass def b(): pass # setting attributes on functions try: b.blah except AttributeError: pass else: print 'did not get expected AttributeError' b.blah = 1 print b.blah == 1 print 'blah' in dir(b) # setting attributes on unbound methods try: F.a.blah except AttributeError: pass else: print 'did not get expected AttributeError' F.a.blah = 1 print F.a.blah == 1 print 'blah' in dir(F.a) # setting attributes on bound methods is illegal f1 = F() try: f1.a.snerp = 1 except TypeError: pass else: print 'did not get expected TypeError' # but accessing attributes on bound methods is fine print f1.a.blah print 'blah' in dir(f1.a) f2 = F() print f1.a.blah == f2.a.blah F.a.wazoo = F f1.a.wazoo is f2.a.wazoo # try setting __dict__ illegally try: F.a.__dict__ = (1, 2, 3) except TypeError: pass else: print 'did not get expected TypeError' F.a.__dict__ = {'one': 111, 'two': 222, 'three': 333} print f1.a.two == 222 from UserDict import UserDict d = UserDict({'four': 444, 'five': 555}) F.a.__dict__ = d try: f2.a.two except AttributeError: pass else: print 'did not get expected AttributeError' print f2.a.four is f1.a.four is F.a.four --HXjrLbAr5v Content-Type: text/plain Content-Description: Output of test of func/meth attrs Content-Disposition: inline; filename="test_funcattrs" Content-Transfer-Encoding: 7bit test_funcattrs 1 1 1 1 1 1 1 1 1 --HXjrLbAr5v-- From Vladimir.Marangozov@inrialpes.fr Wed Apr 12 05:22:09 2000 From: Vladimir.Marangozov@inrialpes.fr (Vladimir Marangozov) Date: Wed, 12 Apr 2000 06:22:09 +0200 (CEST) Subject: [Patches] regression test finalization Message-ID: <200004120422.GAA06916@python.inrialpes.fr> Feature-specific modules keep being imported until the end of the test suite. This increases unnecessarily the overall memory consumption. This patch suggests a best effort per-test finalization by unloading the newly imported modules after every test. If not convinced in the usefulness of the patch, I can provide figures. -- Vladimir MARANGOZOV | Vladimir.Marangozov@inrialpes.fr http://sirac.inrialpes.fr/~marangoz | tel:(+33-4)76615277 fax:76615252 -- I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. -------------------------------[ cut here ]--------------------------- *** Lib/test/regrtest.py-orig Wed Apr 12 06:09:22 2000 --- Lib/test/regrtest.py Wed Apr 12 06:08:38 2000 *************** *** 105,110 **** --- 105,111 ---- if single: tests = tests[:1] test_support.verbose = verbose # Tell tests to be moderately quiet + save_modules = sys.modules.keys() for test in tests: if not quiet: print test *************** *** 118,123 **** --- 119,128 ---- print "test", test, print "skipped -- an optional feature could not be imported" skipped.append(test) + # Unload the newly imported modules (best effort finalization) + for module in sys.modules.keys(): + if module not in save_modules: + test_support.unload(module) if good and not quiet: if not bad and not skipped and len(good) > 1: print "All", From hniksic@iskon.hr Wed Apr 12 08:18:50 2000 From: hniksic@iskon.hr (Hrvoje Niksic) Date: 12 Apr 2000 09:18:50 +0200 Subject: [Patches] Re: Fix for readline() method of mmap objects In-Reply-To: Hrvoje Niksic's message of "04 Apr 2000 20:11:32 +0200" References: Message-ID: Hi! Has the readline() fix been applied? I've received no response to my email, nor can I find anything at the patch list archives. From bwarsaw@cnri.reston.va.us Wed Apr 12 18:24:39 2000 From: bwarsaw@cnri.reston.va.us (Barry A. Warsaw) Date: Wed, 12 Apr 2000 13:24:39 -0400 (EDT) Subject: [Patches] posixmodule.c memory leak patch References: <14579.42948.116873.135215@anthem.cnri.reston.va.us> Message-ID: <14580.45399.505489.166542@anthem.cnri.reston.va.us> >>>>> "BW" == Barry Warsaw writes: BW> BTW, Purify reports a bunch of other memory problems which BW> should be nailed before 1.6 final goes out. I'll see what I BW> can do about whacking them. On further inspection, most of those are in system libraries, or in pcre. Nothing I can do about the former, and given sre, I'm not going to worry about the latter. -Barry From mhammond@skippinet.com.au Thu Apr 13 03:23:43 2000 From: mhammond@skippinet.com.au (Mark Hammond) Date: Thu, 13 Apr 2000 12:23:43 +1000 Subject: [Patches] Patches to build process for Windows Message-ID: Attached are minor build-process changes for Windows. Notable changes are: * Temp directory for all projects are now specific to the project (rather than common as before). This avoids any conflicts with debug symbols or common file names etc. NOTE: You should manually delete your existing build directory after applying this patch, as the MSVC "clean" command will now only clean the new temporary directories - not the existing common temp directory. * Base address for all extension modules updated. PC\dllbase_nt.txt also updated. Erroneous "libpath" directory removed for all projects. * winsound module moved from a builtin module to an extension module. This was done primarily to avoid Python16.dll needing to pull in winmm.dll. Really dumb test added for winsound - but if nothing else it ensures the module imports. * PCbuild\.cvsignore updated to hide more junk! Ive attached everything as complete files, rather than diffs (most of them are either new files, or modified binary files) Release info: I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. Mark. begin 666 win32_build_patches.zip M4$L#!!0``@`(`"E?C2AC)S `5 4``%,@```1````4$-B=6EL9"]B\>/Q,X+"&3A`Q45\SQS[IWA''O\$3K<](0OQ@%H[)99PF4>Z$%(N8"^ M)_YE9@`-;C$X@2ZQ644Q?$H-!:M]8L[(A$'OSF%>Y<]O?QT??=R%UF0XC@2, MPF7(+1JA?H6&\&P2P"_F^5PX<%XH%B7.ER^@]:#;&T)=:PVQ>GPDFX?507/X MNU\'Y9H[9R7X=']Q_AFTN4-L;IZTN3.#-C<\XLT5*-X73XNEC;.J[?Z/ZHYY MYW+>\5&MT:Q$X6*T\;=1A.N0_XXX@`"-P2BU.P MR8R-,<("# 484<"!'.8F.0U][DR@VZG^K'_-0(4^PW$,ZO>N\ +H)"A@"MLF M#@7YWPN=S(Q,,4(#=0SQ)A60@U+8//2W",$D#O@N,_EXCK1-X8SY),0=DOMP M-V6.7,A9L,Q,-N9 D5;4)\G:!#<=,%N ,V5#RM;B#B8`MQC8/;%=BY4?3USB M):=M4_J5S4A]X?O#XTXFVCL;+:@%F,^$R!3P;^HC*XAX_= MY^UX,>^70LOF8@/FKB/^(.J.R!^+&_^]7K()=U(=D0W]0:^/BUCBKL^\6K0O M&G.90YECAVN?#;J-&J9Q1?-47Y'<8!Y?M&07ABX83#2N ?*$CT[ MHN4$S+,9Y:A\N\8-B3=A"=*R:YW9;E)9/H4ES#H)/'(G`;/=$R]F<[.2X-;$ M$1X;Q3(DE\HLLD*U\;U8H>,"NV>HF/U^Q;3B\D>H:EH<'#:#Z@A+3 2HG2&H MUV>@-O\&M5<"5<.SU>J>E92HV-7JEU?-N#S"=JUWK6/M-PYN:*":*6X>4EM" M_L-CV)8\%CZ9WA5V&]&:BG6&[8G.Z MG@[L6'+/HMJS8.Y:W"@5,1B!'5=M;+V3AS<%V&_N0*]5/'.-"#:#:J'C?2M^ M!Y4NT-)!V_LO]=I9"AUB3I(?26N.DP?\JL%$=8;%DB89#"AYS& MK=0PTP%8--VDLDBZ'QK^W,<_GC*N3L6=CYFQ+-P`8D[1[\JMLXOS-)HDD SW M7$RO$LC:"8_.R W:;BY,J?QEI7A_RDXOBOA/V1XYE7J43P`>P3 H*P4U-G1W M3G$^B]2DC \.0=0LLZ1?70X'U=HP395ZRSQ#X%.0ZE*C[ B'1;^OU!]0] M?2S86]M/MVM[BKU;V3>->HZNGSY#UZ,]^5]5G28:;&=TF*XIY7[RO@7[(!H_ M.HC&CYZA\:,7U?C1`QH_>M?XIRD="A5N"RO[S W>A1]Q\.60A%: J&6EH_^J M#89*W@]&-'&$;.H.[0_YE\>WY1*[A/DU;(3(7+V,D3S:/)I!<>4I_E *_R)^ M]$;IOAO2,PUIMTJ^BET]U9:B.YJ#"7$V61D1SOG>&TSBG2_,V:K/[^]UC\CQ M9A%]1>][R_=?!W7 XK,<\/E79(^]%EOWE-+A/67O&[<NQK4ZA4\!AU!0XOY<4[LJ%(PG_H9ZFD7F_N\YN[W>)#; MHKI#\VF(F](]BVN+CWS_`5!+`P04``(`" `I7XTH)(%H'$D$``!A#P``$ `` M`%!#8G5I;&0O;6UA<"YD8D(O6Y7*T7&-N"K$T=Y:&FAN]>]2G?2H:+:GIEGGAG;3\()# 1- M5*IF&3C\GDL5\P3\+&="@9>H/SG-H",DAW,8DI WK# DL84SC] [,N

HAX MTOCMU]^/CTY>`NMR]",99]#*A60%Z ?HJ"0D&?S!DU2H""XKU:K&>?\>G!$, M1Q-PG=X$I\='>GG2''0;.,B*AH.=]$=U!7TP3DBPM MJ#Y6+ZHU'=?N=!N:-9(V80Z?YO/CHW<#U_>;71C'P7V,59+!8(4"5"&#B('^ M)GFT%;$U+-# GD'1Y I2L"K[/6]5#I1$D,:*3S M1&N26\'3)3!D5=@TUY#@I@%V"3!2+Y1DI8BP?MPBX(\DC"6_^F'>&LZP@G&'] M:C!S;EM\+J+R.ND%;SSRH"FE>O!XTB[J='C,(\8C*K#\ZMK)IS30@?KR&6K6 MCJVO*)$>R19@52IH:GM>@\H*?^3'1X-)OQ$*MIJ-_78CH6:,#'L=`.N74]RG M,PL:C0-=-/R+;*VF[\)URH-!I[U%<+U<="HP3=BMH7 9Y5F<9X$C$K VZ-L> MO2CC2 MJ80'YL+K3%LYGC#M?*HVV,SLP DT'"!ZPWK-:L8#AVW==TUXP#7G=&-OYH-6NUR>.V/G7[?3 :#IA>X7[S1>*+- MMPC;<<"F)8/=Y,YN\IX^5-]Z$94YPQNUFGMMZ^UY%9W!`[PAMYTFO,N6L133 M6A79/N@36\:](J1(A;<#;(E/#5K]!#9;!Y9.A^TMOUVO-:8IU8^,9YM;6$M& M:\ON8K\W_(P0*+=WS^*-#>YX$G%9KU6P`OV025;#.1.K$9:4QDK)8H(*SN1\ M92'LGL2E6[K@LL11DF]&),]*^%PPL\JFM'3 (8U7DW5_F9386$(7^*"XZM4_ M7I;4_]6LM91?61?\HE/%C[6G#+!5GEU9%;MXGL5+5NC@.[?ONR_+9OF,>[5H M7AP6S1+[9"E',IMAN?I7R./L/J^O> MVK9$-F"%S#ZM5XONT$'-W7Z/-C)A5C:OQ7M>7?>:-P)IT'R5)Y07/TGN)+VQW98/(/]^JWTD-CFX M`LQJ!H'HH_KUJZK.J[C]$3J">M*7XP`,?L,MZ7(/!D'(A(2^)__E-("&L#@< M09?8O**YQ/.YIV&_3^B,3#CT;AWN57[_\L?^WL=M<$V.=B3@#,Y"8;$(]C,T MI&>3`/[BGB^D`Z<%75&AY6SYO#JWX=M$OAG)3@ MX.[KZ2$8&G5 MS8$AKVA.L;4)IATP7H KU4!*UQ(.1@"3#/R.V*[%RT]@K@#3$[XP[E"!*=,7 M1@-*3;50R4]*4\O-MB4E5I\$4] *!4UM^*'5`-!^.\#SF'@AH%I" ^T)7K6HN4$W+,Y$ZB!V^R& MQ)OP!&DYMSN;X?XM;$D1XW8T%2>V5VN<>U M\4VOL'&!WW$4SWZ_0JVX_1&JAA%[A\-0=*0E)Q**G2$4+T^@V/P;BKT2% T\ M7JWN24F+FEVC?G;1C-LFCAN]RP'VKM"X84"1IKAY2&,)^8^(85OJ8%RW'&J% M# ]STN_7XF:M?(WG:^(1.RI)_O606M=B8?Q43IUANV(+MNHY3BQI9J'L63!W M+3$JZJN*W@1K,IS<5,?K#=ZGY'""P+LY7U\1S,N.=PZZ140+=4.?22YH2) MI(7N^:Z45M3!2L.L23)#V UQ4S-_RJT41UI\V2)AD,*'@L6C;$13`VQ2-^DL M@NZ'(W_NXP>EC+LS>>MC9"P+$T#H%&M13QD85#6"L6D3+MSA@`\TH8R?A\(XG$5B<'%V?"\6ANF MX2BZ;%1VI,,CA:ZW!_6'5#HM\L_6Z./-&IUB;U?H=58OT>?C%^ASE(VW56>6 M:*F=T5-V7Q+-Y\GT!NP=:K6Y.ZTV7Z#5YDZUVGQ J\U?6OTT/4-5PK3PLL_= MX.<3<),E$IX-PZL)>O[9[<>2]6U"^AZZ3U2L=J3\CU;[9J#?^_K\UI*\J5:\ M/[-?Q>+_6"S6R.;Q$V4SNNK8A6YF@Y$1SUS->9<@W?J2SG979[(!NR]C[UAW M?N1+GU>M/OJ+JL\.[H4>>Q>T*O)O?7NSX48I1^P!4K\NC'Z&"Z-7JBN/NE#Y MR>M((D@OOX+J&E@XLB\H8MF*1[+O&]:\-]A@L'RR6#N=?P#::I3=*F8WD*%' M>21SBN*@=W%>JU=0=CJ2A4KZ8AP[ZA7HDU^$//%.[EE/?,\LU[E-?T'4$L#!!0``@`(`"E?C2AT$O+ 2@4``) ?```3````4$-B=6EL M9"]P>65X<&%T+F1S<.U9:6_B2!#]'BG_H<;9#YG1!!PRBF;0LA+!P*#A4B [ MFU4DJ^ENH!?;;?F8P+_?:A]@AR,7LYE5$A&EC^K7KZJ+5W'["#J">M*7XP`, M_H-;TN4>#(*0"0E]3_[#:0`-87$X@2ZQ>45S%WSNDD##@3ZA,S+AT+MUN%?Y M_=,?AP='N_":'.U(P!EY':$C/)@'\R3U?2 ?."[JN<#Y\`*,'W=X0 MZD9KB-W#`S4\K%XVA]?].FC?A7-6@N/YY_/W8"P<8@MZTA;.#-IBY!%OH8$^ MUT_UTL95U7;_:W7'NG.U[O"@UFA6$H?1WWAMU7*G!)T;A9/#@W>=^F!0;=9A M.!4^X,>1`1#X02S!P"8S/D8?"S"4,(I<#I29F\0U](4S@6ZG^JW^,0,5^ASM M.-3GKO0"Z"0H0*5M$X>!^O5")[,BTXS0H#B&]* *R$(K;#:^EB%0XH#O+0`AL2B.477)GCP@!$#7*D&4KZ6<# $ M>,S Y\1V+5Y^#'6%N,RZ38>@;4;K2]\7(Q6VJ124^S!&`GGWB+>-RMI^E]SB MQ.<:'(_P#U,NWI^ [W-R ;470G_`-P=_C\4.?[^7O")<%)E40/] MRUX?-['D;9][M>A\#.YRAW&'"CPV?6DTH-14"Y4.+7EJN>FVI,3JDV *6J&@ MJ1W?M1H`VF_'F$7O-:A4MA]MS"^"NJ@.ZG#E<[/3J&4(+(>C*)NQDWF.D4DO M#-PP, WA@;9"SUJTG(![-F<"U7"7W9!X$YX@K:;6F>TFE>536,&LD\#4.PFX M[9YX,9N;M2"W)H[TN!E+D]HLL\T=LHTO>H6-"WS.44?[_0JUXO815 TC=@^' MH>A(2TXD%#M#*'X_@V+S+RCV2E T,,-:W;.2%C6[1OWBJAFW31PW>M\'V+M& MXX8!19KBYB&-%>3?(H9MJ=2X:3G4"AGF<]+OUY9-_$1.W\QMRR6>2OI'<^D, MVQ5;L'6/<6)%+PMESX*%:XE124>^$B>NVCAZJS(T!7C:VLM!K>+1-2(X#$4+ M2]TG_0L4V1(M-=H^?S&HG94J(Y^J\K:&&\VF-)92.:&F"3NDEG&70_'/D+'[\A9=R=R5L?(V-9> "$3K'(E5MGG\]3 M;Q)',MQS/KVL(TK$RYH^/S5.=?6C;?>-*5G)NXA)%@9EK5!,Z[2[8(C (U$H MXW\$03*A8C&XNAA>5FO#-"!%EXW*CG1XI,[U]J!^KT*G9?[)^GRZ79]3[-WJ MO,GJ.=I\^@QMC@[D/U9FENBHG=%2=E<6S:=)]!;L/>BTN3^=-I^AT^9>==J\ M1Z?--YU^G):A'N&Q\++/W> 5BK?)$OG.QN$GBGG^R>W7DO1=&OH2FD]4K/:E M^@]6^F:@W_FW^5XYKI5O\,ELXA$[NM3Q;X;4NA%+XWW5B9=G]E8P_H\%8UTZ M^6.E,[KEV(]V9L.1$=!31)-VL=55-? M\I%]2Q%+5SR2>^FPX=W!-HO58\;F^?SCT&ZK[&XQPX$,/]OCWU+*=.ZZZP_*AN#<^R\LCS$YU@13(F4K4 M_8!%MU$[X-10FEMQ;_D^[%]02P,$% `"``@`U5V-*.9!"#ZX! ``TQH``!(` M``!00V)U:6QD+W!Y=&AO;BYDD:"0G+H(V6"]@ M6[+7J _!]<$)(\($V+[XA^(0&LRE< )=-*,5S;L/IX)KLFXC?(TF M%'JWG/J5WS_]<7CPO@BN2:4="BF!6L1<$L-^A(;P9RB$;]0/F.!PKI=*"N?# M!S![T.T-P#);`UD]/%#-@VJ_.;BR+="^,UX^@Z.[S^?'4!<\$))CU?-FT5-XXJ-JV_ZQN'W:NAAT>U!O-2A*M##89676]*9*1C:+)X<&[CN4X MU:8%@RD+0/YP$0*"&^0R`C-T3<-LV MAG+%D' 1BIG4\$P#6 LW2\'A_QM1%;= M]:E+44 U.!K)/T3%MW/E'1?@)<3_*[1\,C9@%BSSW:@%D3\0-]FQ-3IA/),2 MU6#W>[;TX8I;F_KU>%Y,ZE%.*,=,3E=I;N1@/%0#E?!D++6EWK; R+51. 5- MUS7E\%VK`:#]=B37SK$&E'"=XV&8C'_G+ M#&.37A1Z43@TF0_:`CUOT>(A]6>4,*E^178#Y$]HBK3H6F=63"K/1U_ K).0 M:^XDI#/OQ$_8_%A-<6O"A4^'B1@I7SDO*USKMEW!KD[OJ+*HFF82D6P&@PM7 M3 08W\M@-/\"HW<&ABE74ZM;/M/B8M>T:I?-I#RL][I.KVVEM4ZM[LCBE1S7 M,,' &?P2=>L7':W'*9C!<>7A\ M*GT!@\Q!,Z/M_36G7CZKC *L3HPUW+@WBW/>L]S8;G6_2@BIM==KXY,^N*8^ MIV[Y3'?E',HSQD^+$\+2TBWC@2>$&U>D?!-WDO8@6!\,CH_#>HQ4!B;86GE MJ^I9)6N;<+XPC0_U38(\:]U/-G MOM$^JX:6GJ2A+W3I79>O9[N;;KD8+S%XNQG_@L+XJXM>(FA=4^I9_E$PV4U) M2_Z-;\-;W1:#Q6?;QN[EK\M"H[RKA)TC(A_3^+\4BJ+3N^S7K4J\4:1FR'AU MAN.%9W&R;+P3H2-(Y-(@E1X=[_UPN>=;PJ,^Q1]Y`BW-\_ZIB9,;GXQRP^H^ MWH*BFK+ED]3F+\S_`E!+`P04``(`" `I7XTH1?"H1K (``#0C@``% ```%!# M8G5I;&0O<'ET:&]N,38N9'-P[5WO3^LV%_Z.Q/_@Y;X?[IUVVP(;VM Z"6AA MU8!6M.SN3DB5X[BIWR9V9#M ]]?/3EI(:6N7'W?C:@\NI;/[\_2_;6^]<`D^IJ8G@]=7QRVISWV'2X//DP MR<;8]"[,X^VM;\[;_?[A:1L-QDPA\\N%1AC=X(1%*,43.C*=K*&!0&'19VVK M93-D<\5XC"[.#W]K?U<1E2MJZE'4OLN$U.A\)@41D::81\C^R9Q7SJAL%M)0 M?83NAZIFU AJJVM_%CDBF".54<)&4Z,Y$7S$XMR,DQV-VS'EMBU^KVCEY'"* M(J-9<O DW:W(!\M;-0[!:GD] MH10++7)CP0A5:&146.P@ENN466[PDB84*QJ@]Z'YB&PO_5;XP2FRU/X5!59! M62'69?>;"'9 L*GH<$H>!_[XTM?0A0L^D8WU+# M0M;18;^-KA0=GI\<5U2X+RZ 'I;=7-2RJ-+-=9;K88M)%#Q(K];H<$UE2B-F M>-%5;X!E3&>2'@XM:^96JJI/[4',LA+&_#YJFF8?9:G-]3+,G9@+28;J;2>J5%LW?5;P];9\/V'[WNY:"BQ)_I;J-1 MZ'(^.&NF+%KNL3GPH%ZUO72BIUG"PMV&T=</L$6C5^D?]X[W=9JB(=7Q+[11'YVK?'UDL M/.M<_&9$&(MJY2SS3ABLRW3:94)D10[Q@=%23P[ M@J,;G,VKJ3%-YG)$0A^V<*[GXG,6E:512.85S";)9COW@Z#R4$V5F3('IO5( MW"J#3)*8`<%D;+S?06?OQ_UY;V8=2>PD85P7@M;U:D'C^]8L^1X$C;L=NM.P M/\%Z!2)+!HMZ6#G&<>,\T4;J06#^D6*T^U='@\O#X\%Z\@#X+]/]I\HQF5)=6Z"Y:XK'GL>AC MV9U2MIM*JVT]9LRU[/H"*AV^@$J'KTJEPR=2Z1"H]&E,9AC*#!,]4#33;YI? MC0WE^B"HU>=D,(QJ1D"PW(778.'%:Z.WQ<4N[OLWR!I;K%Z-KC>AZ%/=>!2- M>BG4S]R.:+1P":L9_1]7I15]E5SNXNHWR>VW2I#)C-<6F-#T/4V=G/A%Z?\5 M.+;(-+P6R58QJS#MO^])7K67+W8E;SDW\D4=2N-%#N55TB>;IDR6N7SW"5Q^ M\60N7Y]I6=#DRVOQM>587#F4-YES^4\ZDZ_=36S@`"Y:AO^K"?F2>5QNVFFR+F(\H2JZR$Q MH,3`,AA223!2H$A M>?T;2;$>`S/Y[0ELR4M*148`$'(AE&8,)IIGHMGERW=[J DH.1(D8TT)&+CJ)DR $,@XP.0B) M2LD%7(WXS,G )"1$VB[2MH_S`6G[83*T!,[-3TRCS""4`#-M`I2F2@-2_JDG M<0H4Y?5U(RG^HA U.2TIYY">]!I23#66,41-+O8V&!4O46!\) `HIRW-"9D"3$Z8 M;LHW10%*#I3,U1OC# C)L2[08I1BN0,8.4)NEN*8PB).'LB<&B=O#,]]&\6-B;-+T(UEJZ\D^,PRT$KS-,F-+V$4+ R&%) M%B0P)3],@L<`DS>T2C$LMW Y-Q.;JS$\1^"Q(5@>OPE,T0\$`'(#!&;DBY%2 MJO$L:0`P.?R_P6DL(H@`O Y.1"K/('G@,Z>"F,"<7%F65-T0"@L3SC?A(*?D\6[@U[P3S7Z%$-8"@F['/,N* M#T#(@Y 6$\#(,=4R(N%5*;<'Q.HA!&("38P*)'SB-X!1BY;*MYX!<;D M-R8M10;DY+NJ,S#E1*8S=Z+=K7E<57MHN,D(,"AY4E K]?32I%Q#/A(["@/A7[[&R<$ M0GEH"VQW[ZY5JSKV^.^9\? SF/?0XM25GASYH+-[9DF'N=#W`Y-+Z+KR;T9] MJ'&+P16TB[]/K\[0COC,A'+ M+3/4_0@UZ=K$AS^8ZW$IX#J5R2B=#Q] [T"[,X"JWAC@X_F9ZAZ4>O7!7;<* MVBT7^1Q56KVX" ^C MBZ:4+&=",)1A,#X_>]>J]ONE>A4&$^X!_@KI`X%[8G$3;#)E(XPH!0,)PS! M7YDYBRP&'A=C:+=*7ZL?$U*!Q]".077N2->'UD(%J+1M(DQ0?VX@$C,2S5 - MTB.(MR6%7FBI[<9W,@!*!'@.HWST@(Y3*49\'+AA)F V84(M)99^)B8/'\!$ MQ\(QY:Y-<)L!,P8X4W7$_EI<8 IP4X'-B>U8K/ 2UY7BLL:V;8*V7:TK/8\/ M5=HFDE/FP0@=6 ^/N+M5VN4\H':FK1=XT:@/;+!1;)I0;%XNZ=BUP,UU%S;9> M+=_4H[:!_7KGMH]/=VA.Y6M)>O MV!HTBS8W-V/"@94322E[ZC_@"V*8RZ!7$@=NFM@[4W47"QPVM]>O%%VZX0AV M0]K"\^E3Y@NDS:5:;+1[O-ROY'/%H4?5F;2A&X[&;BY'UCN;C?97E$"83S?F M1V,P9:Y@5CZ7PK#4*>8NFF.3+UH8GN=(:84/>#Z8UG@Q0LQ[XL1FWH19L8ZT MV*I%`C^6#[@9]9I#&AM@DSJ+AV72O6#H/7A8]P5J#.(0TXXY+ @I6 C0:K-? M?1*B\4%[,$*SNQ$::^\'Z#:K8_"9/0*?89Y?!YYV@G;F8Z09AT'4W*[];)(: MIR.I<01)C9.2U'B"I,8;29^)G) ON".LX#''_V_C%>LM\ M:*KV @6&J'=4V M4W "!J]_Y/FY2+P/?3\"U43EZC5A7?3'@2W\ MK/]RLB6C3N#MQ^-_YDDZ/0GR#\S,L1_[5N.389?-I[B1TW M(6O+OEV%O%V%G )N_TNB/P/6;1U9G;SECC@1]:Q=6F^Y>-YEL7HGO7U\_1W_ M?JOD:I&'?1FXE(5?J2DW^YV;7J5:#(FP0**!Q9MR0\)4A;D^X3DJN'Z+<)&B M+[^)?^FUTV$?D0X]9-?V>TMJ5%=<`-'3\DN/?P!02P,$% `"``@`*E^-*&;$ MG5J#! ``-1 ``!(```!00V)U:6QD+W-E;&5C="YDQ_:U9;PLJIVT7$2$$!H>1.AU^MII]T7[:B MK3TS?OS,C/.8?("AH($*U2("BS]Q5_D\`#N*F5 P"=3?G$;0%2Z'&Q@1CS>, MD+MH,W ^(71%EAS&:\F#QF^??[^\^' .KL MA$))N"V5RQKGXT>PQC :SZ!C]61Z1#/1O$,O"BL(P00-S`5FA2TC"*+T<^Z!BH$1"Z',J%EOD M3952.YJ%Q?,M,.25^#1;CV#C`"L%N%(;V-EU$F*@S%7%?K40G*0UC@QH=ID> 4A><;37%*0F[ MU1S_,9W9Z^?F^@Q@ROS-<.D9;O&ED/G#I0V3Z7@"3==5ZPD/VDFN%O>Y9%Q2 M@24H[X)L2AV]4#^*.3GCP#M0E+@3$CV"42JAJSV9-*A;XAM^>3&<#1J>8-EL M:K<;`4W'R+'?!3!^O<)^71O0:)RL99I#LE^K:7?@+N3.L-LND-R9DVHY:2$. M\TA"QG'DQY%CB0",/7HQHB\C'GB<"52-W^".:Z":>&QZX]J52,9CJQ.ZZZ7CAVT6^-[&V.]"Y3.T4C2PY.XYU+$ M\5;1UG?%O%I&<@H==P.TKO4)S '>LS;9' \^F"Y>#Y_+7\%D.X0\Z+2_9;=K MU<8\I/IF..I9XLVI[3R'QD%_] TA4%-71^M3'ZQX(+E;JY8P%7V7!-EPR40V MPI1"7RDWF:!,,W>9>0A[(GX>%CYR-\=1+M^/2!SE\+%@J97-:1Z 0^IGDUVA MPW@>;D,\]77399(@7N!SG]+XFL0T57SY/2 M,EXWRIN*5:F4\< M*$$=;]LHM>M2V7>MV;39GN7U,GTVKTLE4SWN#.S.:YJ<7Z1O5N3*:47.L<_K M\4M1[U'CRCO4.&G1?Z_%+%-.KZ">[$@!WR;*)[#?H,S.OZ3,SCN4V7FW,CNO M*+/S4YE_3+%08K 5O!YR/_HIUUJN#XU>^$2#Z+F*.RS3\6+YWJ;J(PM%O?@> MD&I0:BE^K7_AB_>)@+T&IXBVB@/*D]=K#6N/[Z;M3@,E8JA8[/(PDPHOF962 MQ[^#[WD'RU)3SBV=[=Y8_@%02P,$% `"``@`*E^-*&Q"^-%Q! ``CQ ``!<` M``!00V)U:6QD+W5N:6-O9&5D871A+F1S<.U7;6_B.!#^7JG_82Z]#^UJ2RB< MJEUTG 0D(+2\1(1>MZN5(A,;\)'845Y:^/<[3@B$\M+=]O9T)QT"87MF'C\S MMA\G%]#G;B@C.8W!8(_,DP$+P8X3RB58H?R+N3&TN(NR(S!\$FPL/[[;W^?<.C"$,AF,PC>X8N^=G:GC<&'7&#Y8)VCT7U0I<+C_<7H&Q$L3G M[G6/BP7T^"0DX4J#\K)\4ZZHN%:[4R^01^Y9M,$FR>S\[)>^:=N-C@GC.8\` MOT+&0."1>)R"3Q9LBDQ+,)8P28G'RBU85RB)N)C!H-_X9+XO0"410S\&YC*0 M80S]-0JXTO>)H*!^82(*$85FB@;Z%(HE+R$3K70XX$$FX!(!45>* M*9\E6&]5U:%:")ZL@"*YU*8H^P27$+!F@)%J(.?L<8%EP 4#MB1^ MX+':C])7J#O[:'(W-PMA'S&(F8!I<3 M_*,JT9)Y\L%K;2K T6,$&9<#D6 MH[QQLEW748'JM.XPU'9<>M(EGD7B.6BE$II:EE5WO1);LO.S_KA7]SE=]T9V MJQZZ61N)=ML`VJ^7N(97&M3KITN;99-.VFS8)MQ%S.FW6P6ZF^&T;DY6DMV, M4I=A$@=)[!@\!&V+7O3HBIB%/J,64WYB$,[9&VIKVF9TF5>13VL+LD\!E MOXZ9'UR'&9NO!Y>D.Q,R9$XF%&K"PE3/"+<_ENMTFJW'!30,(TL+%Q!T(3TY MDZ#WQZ#?5T'O? 9]6 '=P%W8'50K6MH<&&;SKI.U'1PWAO?VNM=OMO+FG3TR M>KVLT^\W+,?\; U'8V5^0-BV`;J;,]B=W-B=O*NVV->N<+V$XFE;]ZV6]O-Y MI97![;PE5YS&7\2KP..32AG9/JF-F\>](B2="L\*Z!Y>.F[Y(^AT$Y@[';:,-I;=P5YW\ DA4)\7>_&9#18L%,RK5DJ8@;JVD')I]YL;2'TD02Y6S1G7HXC/;9MD23.X1-.LU$Z<7,';+K! MNK.I+_4\+"QQYWBSU+K5#[3U%O&]>8/X4H7U#TDO7W@W M:IEU/.U]21./145)+*4GU,1WO)VHUT"IDA^%4T-YSEEO\Z+S#5!+`P04``(` M" `J7XTH/*=.&DX$``#F#@``% ```%!#8G5I;&0O=VENJ?]A+GL?VM4VH7"J=M'E)" !H>4E(NEUNUHI,HD!'XD=Y:6%?W_C MA(304JKMKO:^'"K"'L\\\WAL/W;?P9AYL4C$(@6#/M! 1#0&.\U\)L"*Q3_4 M2Z'/`@I7,"$AU95'QA.1<5]!BT6\-5E2F#YR&NM__O'7^=F[4X #BGXDI3YT M,Q;X.? 'Z(LX)"G\3>.$"0XW:J,A<=Z_!V,*DZD#IC%TL'M^)LU.9S9P[BT3 ME#O&6TVXV'R\N01CRTG(O*L1XVL8L7E,XJT"C4WCNM&4<;W^0"^9(_$BU*#S M;'E^]MO8M.W.P 1GQ1+ /RY2(/! `N9#2-9T@315< 3,<]:I=(MVM"$."%.0WSG@MHM;,T4!;0%5L%6DHZG'O M>Y&!1S@D$?788HO,/<$7;)EAI64]'U>4RUR\(EH+GF_!1V;YF.0;$EP\P&H! M1DI#23A@'&N 2P5T0\(HH.WOXBXA]WOG< 64XTB62!(VES5;">;1!!:8_'!J M)'Z)QO-4,QI0DE %+N;XX\OYO;Z#+D]"%NS?#%CLYRY=,EX>-6FP9E,+.D$@ M'BT:]_+Y&C2BW*?<8UB&1N5D>YXK`^7!!$4YL(^$1P*+I*M\H&=9NA>H=$// MS\;.2 ^9O^O-[)X>>T4;N0W[`,KO%[A:EPKH^HDZ%NSS?-V.;<)M0MUQOU>C M5YGS.KE%"0YGD+M,LS3*4M=@,2A[]+K'D*0%X&W+5[ M%O54X3K=1@&;-QM(ZU%NT3+N#2%Y*CP2H 5X>7B-3Z#Y56#I]/)XU^ZUFOH\ M\>2M\6PE\]&2435R:!P-)Y\1`M5V_2R^&(,UC3D-6DT59R#OF7C77/ILUY+; M,!(BR#LHX'ZPW(T0_X%$I5NRHD&)(P*Z;Y$L+>$SYA=6?^Z5#MCTHEVGJJ\? M!%A8XJWPGF@/6Q]O2NK'6"/!,#R,EQK:5AJ;:^.ZU<"/<@02-)&E;475JJLE MVN([1*/YZ6KC+9:6(S*[?=MU9IV>4U+0(G_>YH(72F>.;/-UM2LOJ#=KW?7+ M6E=BGU:Z8UX_HG/7/Z!SOL3Z%2KG[U0F+)3FZQ#5QG^J-N[/5)O!UYM^N>^HG_N__I7B%5^/IYJ%JH.EINV$QJE/TD4C^9YHHUNJ8[U M_&_5RHF!4EE_KQ:GNK 4S\\3#\477?;:5J#:(HL]FO];**'Q=,QZIJZJWZQ> MI3IJ?BY,1#GP+DPEK:)7/:K_!5!+`P04``(`" `J7XTH^$B%PY8$``!-$ `` M$ ```%!#8G5I;&0O>FQI8BYDS]^AWJ8DOK2[<)BGUIX#CDS/#PS) \#-_! M2-! AG(9@<&?N2-]'H 5Q4Q(F ;R+TXCZ F'PPV,B#UJ_??S]\N+=.; ^QS@2<0:=6#@L`?T`/1FX)((_>! *Z<%MI5I5.._? M@S&!\60.IC&88_?R0IGG[5E__C U0;L77J,.5YM/M]=@;#WB"GHS%-X3#,4B M(,%6@^JF6JO6U;ANK]]2K)%T.LS@BWAU>?'+R+2L=M^$^5J$@!]/1D#@F3B" M@4N>^!(I5F N89$PCE28G]4D#H6W@O&H_<7\4("*0XYQ',R-+X,(1AD*4.FZ MQ&.@?H/8*XPH-!,TT)>0%+F"%+3*\<@'&0,E'H0^IV*Y1=94>DNQBK'"JHXO M:^ZI>;P=R<+@Q188LDI\BJM+<-$`JP0X4AERLH[P,']<(N ;XOH.;_YGW@HN MW2OEJFO'$:8R#,5"U6DM!>4A+''29H9=S@)N097"_S#5$[?WBW7 M)^%2UJ\&2_=MAZ^$EQ\G99C.)E-H.XY\F?*@F^1I<)][C'M48/K579!%J:T& MJL.74M-*OJ&DQ)F2: U:I8*N[G3:HDZ%;_CEQ6@^;+F"9;V9U6T%-&TCPT$/ M0/OU"M?I6H-6ZT054_[);)VV9<)=R.U1KUL@N#,GE;+3(I1S2$(F<>3'D6V( M`+0]>C%BX$4\<#D3J!+GXN8D6/$,:>\Z9':>5)%/90]S2 (7^B;BKG\3I&P> MRXLP6'DRX'9ZX-5,A3G^Q;3WN=IBRW0%WD';,-)\<,E ]Z0C5Q+TT1ST^P;H M_3]!G]1!-W###<:-NI8TQX;9N>NG;1OMQN3>PMX#!O<,T&F.6X8T]I!?10H[ M4-OE<>!1)V9X5K+^M+MKXD?E6:LU#F;4=IZR<3@8?T$(5-2G@_&I#YYXX'&G4:^HP9^+G8>&:.SF.=/B^1>(HAX\%2ZUL0?,`;%(_Z^P* M'<:+JFQFN=*OYHITO E+:4*Z%P\&XEL1,A:E/#+XH(,HZ: M6D5/;D=_R]#"$[EHXB4<*:NJH'77F<_:W7E>1MUGBZ8GO52NS:%EGI?L_'Y] MM6#73@MVCGU>KH]%O46L:V\0ZV1Q?K14LTQ8W8*XL@.)?)UFG\#^;N&V?XAP MVV\0;OO-PFU_0[CMG\+]?:J%4H-+P9LA]Z.?:GY.S<$-GVD0E47=9IFL%^OX M&I$?&ZCQQ3=#*DNI9?\$./)O^E'W7I!3-$O&`>7)TUM!6I.[6==L845'DL4. M#Y,JNDF[DIQ_$U^!I4&I*6>5]G;OFG\`4$L#!!0``@`(`"E?C2AG$9H*9P0` M`-P/```3````4$-B=6EL9"]?KKA^1T MP01.T1TJE0`#0L>;,&F:*I)EO -LL769V]UGX``/N!#*4\P@,?$97^AB &<6,2Q@'\D]T(NAP%^$&AK:'=%VD.#M"!LV8NRS!_00=&7AV!+]A$'(I MX*Y4+BN-27?Z.&Z#]L!%M0)7FR]WUV!LA>UQ MYZ;/Q0KZ?!;8P5:#\J9\6ZZH=:U.MYX1)][I2@-G\>+RXJ=!VS0;W39,ESP$ M^A4R`AN>;9-;^U/!:@X1(I#:&]\ M&40PR%# D9YG"P;J+XA%845AF*"!/H>\U25BH95>#GZ4,3BV@-!'A\^W1-R1 M8LX7,?59=7.]1*%2B1W/PN+9%A@12WR*KF?3U@'U"FBE,N1\72ZH!;11@!O; M\UVL_0AUA;@[-X?MUU[&&LQ!JVD6@-]% R%PZD) MY5V0Z3B66JANY(Z==N#N2\=VQW:T!*U4(E=K/*X[;@DW>'DQF/;K'F?9;&*V MZH&3CHEDKP.@_7Q%>W:M0;U^NIUI%4G"9L-LPWV(UJ#3*M#19? `M#UZ,:(G(@P\9)S4XUSO=WT$<5T TZ>;UAM:(EPZ'1;MYWT[%%=F/T8-+LD8([!NA.CGL( M:>PA_^ I;$\=FJ>><-R8T;W)YN/6<9I"]G,9DTKHV.W3%G&\5;3U73ZKE(F' M),=]GZQK==IR@/>L39+3*0?=I2?A<_DKZ&R'D >=]C?-5K52GX6.>@R.MB?Q MYM1VGD-COS?\1A"DHJNC]:D/5A@(=*N5$I6BGH\@&RX8ST944NA+Z283$F;F M+C*/S9YM/P\+E^CF.-+%_#FOZ50M;J.GY?E!+MFE;>W.*M4:8? M[72=3$G$8;ETR.*HII7T_(7SMXP0,+G@-7I+H\RA^F+>-Z>31FN:-T?WV:PF MI$B5MMTWVZ^J;?Y,OEEK;T]K;8Y]7FE?BGJ/SMZ^0V>3#?D'5)9EFN@5=)$= M"=[;Y/8$]GG-M?XFS;7>H;G6NS77>D5SK?\U]\>TB/2$M@)K(?K1?UR(+99) M<;$G;Q3FH4&Z7/R4GHI(:CGXT/W"I^)3$7L=33%-&0<.)E^"%; YNI^TVG6Z M\P/)8A?#IW2]E\Q*R;5NTW>Q@V6I*6>7SG;?*/X"4$L#!!0``@`(`"E?C2CM M"/Z*) 4``(X>```0````4$-B=6EL9"]?5(F,;\)+841[3\N_W.B&0M$#?[:S:JA5^ M7!^?>Z\YMW$^0D=07P5J'(+%?W)'>=R'01@QH:#OJW\Y#:$A' [[T"4NKQAV MX',#>WU"9V3"H7L?NSL?MX$U.=J1D#,XCH3#8M OT%"^2T+XB_N! M4!*."J:I<3Y_!JL'W=X0ZE9KB-W='3T\K)XTA^?].AAG0AZ6X-/5MZ,]L.:2 MN(+NMX6<05N,?.+/#3"OS .SM'95M=W_L[IEW9%>M[M3:S0KVEMT-EE8=;PI M0<]&T61WYT.G/AA4FW483D4`^"M5" 1^$DIV(\1]94R;&81)@?G87+*9=Z'[DDF5D\F@-#5O&V,]3E\%@1CI:$V5H#R M,6Z==XSXFTCD-SOA#B1KB$]1.!90.Q!G+;V;X-=(O; M=X5-OJ?'?")D*A]ZH'_2Z^,FCKKL<[\6Y\3B'I>,2RHP5>;2:$"IK1=JL4E( M&KFYMJ+$Z9-P"D:A8.CM/K0:`,9OG_#,[!E0J6S(9<(LQCFN#NIP&G"[TZAE MMEX.Q\&U$_?R[&*37A1Z46A;P@=CA9ZU:,F0^RYG`O5NF]V0^!.^0%I-W62V MG5263V$%OI^PNUY@VOIL5-B[P*XXR MV>]7J).T/T+5LA+?H>EHRXV;7J MQZ?-I&WCN-4[&V#O'(T;%A1IBIN'M%:0_X@$MJ4/Q45+4B=B>(P7_7XM:=;* M%WBR)CYQX^(37 RI>(T8E$WDKG#AM MX^BE/J8IP,/6G@QJ%9_>((+#4'2PHGTUOT.1+=%2H\WSQX/:8:DR"J@N9#=P MX]F4YG(F/]AN=7\@!!:!V8WUR1S,N"^YHO.,NA!- KF`7Y- MRK@[4YXG,?*4,;:'^I1'87!Z?'PI%H;IJ$H>FQ4EDKR M6)GK[4%]NSJG!?W!VGRP69M3[.W*O,[J,;I\\ A=CO/PDJK,%AKJ9G2479=" M^V'RO '["37:?CJ-MA^AT?:3:K1]BT;;[QI]/QU#1<*T\'+ O?"M";?-%M*= M#<*S"'G^^>S7DO-M$OH:>D]TK)Y$\>^L\LW0O/;O\DM+\:8:\?K,WHO$_[%( MK)-+\WYR&5]J/%8OLX'(B&:NSKQ*@"X#16=/5UNRP;HN8*]2:W[EBYUGK3CF MHRI.>O?SO"5GG:Z_] 7-ADNC'+%;2+W?";V%.Z%G*25WN#-YXZ5CH42/NV'J M6E@KLF\=$KE*1E8O$=:\#E@[O7I\6#.9?\;98I+=)&$U4)%/>2QKFMJ@=WI2 MJU=09CJ*15KJXB#0>[[/N-<%VP,>XAY4BW,YJ4N6]ST92I.4])8OBOX#4$L# M!!0``@`(`'B^C"C9*"Q'A 4``,DB```4````4$-B=6EL9"]?=&MI;G1ET:L"!*DK1<1+!D**"L8)SO9XBH<5>8 _;:_FE M@7]_LW[##J]-*(WN$N5E/3O[^-F9]3Q,_!9ZS/"XS\?\>E#ZH?1U:2D?'R],38=8; MMS?Z-ZT%TE?F5"MP-K^Z? ?*PB$V,\Z[S)E!EXT\XBTDD.?RA5Q9NZK1U3XW MMJR[%.M.3YKMFWJZ8]QPO+AAN5."NQN%D].3-[W68-"X:8$^93[@M\,#(/"= M6,P$F\SH&#=9`IW#*-IS(-S<)+*ASYP)J+W&E]:''%3H4_2CT)J[W N@EZ" MP6V;.":('R]T,&: *X4A)6PQ!V. B08Z)[9KT=H/ M<1>0RY.W+@_2>CR-^SX;BR';S<[,=< O+_2#CY_B:3IB3EAAAT&[[&@;"X@\:]9I1CA3J M4L>DCL$P=7+F-#",H5@H"M*2H%28[W*#6!H)IB"52O?1MR1N_*;3!I!^.\,3 M]4Z">AUV':L,];HQ:,&=3X>]=C-')C-'"X;QA@7?BZ)+/PS<,!@JS ,IQ<[/ M=P0'FYH,Z^,6KXG#/3J,"X.XV6,F.O$F-+G-V,\V1+2YA5CD3$ZCR@ MMGMN"K3[U6QLH_R(;5/3ZH95HG,J/!J*$N\)S5!VN,4G',H]W83R32!#^6L5 M!W]!^6\&Y3X:.U&J.XYAA28>S^1::\;#9NT>S\S$(W8D._Z];ECW+'-6\!!W MU&HE'@Z5UO7=33)&N]+_.DB=],_#AJ9UU(Z.EF]X_[8"92,E7.2JO%"N/;U; MMYFY&FJ<6-+/@]NS8.%:;%21<2<<)/6NB]8'\<"D`$];>SMHUCUCA0B:H6RA M$G^4/T'9S-!2I\WSUX-FM5(?^880WQ7<:#:EF-IEZ(HX"O.=S)@IS8XYH=Q)CB[U4U MVN\C^RPQ_Y+8/_CH.6OLJ9OK!X!F:*6_6S"7Z M=M7%C*.&QA3.KFSTC$,Z3P9;:-1^X*YU>7!^L)VY_DNCF. MR\O>_6$D&W:QY=JK:]JCGUN'O5LF]Q$O\327*D7]RO/,TW]M](ZC7[^D@')S M9*0..#3+3B%J+UW7XR@= MK_]]AKJ\Y!;KR!U4IC$'Z9]^7&6*OG<;NGF=]9Y9\L'N^F*A'$I/79NB_ M(";Y^OBJ&WOJQD_O0E0%92+_"BVN9+&E^$9LPQNM'6[YZK[!<2=2'B-F.>"A M9] H!H+JH']WVVS5\:CTN!F*N&0!-)[XFN[)_ZO\X<[N"6)=R%O+,8OQV#M( MP8RXKC@P_\\H"5-ZW..K[/WQOU!+`P04``(`" "I8(TH>7W1X18#``#N" `` M$0```%!#+V1L;&)A2:'ND)] [X1J@($S6(N-0 YKYA 8YQ:=.\^S7RTJ\"V X MD)IQY*? %##OL3,^K':T"%Z#D:Q&$)Z^Y9EOF9]V`OB\@?E*P)BTR/@6A"(A M2)N"PH>%@CPC,X<2:S]ZY9,8UZ__TG)PNQ&/O0D^KHVA$)67V]-@YS#/QF]# MY/=HM^"D?A@W#=J-MQQ3);YA0#F@9UL0/H:VW.Q%CMAJMGR0J MSWZVI)7KNN](00B/E#$I=XT MV#7BGDC20NFV4+=,-0AZ`]IXT3$YEWZ^$S%W%H081DYYV"PD;ZB]W94^++R\ MN?YQFV>U[KH@@[XCN ?AZW:(*_R-TLZYE'#XG$&!Q:OPC*]7P^OSL^)%GOWP MM"&S'&X?/2HG*+JOFO<46K0,4#GR<'*29[2P=IRO(?4LJ.+J:D[]\7="A1RE MJ+>1N@ZO`T'-XE+V,)F-Q,U$_),B+6PR&XF/$_$@E,7F"/$Q$JN)^.-T?8<^ M3:PB<3LCJ)6.J;J-Q*>)H$J;H\2G&1&>T !?0[>Z?3EQ7TZJXVI6_.%ME]LM M/AJ6C&)&K(IB(L83!FFBB$0Y$;T2M:9QQ#Q[2I21J.;5<+JG)D_YJ")Q,1)Y M]HT.B(WQ0C>V[WZSJF1&I))8QJ24Y=Q]55KFDD09B6I)R'_)0I55)"XF@J9" MNJJC#"8(EY'XLU$L'L)QQIN-#LD^+IEKCU"S$;' MVZ4JE3HY>[.1N%X2#NO>"K\]).(`*&\.(KSZZ47S%JV?4I4L7>K M8JFJ16D2/JHB$@?=7DMAUCH,C241N[VJ]H=MO&7H%POA`YS*P8!?1(F7K_;X M?U!+`P04``(`" `J6HTH9D AC-,%```)#P``"P```%!#+V-O;F9I9RYCI5?? MCYM&$'ZN)?\/H\M+5RF M]?UX-![!E9^5YQ"0NAH"5C-Y8"F)+YDL>%US48(2T-1L`@D:-H%"I'R'_Y$8 M4EXKR;>-8J R7D,M=NHYEDR#7-7C42J2ID 3T5IDV@F)T!&J1E:B-F+/7&6B M4;!C#) ";69XVKV,2\52/$LEQ8&G+$4-L<('[MJ*`]/6&#>5`EV#RU7%8@F\ MA!B/A#!GM=9 &\>CK5"9X?A^IQ9"Y=7IT)>DXU'=5)60.@*]4TU>E6CKRKA MO6)W)6 87Q,Q0%],UX[^)] =\N0B3P_C7 (%#)L*6 M46Q2?>KTP-"\FC0B2=5LXC)JXMS9&QD>@_.DXO-=!;)H4X6HT& M$]-XA )%G**[#S'/XRU28@X0W0^Y9CQZ2XYY!VTH'$PA63*%KDDEJVO8J>K7 MAP=\WE='/&=Y+^1>'R.,G.D\,0ER_L"X=*>.I9+I#,GL*>1EO6]T/YSA9L1&H]FUL)Z M(L/,EFZZGEM1Z*,9`01VN'*U_L? 7X#KAW0,6(5XWID56;@5NTC@XQ'0_O7< M1B,#.H>%?]/(\3T21[51@-,)>/:3ZSS9WM0FI3Y)8R/S`Y1T.['*!$Y). M?Q71=E\S(HEG&TH*!'K?)CN,!7: YUY8FO>Q'Q@=^MO__7L@FH=;6(BTR:DQ ME3N^;]JD?44CJH(=-P)4CZ9>E,YV+,-MPW-UAW5<:!IJVMB=0V9*:J-A7KY] M1Z7."^I$]\E]2_^&ETG>8/W<+$U>9S>TS+Y2_L-!\%23Q%+&Q[?O?AM FI0+ M40UB6U[&=<+Y()A@6\L&$29E*0817L1[=D795;HB_3BX7K+GX74UN"RP?\5* MR$%0LCW[.HSLM[S8#T/B&EW-]]BIAJ$L'EY'NNH:TB3#9T*'LF$@DRQ.A^,6 MXCN@W#O^,+KDR;_Y,&F52 .\X;N4[;#BO%\^#,2K/B1RV-Y-+I*X97_#2GP7 M#,@D(F5)K65T^=S=@36;+?S9"CO9P@K^P&;RGE9-!9SO7QX7L40/YQMZ-UQ) MP:JE-GZ%C?97O(7-\NCHZM*;<>7O?^!W^'9^@_IVHPOI9G(JJI?)JS\6X09= M,O/786^'*;!NCYGI7:T#3J)=O;6RW92$3T*Z[EH)/>[#NOA:6(_[<%N!K4 [ MZXN<\7]/C\788>G'/H3UV$(XNH!4AZB7"6!,5S73/1#?:0)[8U,FU#+KB;[9 MX 61?]71/3%TU=OR=-.^&EW%K80>7\"ZE#M<3RX$Q$F#'O=A4]4M;B87`EG< MH5E\`5%Y=R"-OX,Q%T\X3OH"5.DM3,.SK*/WWB::![8UZVW0':#;HB?#2??: M#[JC;I3_(3YHYM#ET)Z0G*(M+VAA=K9NWNA+,-Y'=0^Y3RYRL%U'W?T^ M8]1?DK>DRG!V[^T+2EQ^+<5J@ >OND ?#?J#!B_I](VD;\/UL;YO+P8;UN(*CCK/UGF4A&L5+EO?5_3R!GU_&HQ=L MK_\!4$L#!!0``@`(`!=BC2A,;&0"H ```-(````9````;&EB+W1E3V.30N"0!"&[PO['][LHB!B000=.W7NTEG<40=T9]L/ MQ'_?&M0MD.>'-WJ]SYIBM.!I(5,3M#_1HVS(EGC_2-5Q>W@/)<87E!+`0(4"Q0``@`(`"E? MC2AC)S `5 4``%,@```1``````````$`( "V@0````!00V)U:6QD+V)S9&1B M+F1S<%!+`0(4"Q0``@`(`"E?C2@D@6@<200``&$/```0``````````$`( "V M@8,%``!00V)U:6QD+VUM87 N9'-P4$L!`A0+% `"``@`*5^-*.B!37$J!0`` MXQX``!(``````````0`@`+:!^@D``%!#8G5I;&0O<&%R This is a multi-part message in MIME format. --------------8747A0C814C2A18EFA16F3DA Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit The attached patch set contains the following fixes: Patch Set Contents: ------------------- Lib/test/output/test_unicode: Added test output for Unicode string concatenation test. Python/compile.c: Fixed problem with Unicode string concatenation: u = (u"abc" u"abc") previously dumped core. Lib/codecs.py: Added more documentation. Clarified some existing comments. Lib/test/test_unicode.py: Added test for Unicode string concatenation. Misc/unicode.txt: Updated to version 1.4. -- Marc-Andre Lemburg ______________________________________________________________________ Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ --------------8747A0C814C2A18EFA16F3DA Content-Type: text/plain; charset=us-ascii; name="Unicode-Implementation-2000-04-13.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="Unicode-Implementation-2000-04-13.patch" diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x *.orig -x Demo -x CVS -x Doc -x *.orig -x .#* -x distutils -x PC -x PCbuild -x *.py -x ACKS -x *.txt -x README CVS-Python/Lib/test/output/test_unicode Python+Unicode/Lib/test/output/test_unicode --- CVS-Python/Lib/test/output/test_unicode Wed Apr 5 22:11:19 2000 +++ Python+Unicode/Lib/test/output/test_unicode Thu Apr 13 13:40:53 2000 @@ -4,3 +4,4 @@ Testing Unicode formatting strings... done. Testing builtin codecs... done. Testing standard mapping codecs... 0-127... 128-255... done. +Testing Unicode string concatenation... done. Only in CVS-Python/Lib/test/output: test_zipfile diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x *.orig -x Demo -x CVS -x Doc -x *.orig -x .#* -x distutils -x PC -x PCbuild -x *.py -x ACKS -x *.txt -x README CVS-Python/Python/compile.c Python+Unicode/Python/compile.c --- CVS-Python/Python/compile.c Tue Apr 11 11:26:15 2000 +++ Python+Unicode/Python/compile.c Wed Apr 12 18:05:29 2000 @@ -984,11 +984,32 @@ REQ(CHILD(n, 0), STRING); if ((v = parsestr(STR(CHILD(n, 0)))) != NULL) { /* String literal concatenation */ - for (i = 1; i < NCH(n) && v != NULL; i++) { - PyString_ConcatAndDel(&v, parsestr(STR(CHILD(n, i)))); + for (i = 1; i < NCH(n); i++) { + PyObject *s; + s = parsestr(STR(CHILD(n, i))); + if (s == NULL) + goto onError; + if (PyString_Check(v) && PyString_Check(s)) { + PyString_ConcatAndDel(&v, s); + if (v == NULL) + goto onError; + } + else { + PyObject *temp; + temp = PyUnicode_Concat(v, s); + Py_DECREF(s); + if (temp == NULL) + goto onError; + Py_DECREF(v); + v = temp; + } } } return v; + + onError: + Py_XDECREF(v); + return NULL; } static void diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x *.orig -x Demo -x CVS -x Doc -x *.orig -x .#* -x distutils -x PC -x PCbuild -x *.c -x *.h -x *.in -x output CVS-Python/Lib/codecs.py Python+Unicode/Lib/codecs.py --- CVS-Python/Lib/codecs.py Thu Apr 13 11:11:33 2000 +++ Python+Unicode/Lib/codecs.py Thu Apr 13 13:40:21 2000 @@ -231,10 +231,13 @@ """ Read one line from the input stream and return the decoded data. - Note: Unlike the .readlines() method, line breaking must - be implemented by the underlying stream's .readline() - method -- there is currently no support for line breaking - using the codec decoder due to lack of line buffering. + Note: Unlike the .readlines() method, this method inherits + the line breaking knowledge from the underlying stream's + .readline() method -- there is currently no support for + line breaking using the codec decoder due to lack of line + buffering. Sublcasses should however, if possible, try to + implement this method using their own knowledge of line + breaking. size, if given, is passed as size argument to the stream's .readline() method. @@ -288,6 +291,14 @@ class StreamReaderWriter: + """ StreamReaderWriter instances allow wrapping streams which + work in both read and write modes. + + The design is such that one can use the factory functions + returned by the codec.lookup() function to contruct the + instance. + + """ # Optional attributes set by the file wrappers below encoding = 'unknown' @@ -346,6 +357,21 @@ class StreamRecoder: + """ StreamRecoder instances provide a frontend - backend + view of encoding data. + + They use the complete set of APIs returned by the + codecs.lookup() function to implement their task. + + Data written to the stream is first decoded into an + intermediate format (which is dependent on the given codec + combination) and then written to the stream using an instance + of the provided Writer class. + + In the other direction, data is read from the stream using a + Reader instance and then return encoded data to the caller. + + """ # Optional attributes set by the file wrappers below data_encoding = 'unknown' file_encoding = 'unknown' @@ -452,6 +478,11 @@ buffering has the same meaning as for the builtin open() API. It defaults to line buffered. + The returned wrapped file object provides an extra attribute + .encoding which allows querying the used encoding. This + attribute is only available if an encoding was specified as + parameter. + """ if encoding is not None and \ 'b' not in mode: @@ -487,6 +518,11 @@ data_encoding and file_encoding are added to the wrapped file object as attributes .data_encoding and .file_encoding resp. + + The returned wrapped file object provides two extra attributes + .data_encoding and .file_encoding which reflect the given + parameters of the same name. The attributes can be used for + introspection by Python programs. """ if file_encoding is None: diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x *.orig -x Demo -x CVS -x Doc -x *.orig -x .#* -x distutils -x PC -x PCbuild -x *.c -x *.h -x *.in -x output CVS-Python/Lib/test/test_unicode.py Python+Unicode/Lib/test/test_unicode.py --- CVS-Python/Lib/test/test_unicode.py Thu Apr 13 11:11:37 2000 +++ Python+Unicode/Lib/test/test_unicode.py Wed Apr 12 18:38:30 2000 @@ -391,3 +391,11 @@ print '*** codec for "%s" failed: %s' % (encoding, why) print 'done.' + +print 'Testing Unicode string concatenation...', +assert (u"abc" u"def") == u"abcdef" +assert ("abc" u"def") == u"abcdef" +assert (u"abc" "def") == u"abcdef" +assert (u"abc" u"def" "ghi") == u"abcdefghi" +assert ("abc" "def" u"ghi") == u"abcdefghi" +print 'done.' diff -u -rP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x *.bak -x *.s -x DEADJOE -x *.rej -x *.orig -x Demo -x CVS -x Doc -x *.orig -x .#* -x distutils -x PC -x PCbuild -x *.c -x *.h -x *.in -x output CVS-Python/Misc/unicode.txt Python+Unicode/Misc/unicode.txt --- CVS-Python/Misc/unicode.txt Tue Apr 11 11:25:53 2000 +++ Python+Unicode/Misc/unicode.txt Thu Apr 13 13:40:51 2000 @@ -1,5 +1,5 @@ ============================================================================= - Python Unicode Integration Proposal Version: 1.3 + Python Unicode Integration Proposal Version: 1.4 ----------------------------------------------------------------------------- @@ -162,6 +162,17 @@ For the same reason, Unicode objects should return the same hash value as their UTF-8 equivalent strings. +When compared using cmp() (or PyObject_Compare()) the implementation +should mask TypeErrors raised during the conversion to remain in synch +with the string behavior. All other errors such as ValueErrors raised +during coercion of strings to Unicode should not be masked and passed +through to the user. + +In containment tests ('a' in u'abc' and u'a' in 'abc') both sides +should be coerced to Unicode before applying the test. Errors occuring +during coercion (e.g. None in u'abc') should not be masked. + + Coercion: --------- @@ -380,6 +391,13 @@ data, consumed = self.encode(object,self.errors) self.stream.write(data) + def writelines(self, list): + + """ Writes the concatenated list of strings to the stream + using .write(). + """ + self.write(''.join(list)) + def reset(self): """ Flushes and resets the codec buffers used for keeping state. @@ -463,6 +481,47 @@ else: return object + def readline(self, size=None): + + """ Read one line from the input stream and return the + decoded data. + + Note: Unlike the .readlines() method, this method inherits + the line breaking knowledge from the underlying stream's + .readline() method -- there is currently no support for + line breaking using the codec decoder due to lack of line + buffering. Sublcasses should however, if possible, try to + implement this method using their own knowledge of line + breaking. + + size, if given, is passed as size argument to the stream's + .readline() method. + + """ + if size is None: + line = self.stream.readline() + else: + line = self.stream.readline(size) + return self.decode(line)[0] + + def readlines(self, sizehint=0): + + """ Read all lines available on the input stream + and return them as list of lines. + + Line breaks are implemented using the codec's decoder + method and are included in the list entries. + + sizehint, if given, is passed as size argument to the + stream's .read() method. + + """ + if sizehint is None: + data = self.stream.read() + else: + data = self.stream.read(sizehint) + return self.decode(data)[0].splitlines(1) + def reset(self): """ Resets the codec buffers used for keeping state. @@ -482,9 +541,6 @@ """ return getattr(self.stream,name) -XXX What about .readline(), .readlines() ? These could be implemented - using .read() as generic functions instead of requiring their - implementation by all codecs. Also see Line Breaks. Stream codec implementors are free to combine the StreamWriter and StreamReader interfaces into one class. Even combining all these with @@ -692,9 +748,10 @@ are used as format strings, the following interpretations should be in effect: - '%s': '%s' does str(u) for Unicode objects embedded - in Python strings, so the output will be - u.encode() + '%s': For Unicode objects this will cause coercion of the + whole format string to Unicode. Note that + you should use a Unicode format string to start + with for performance reasons. In case the format string is an Unicode object, all parameters are coerced to Unicode first and then put together and formatted according to the format @@ -922,6 +979,9 @@ Introducing Unicode to ECMAScript -- http://www-4.ibm.com/software/developer/library/internationalization-support.html +IANA Character Set Names: + ftp://ftp.isi.edu/in-notes/iana/assignments/character-sets + Encodings: Overview: @@ -944,6 +1004,12 @@ History of this Proposal: ------------------------- +1.4: Added note about mixed type comparisons and contains tests. + Changed treating of Unicode objects in format strings (if used + with '%s' % u they will now cause the format string to be + coerced to Unicode, thus producing a Unicode object on return). + Added link to IANA charset names (thanks to Lars Marius Garshol). + Added new codec methods .readline(), .readlines() and .writelines(). 1.3: Added new "es" and "es#" parser markers 1.2: Removed POD about codecs.open() 1.1: Added note about comparisons and hash values. Added note about --------------8747A0C814C2A18EFA16F3DA-- From fdrake@acm.org Thu Apr 13 15:13:42 2000 From: fdrake@acm.org (Fred L. Drake, Jr.) Date: Thu, 13 Apr 2000 10:13:42 -0400 (EDT) Subject: [Patches] Unicode Patch Set 2000-04-13 In-Reply-To: <38F5B431.39FB76EA@lemburg.com> References: <38F5B431.39FB76EA@lemburg.com> Message-ID: <14581.54806.244258.685523@seahag.cnri.reston.va.us> M.-A. Lemburg writes: > The attached patch set contains the following fixes: I've applied this to the CVS repository; thanks! -Fred -- Fred L. Drake, Jr. Corporation for National Research Initiatives From thomas.heller@ion-tof.com Thu Apr 13 15:34:11 2000 From: thomas.heller@ion-tof.com (Thomas Heller) Date: Thu, 13 Apr 2000 16:34:11 +0200 Subject: [Patches] Patch to ihooks.py Message-ID: <012401bfa555$55b63170$4500a8c0@thomasnotebook> ihooks.ModuleLoader does not implement reload(mod) correctly: If mod has already been loaded by ModuleLoader, it has been returned from a cache. Added an additional parameter to import_it() to force reloading. *** ihooks.old.py Thu Apr 13 16:26:06 2000 --- ihooks.py Thu Apr 13 16:27:18 2000 *************** *** 467,480 **** if not submod: raise ImportError, "No module named " + subname ! def import_it(self, partname, fqname, parent): if not partname: raise ValueError, "Empty module name" try: - return self.modules[fqname] - except KeyError: - pass - try: path = parent and parent.__path__ except AttributeError: return None --- 467,481 ---- if not submod: raise ImportError, "No module named " + subname ! def import_it(self, partname, fqname, parent, force_load=0): if not partname: raise ValueError, "Empty module name" + if not force_load: + try: + return self.modules[fqname] + except KeyError: + pass try: path = parent and parent.__path__ except AttributeError: return None *************** *** 489,499 **** def reload(self, module): name = module.__name__ if '.' not in name: ! return self.import_it(name, name, None) i = string.rfind(name, '.') pname = name[:i] parent = self.modules[pname] ! return self.import_it(name[i+1:], name, parent) default_importer = None --- 490,500 ---- def reload(self, module): name = module.__name__ if '.' not in name: ! return self.import_it(name, name, None, force_load=1) i = string.rfind(name, '.') pname = name[:i] parent = self.modules[pname] ! return self.import_it(name[i+1:], name, parent, force_load=1) default_importer = None Disclaimer: I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. From fdrake@acm.org Thu Apr 13 16:10:32 2000 From: fdrake@acm.org (Fred L. Drake, Jr.) Date: Thu, 13 Apr 2000 11:10:32 -0400 (EDT) Subject: [Patches] RTSP support for urlparse.py In-Reply-To: <200004130325.NAA06753@mbuna.arbhome.com.au> References: <200004130325.NAA06753@mbuna.arbhome.com.au> Message-ID: <14581.58216.675833.972193@seahag.cnri.reston.va.us> Anthony Baxter writes: > The following adds support for RTSP (RFC2326) URLs to the standard > urlparse.py module. Anthony, Is there a reason you supported the rtsp: scheme and not the rtspu: scheme? I'm looking at section 3.2 of RFC 2326, and they look like the same syntax to me. Thanks! -Fred -- Fred L. Drake, Jr. Corporation for National Research Initiatives From jeremy@cnri.reston.va.us Thu Apr 13 23:06:39 2000 From: jeremy@cnri.reston.va.us (Jeremy Hylton) Date: Thu, 13 Apr 2000 18:06:39 -0400 (EDT) Subject: [Patches] Re: Comparison of cyclic objects (was RE: [Python-Dev] trashcan and PR#7) In-Reply-To: <14582.14222.865019.806313@bitdiddle.cnri.reston.va.us> References: <14580.48029.512656.911718@goon.cnri.reston.va.us> <000701bfa505$31008380$4d2d153f@tim> <14582.5791.148277.87450@walden> <14582.14222.865019.806313@bitdiddle.cnri.reston.va.us> Message-ID: <14582.17647.662905.959786@bitdiddle.cnri.reston.va.us> I did one more round of work on this idea, and I'm satisfied with the results. Most of the performance hit can be eliminated by doing nothing until there are at least N recursive calls to PyObject_Compare, where N is fairly large. (I picked 25000.) Non-circular objects that are not deeply nested only pay for an integer increment, a decrement, and a compare. Background for patches-only readers: This patch appears to fix PR#7. Comments and suggestions solicitied. I think this is worth checking in. Jeremy Index: Include/object.h =================================================================== RCS file: /projects/cvsroot/python/dist/src/Include/object.h,v retrieving revision 2.52 diff -r2.52 object.h 286a287,289 > /* tstate dict key for PyObject_Compare helper */ > extern PyObject *_PyCompareState_Key; > Index: Python/pythonrun.c =================================================================== RCS file: /projects/cvsroot/python/dist/src/Python/pythonrun.c,v retrieving revision 2.91 diff -r2.91 pythonrun.c 151a152,153 > _PyCompareState_Key = PyString_InternFromString("cmp_state"); > Index: Objects/object.c =================================================================== RCS file: /projects/cvsroot/python/dist/src/Objects/object.c,v retrieving revision 2.67 diff -r2.67 object.c 300a301,306 > PyObject *_PyCompareState_Key; > > int _PyCompareState_nesting = 0; > int _PyCompareState_flag = 0; > #define NESTING_LIMIT 25000 > 305a312,313 > int result; > 372c380 < if (vtp->tp_compare == NULL) --- > if (vtp->tp_compare == NULL) { 374c382,440 < return (*vtp->tp_compare)(v, w); --- > } > ++_PyCompareState_nesting; > if (_PyCompareState_nesting > NESTING_LIMIT) > _PyCompareState_flag = 1; > if (_PyCompareState_flag && > (vtp->tp_as_mapping || (vtp->tp_as_sequence && > !PyString_Check(v)))) > { > PyObject *tstate_dict, *cmp_dict, *pair; > > tstate_dict = PyThreadState_GetDict(); > if (tstate_dict == NULL) { > PyErr_BadInternalCall(); > return -1; > } > cmp_dict = PyDict_GetItem(tstate_dict, _PyCompareState_Key); > if (cmp_dict == NULL) { > cmp_dict = PyDict_New(); > if (cmp_dict == NULL) > return -1; > PyDict_SetItem(tstate_dict, > _PyCompareState_Key, > cmp_dict); > } > > pair = PyTuple_New(2); > if (pair == NULL) { > return -1; > } > if ((long)v <= (long)w) { > PyTuple_SET_ITEM(pair, 0, PyInt_FromLong((long)v)); > PyTuple_SET_ITEM(pair, 1, PyInt_FromLong((long)w)); > } else { > PyTuple_SET_ITEM(pair, 0, PyInt_FromLong((long)w)); > PyTuple_SET_ITEM(pair, 1, PyInt_FromLong((long)v)); > } > if (PyDict_GetItem(cmp_dict, pair)) { > /* already comparing these objects. assume > they're equal until shown otherwise > */ > Py_DECREF(pair); > --_PyCompareState_nesting; > if (_PyCompareState_nesting == 0) > _PyCompareState_flag = 0; > return 0; > } > if (PyDict_SetItem(cmp_dict, pair, pair) == -1) { > return -1; > } > result = (*vtp->tp_compare)(v, w); > PyDict_DelItem(cmp_dict, pair); > Py_DECREF(pair); > } else { > result = (*vtp->tp_compare)(v, w); > } > --_PyCompareState_nesting; > if (_PyCompareState_nesting == 0) > _PyCompareState_flag = 0; > return result; From bwarsaw@cnri.reston.va.us Fri Apr 14 00:14:49 2000 From: bwarsaw@cnri.reston.va.us (Barry A. Warsaw) Date: Thu, 13 Apr 2000 19:14:49 -0400 (EDT) Subject: [Patches] Re: Comparison of cyclic objects (was RE: [Python-Dev] trashcan and PR#7) References: <14580.48029.512656.911718@goon.cnri.reston.va.us> <000701bfa505$31008380$4d2d153f@tim> <14582.5791.148277.87450@walden> <14582.14222.865019.806313@bitdiddle.cnri.reston.va.us> <14582.17647.662905.959786@bitdiddle.cnri.reston.va.us> Message-ID: <14582.21737.387268.332139@anthem.cnri.reston.va.us> JH> Comments and suggestions solicitied. I think this is worth JH> checking in. Please regenerate with unified or context diffs! -Barry From jeremy@cnri.reston.va.us Fri Apr 14 00:30:02 2000 From: jeremy@cnri.reston.va.us (Jeremy Hylton) Date: Thu, 13 Apr 2000 19:30:02 -0400 (EDT) Subject: [Patches] Re: Comparison of cyclic objects (was RE: [Python-Dev] trashcan and PR#7) In-Reply-To: <14582.21737.387268.332139@anthem.cnri.reston.va.us> References: <14580.48029.512656.911718@goon.cnri.reston.va.us> <000701bfa505$31008380$4d2d153f@tim> <14582.5791.148277.87450@walden> <14582.14222.865019.806313@bitdiddle.cnri.reston.va.us> <14582.17647.662905.959786@bitdiddle.cnri.reston.va.us> <14582.21737.387268.332139@anthem.cnri.reston.va.us> Message-ID: <14582.22650.792191.474554@bitdiddle.cnri.reston.va.us> Here it is contextified. One small difference from the previous patch is that NESTING_LIMIT is now only 1000. I think this is sufficient to cover commonly occuring nested containers. Jeremy Index: Include/object.h =================================================================== RCS file: /projects/cvsroot/python/dist/src/Include/object.h,v retrieving revision 2.52 diff -c -r2.52 object.h *** object.h 2000/03/21 16:14:47 2.52 --- object.h 2000/04/13 21:50:10 *************** *** 284,289 **** --- 284,292 ---- extern DL_IMPORT(int) Py_ReprEnter Py_PROTO((PyObject *)); extern DL_IMPORT(void) Py_ReprLeave Py_PROTO((PyObject *)); + /* tstate dict key for PyObject_Compare helper */ + extern PyObject *_PyCompareState_Key; + /* Flag bits for printing: */ #define Py_PRINT_RAW 1 /* No string quotes etc. */ Index: Python/pythonrun.c =================================================================== RCS file: /projects/cvsroot/python/dist/src/Python/pythonrun.c,v retrieving revision 2.91 diff -c -r2.91 pythonrun.c *** pythonrun.c 2000/03/10 23:03:54 2.91 --- pythonrun.c 2000/04/13 21:50:25 *************** *** 149,154 **** --- 149,156 ---- /* Init Unicode implementation; relies on the codec registry */ _PyUnicode_Init(); + _PyCompareState_Key = PyString_InternFromString("cmp_state"); + bimod = _PyBuiltin_Init_1(); if (bimod == NULL) Py_FatalError("Py_Initialize: can't initialize __builtin__"); Index: Objects/object.c =================================================================== RCS file: /projects/cvsroot/python/dist/src/Objects/object.c,v retrieving revision 2.67 diff -c -r2.67 object.c *** object.c 2000/04/10 13:42:33 2.67 --- object.c 2000/04/13 21:44:42 *************** *** 298,308 **** --- 298,316 ---- return PyInt_FromLong(c); } + PyObject *_PyCompareState_Key; + + int _PyCompareState_nesting = 0; + int _PyCompareState_flag = 0; + #define NESTING_LIMIT 1000 + int PyObject_Compare(v, w) PyObject *v, *w; { PyTypeObject *vtp, *wtp; + int result; + if (v == NULL || w == NULL) { PyErr_BadInternalCall(); return -1; *************** *** 369,377 **** /* Numerical types compare smaller than all other types */ return strcmp(vname, wname); } ! if (vtp->tp_compare == NULL) return (v < w) ? -1 : 1; ! return (*vtp->tp_compare)(v, w); } long --- 377,443 ---- /* Numerical types compare smaller than all other types */ return strcmp(vname, wname); } ! if (vtp->tp_compare == NULL) { return (v < w) ? -1 : 1; ! } ! ++_PyCompareState_nesting; ! if (_PyCompareState_nesting > NESTING_LIMIT) ! _PyCompareState_flag = 1; ! if (_PyCompareState_flag && ! (vtp->tp_as_mapping || (vtp->tp_as_sequence && ! !PyString_Check(v)))) ! { ! PyObject *tstate_dict, *cmp_dict, *pair; ! ! tstate_dict = PyThreadState_GetDict(); ! if (tstate_dict == NULL) { ! PyErr_BadInternalCall(); ! return -1; ! } ! cmp_dict = PyDict_GetItem(tstate_dict, _PyCompareState_Key); ! if (cmp_dict == NULL) { ! cmp_dict = PyDict_New(); ! if (cmp_dict == NULL) ! return -1; ! PyDict_SetItem(tstate_dict, ! _PyCompareState_Key, ! cmp_dict); ! } ! ! pair = PyTuple_New(2); ! if (pair == NULL) { ! return -1; ! } ! if ((long)v <= (long)w) { ! PyTuple_SET_ITEM(pair, 0, PyInt_FromLong((long)v)); ! PyTuple_SET_ITEM(pair, 1, PyInt_FromLong((long)w)); ! } else { ! PyTuple_SET_ITEM(pair, 0, PyInt_FromLong((long)w)); ! PyTuple_SET_ITEM(pair, 1, PyInt_FromLong((long)v)); ! } ! if (PyDict_GetItem(cmp_dict, pair)) { ! /* already comparing these objects. assume ! they're equal until shown otherwise ! */ ! Py_DECREF(pair); ! --_PyCompareState_nesting; ! if (_PyCompareState_nesting == 0) ! _PyCompareState_flag = 0; ! return 0; ! } ! if (PyDict_SetItem(cmp_dict, pair, pair) == -1) { ! return -1; ! } ! result = (*vtp->tp_compare)(v, w); ! PyDict_DelItem(cmp_dict, pair); ! Py_DECREF(pair); ! } else { ! result = (*vtp->tp_compare)(v, w); ! } ! --_PyCompareState_nesting; ! if (_PyCompareState_nesting == 0) ! _PyCompareState_flag = 0; ! return result; } long From Anthony Baxter Fri Apr 14 01:55:51 2000 From: Anthony Baxter (Anthony Baxter) Date: Fri, 14 Apr 2000 10:55:51 +1000 Subject: [Patches] RTSP support for urlparse.py In-Reply-To: Message from "Fred L. Drake, Jr." of "Thu, 13 Apr 2000 11:10:32 -0400." <14581.58216.675833.972193@seahag.cnri.reston.va.us> Message-ID: <200004140055.KAA11267@mbuna.arbhome.com.au> >>> "Fred L. Drake, Jr." wrote > Anthony, > Is there a reason you supported the rtsp: scheme and not the rtspu: > scheme? I'm looking at section 3.2 of RFC 2326, and they look like > the same syntax to me. > Thanks! Because I didn't need it, initially, and then, later, because I forgot about it. Feel free to put rtspu: in as well... Anthony -- Anthony Baxter It's never too late to have a happy childhood. From thomas.heller@ion-tof.com Fri Apr 14 12:38:55 2000 From: thomas.heller@ion-tof.com (Thomas Heller) Date: Fri, 14 Apr 2000 13:38:55 +0200 Subject: [Patches] Patches for 1.5.2 Message-ID: <00fb01bfa606$0403dd80$4500a8c0@thomasnotebook> Dear patchers, does it make sense to submit patches for 1.5.2 additionally to patches against the CVS version? Thomas Heller From skip@mojam.com (Skip Montanaro) Fri Apr 14 14:04:49 2000 From: skip@mojam.com (Skip Montanaro) (Skip Montanaro) Date: Fri, 14 Apr 2000 08:04:49 -0500 (CDT) Subject: [Patches] Patches for 1.5.2 In-Reply-To: <00fb01bfa606$0403dd80$4500a8c0@thomasnotebook> References: <00fb01bfa606$0403dd80$4500a8c0@thomasnotebook> Message-ID: <14583.6001.992507.138157@beluga.mojam.com> Thomas> does it make sense to submit patches for 1.5.2 additionally to Thomas> patches against the CVS version? In general, no, I don't think it does. The only place I can see a 1.5.2-only patch being worthwhile at this point is if it plugs a security hole => if you don't apply the patch you open your system up more widely to bad guys. Skip From fdrake@acm.org Fri Apr 14 14:29:57 2000 From: fdrake@acm.org (Fred L. Drake, Jr.) Date: Fri, 14 Apr 2000 09:29:57 -0400 (EDT) Subject: [Patches] Patches for 1.5.2 In-Reply-To: <00fb01bfa606$0403dd80$4500a8c0@thomasnotebook> References: <00fb01bfa606$0403dd80$4500a8c0@thomasnotebook> Message-ID: <14583.7509.402900.368389@seahag.cnri.reston.va.us> Thomas Heller writes: > does it make sense to submit patches for 1.5.2 > additionally to patches against the CVS version? At the most, it would appear on python.org on the patches list, but with 1.6 ~6 weeks away, I think dealing with it would cost us too much of our concentration. Our time is limited, and we still have paying jobs. It also depends on the severity of the problem; at this late date, it's hard to imagine it would be very important. Others may say differently. -Fred -- Fred L. Drake, Jr. Corporation for National Research Initiatives From fdrake@acm.org Fri Apr 14 15:02:32 2000 From: fdrake@acm.org (Fred L. Drake, Jr.) Date: Fri, 14 Apr 2000 10:02:32 -0400 (EDT) Subject: [Patches] RTSP support for urlparse.py In-Reply-To: <200004130325.NAA06753@mbuna.arbhome.com.au> References: <200004130325.NAA06753@mbuna.arbhome.com.au> Message-ID: <14583.9464.919175.424474@seahag.cnri.reston.va.us> Anthony Baxter writes: > The following adds support for RTSP (RFC2326) URLs to the standard > urlparse.py module. Anthony, Patch applied, with the changes we discussed. Thanks! -Fred -- Fred L. Drake, Jr. Corporation for National Research Initiatives From sz@zmail.ru Fri Apr 14 15:35:52 2000 From: sz@zmail.ru (Zaur Shibzoukhov) Date: Fri, 14 Apr 2000 18:35:52 +0400 Subject: [Patches] Proposal To Modifying Map Function in 1.6 Message-ID: Proposal To Modifying Map Function in 1.6 ----------------------------------------- map(func, List_1, List_2, ..., List_n) use the following rule now: if len(List_i) < max(len(List_1),...,len(List_n)) then List_i[Ni]=None, List_i[Ni+1]=None, ... Ni=len(List_i) I propose to change this rule to another: if len(List_i) < max(len(List_1),...,len(List_n)) then List_i[j]=List_i[j (mod Ni)], List_i[j]=List_i[j+1 (mod Ni)], ... (*) Ni=len(List_i) Why? Main reason: I can't use map without lambda expression in the following common case: map(func, List, arg ) (1) or map(func, arg, List) (2) where func -- function with two arguments, arg -- not sequense. Now I must do map(lambda x,y=arg: func(x,y), List) (1') or map(lambda y,x=arg: func(x,y), List) (2') With rule (*) I can write: map(func, List, [arg]) After this change I also can repeat lists of smaller length in map's arguments. I think that it can improve functionality of map. For example: Ls=[list_1, ..., list_N] map(append, Ls, [a,b]) -> [list_1+[a],list_2+[b],list_3+[a],,list_4+[b], ...] or Ls = [func_1, ..., func_N] map(apply, Ls, [args]) instead of map(lambda f,args=args: apply(f, args), Ls) and others ... This modification allow to prevent using lambda expression in map calls in some cases. Here is an easy "patch" to map (for source of Python 1.5.2) static PyObject * builtin_map(self, args) PyObject *self; PyObject *args; { typedef struct { PyObject *seq; PySequenceMethods *sqf; int len; } sequence; PyObject *func, *result; sequence *seqs = NULL, *sqp; int n, len; register int i, j; n = PyTuple_Size(args); if (n < 2) { PyErr_SetString(PyExc_TypeError, "map() requires at least two args"); return NULL; } func = PyTuple_GetItem(args, 0); n--; if (func == Py_None && n == 1) { /* map(None, S) is the same as list(S). */ return PySequence_List(PyTuple_GetItem(args, 1)); } if ((seqs = PyMem_NEW(sequence, n)) == NULL) { PyErr_NoMemory(); goto Fail_2; } for (len = 0, i = 0, sqp = seqs; i < n; ++i, ++sqp) { int curlen; PySequenceMethods *sqf; if ((sqp->seq = PyTuple_GetItem(args, i + 1)) == NULL) goto Fail_2; sqp->sqf = sqf = sqp->seq->ob_type->tp_as_sequence; if (sqf == NULL || sqf->sq_length == NULL || sqf->sq_item == NULL) { static char errmsg[] = "argument %d to map() must be a sequence object"; char errbuf[sizeof(errmsg) + 25]; sprintf(errbuf, errmsg, i+2); PyErr_SetString(PyExc_TypeError, errbuf); goto Fail_2; } if ((curlen = sqp->len = (*sqp->sqf->sq_length)(sqp->seq)) < 0) goto Fail_2; if (curlen > len) len = curlen; } if ((result = (PyObject *) PyList_New(len)) == NULL) goto Fail_2; for (i = 0; ; ++i) { PyObject *alist, *item=NULL, *value; int any = 0; if (func == Py_None && n == 1) alist = NULL; else { if ((alist = PyTuple_New(n)) == NULL) goto Fail_1; } for (j = 0, sqp = seqs; j < n; ++j, ++sqp) { if (sqp->len < 0) { - Py_INCREF(Py_None); - item = Py_None; + item = (*sqp->sqf->sq_item)(sqp->seq, i % - sqp->len); } else { item = (*sqp->sqf->sq_item)(sqp->seq, i); if (item == NULL) { if (PyErr_ExceptionMatches( PyExc_IndexError)) { PyErr_Clear(); - Py_INCREF(Py_None); - item = Py_None; + item = (*sqp->sqf->sq_item)(sqp->seq, i % sqp->len); - sqp->len = -1; + sqp->len = - sqp->len; } else { goto Fail_0; } } else any = 1; } if (!alist) break; if (PyTuple_SetItem(alist, j, item) < 0) { Py_DECREF(item); goto Fail_0; } continue; Fail_0: Py_XDECREF(alist); goto Fail_1; } if (!alist) alist = item; if (!any) { Py_DECREF(alist); break; } if (func == Py_None) value = alist; else { value = PyEval_CallObject(func, alist); Py_DECREF(alist); if (value == NULL) goto Fail_1; } if (i >= len) { int status = PyList_Append(result, value); Py_DECREF(value); if (status < 0) goto Fail_1; } else { if (PyList_SetItem(result, i, value) < 0) goto Fail_1; } } if (i < len && PyList_SetSlice(result, i, len, NULL) < 0) goto Fail_1; PyMem_DEL(seqs); return result; Fail_1: Py_DECREF(result); Fail_2: if (seqs) PyMem_DEL(seqs); return NULL; } Zaur Shibzoukhov sz@zmail.ru ----------------------------------------------- Get Your e-mail at http://zmail.ru From skip@mojam.com (Skip Montanaro) Fri Apr 14 15:45:46 2000 From: skip@mojam.com (Skip Montanaro) (Skip Montanaro) Date: Fri, 14 Apr 2000 09:45:46 -0500 (CDT) Subject: [Patches] Proposal To Modifying Map Function in 1.6 In-Reply-To: References: Message-ID: <14583.12058.856533.820813@beluga.mojam.com> Zaur> map(func, List_1, List_2, ..., List_n) use the following rule now: Zaur> if len(List_i) < max(len(List_1),...,len(List_n)) then Zaur> List_i[Ni]=None, List_i[Ni+1]=None, ... Zaur> Ni=len(List_i) Zaur> I propose to change this rule to another: Zaur> if len(List_i) < max(len(List_1),...,len(List_n)) then Zaur> List_i[j]=List_i[j (mod Ni)], List_i[j]=List_i[j+1 (mod Ni)], Zaur> ... (*) Zaur> Ni=len(List_i) An equally useful rule for a short list is to extend it with the last value of the list: if len(List_i) < max(len(List_1),...,len(List_n)) then last = List_i[len(List_i)-1] List_i[Ni]=last, List_i[Ni+1]=last, ... Ni=len(List_i) (I suggested this a couple years ago but was rebuffed... ;-) Given the somewhat arbitrary nature of choosing any of these three rules, you might as well stay with the status quo to avoid code breakage in the code that relies on the current semantics. -- Skip Montanaro | http://www.mojam.com/ skip@mojam.com | http://www.musi-cal.com/ From Pekka.Pessi@nokia.com Fri Apr 14 16:07:03 2000 From: Pekka.Pessi@nokia.com (Pekka Pessi) Date: Fri, 14 Apr 2000 18:07:03 +0300 (EEST) Subject: [Patches] Making modules callable when they have the attribute "__call__" Message-ID: <14583.13335.672195.314564@rama.research.nokia.com> Hello, Attached you find patches that make modules callable when they have an attribute "__call__". I think that this makes Python mode orthogonal. YMMV. Pekka Pessi -----8<-------------8<-------------8<-------------8<-------------8<----- *** Objects/object.c-virgin Mon Apr 10 16:42:33 2000 --- Objects/object.c Fri Apr 14 17:56:20 2000 *************** *** 601,607 **** PyCFunction_Check(x) || PyClass_Check(x)) return 1; ! if (PyInstance_Check(x)) { PyObject *call = PyObject_GetAttrString(x, "__call__"); if (call == NULL) { PyErr_Clear(); --- 601,608 ---- PyCFunction_Check(x) || PyClass_Check(x)) return 1; ! if (PyInstance_Check(x) || ! PyModule_Check(x)) { PyObject *call = PyObject_GetAttrString(x, "__call__"); if (call == NULL) { PyErr_Clear(); *** Python/ceval.c-virgin Mon Apr 10 15:45:10 2000 --- Python/ceval.c Fri Apr 14 17:56:16 2000 *************** *** 2430,2436 **** if (PyClass_Check(func)) { return PyInstance_New(func, arg, kw); } ! if (PyInstance_Check(func)) { PyObject *res, *call = PyObject_GetAttrString(func,"__call__"); if (call == NULL) { PyErr_Clear(); --- 2430,2437 ---- if (PyClass_Check(func)) { return PyInstance_New(func, arg, kw); } ! if (PyInstance_Check(func) || ! PyModule_Check(func)) { PyObject *res, *call = PyObject_GetAttrString(func,"__call__"); if (call == NULL) { PyErr_Clear(); -----8<-------------8<-------------8<-------------8<-------------8<----- -- I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. From mhammond@skippinet.com.au Fri Apr 14 16:27:17 2000 From: mhammond@skippinet.com.au (Mark Hammond) Date: Sat, 15 Apr 2000 01:27:17 +1000 Subject: [Patches] Making modules callable when they have the attribute "__call__" In-Reply-To: <14583.13335.672195.314564@rama.research.nokia.com> Message-ID: PiAJQXR0YWNoZWQgeW91IGZpbmQgcGF0Y2hlcyB0aGF0IG1ha2UgbW9kdWxlcyANCj4gY2FsbGFi bGUgd2hlbiB0aGV5IGhhdmUNCj4gCWFuIGF0dHJpYnV0ZSAiX19jYWxsX18iLiAgSSB0aGluayB0 aGF0IHRoaXMgbWFrZXMgDQo+IFB5dGhvbiBtb2RlDQo+IAlvcnRob2dvbmFsLiBZTU1WLg0KDQpX b3VsZG50IGEgYmV0dGVyIHBhdGNoIGJlIHRvIGZpbGwgb3V0IHRoZSB0cF9jYWxsIHNsb3QgZm9y IHRoZSBtb2R1bGU/DQoNCk1hcmsuDQo= From skip@mojam.com (Skip Montanaro) Fri Apr 14 16:29:07 2000 From: skip@mojam.com (Skip Montanaro) (Skip Montanaro) Date: Fri, 14 Apr 2000 10:29:07 -0500 (CDT) Subject: [Patches] Making modules callable when they have the attribute "__call__" In-Reply-To: <14583.13335.672195.314564@rama.research.nokia.com> References: <14583.13335.672195.314564@rama.research.nokia.com> Message-ID: <14583.14659.40548.466043@beluga.mojam.com> Pekka> Attached you find patches that make modules callable when Pekka> they have an attribute "__call__". I think that this makes Pekka> Python mode orthogonal. YMMV. Pekka, Can you provide some motivation for making modules callable? It's not obvious to me that it buys you anything. -- Skip Montanaro | http://www.mojam.com/ skip@mojam.com | http://www.musi-cal.com/ From Pekka.Pessi@nokia.com Fri Apr 14 17:17:04 2000 From: Pekka.Pessi@nokia.com (Pekka Pessi) Date: Fri, 14 Apr 2000 19:17:04 +0300 (EEST) Subject: [Patches] Making modules callable when they have the attribute "__call__" In-Reply-To: <14583.14659.40548.466043@beluga.mojam.com> References: <14583.13335.672195.314564@rama.research.nokia.com> <14583.14659.40548.466043@beluga.mojam.com> <14583.14659.40548.466043@beluga.mojam.com> Message-ID: <14583.17536.445303.206607@rama.research.nokia.com> Skip Montanaro writes: > Pekka> Attached you find patches that make modules callable when > Pekka> they have an attribute "__call__". I think that this makes > Pekka> Python mode orthogonal. YMMV. >Can you provide some motivation for making modules callable? It's not >obvious to me that it buys you anything. If we have a simple extension module, say, md5, that basically defines one class/object type, say, md5, it is much cleaner to define that class/object type also as __call__. Now the single object type is sometimes called "new", sometimes something else. Pekka From Pekka.Pessi@nokia.com Fri Apr 14 17:18:57 2000 From: Pekka.Pessi@nokia.com (Pekka Pessi) Date: Fri, 14 Apr 2000 19:18:57 +0300 (EEST) Subject: [Patches] Making modules callable when they have the attribute "__call__" In-Reply-To: References: Message-ID: <14583.17649.904861.454848@rama.research.nokia.com> Mark Hammond writes: >> Attached you find patches that make modules >> callable when they have >> an attribute "__call__". I think that this makes >> Python mode >> orthogonal. YMMV. >Wouldnt a better patch be to fill out the tp_call slot for the module? Nope. Unless you want to make a module without __call__ attribute also callable. Pekka From fdrake@acm.org Fri Apr 14 17:44:33 2000 From: fdrake@acm.org (Fred L. Drake, Jr.) Date: Fri, 14 Apr 2000 12:44:33 -0400 (EDT) Subject: [Patches] Making modules callable when they have the attribute "__call__" In-Reply-To: <14583.17536.445303.206607@rama.research.nokia.com> References: <14583.13335.672195.314564@rama.research.nokia.com> <14583.14659.40548.466043@beluga.mojam.com> <14583.17536.445303.206607@rama.research.nokia.com> Message-ID: <14583.19185.200179.572807@seahag.cnri.reston.va.us> Pekka Pessi writes: > If we have a simple extension module, say, md5, that basically > defines one class/object type, say, md5, it is much cleaner to > define that class/object type also as __call__. Now the single > object type is sometimes called "new", sometimes something else. So you're looking for: import md5 hasher = md5('my data') digest = hasher.digest() Why not use: from md5 import md5 hasher = md5('my data') digest = hasher.digest() The import is the only difference, and there's no reason to think that the md5 module won't grow additional convenience functions in the future. So if it's callable, we could do this: import sha hasher = sha('my data') digest = hasher.digest() hasher = sha.new('my data') digest = hasher.digest() # new convenience function to hash data # and return the printable form print sha.hexdigest('more data') This seems confusing. I don't know of other languages which make modules into anything other than containers/namespaces. -0 -Fred -- Fred L. Drake, Jr. Corporation for National Research Initiatives From Vladimir.Marangozov@inrialpes.fr Fri Apr 14 18:15:09 2000 From: Vladimir.Marangozov@inrialpes.fr (Vladimir Marangozov) Date: Fri, 14 Apr 2000 19:15:09 +0200 (CEST) Subject: [Patches] Re: Comparison of cyclic objects (was RE: [Python-Dev] trashcan and PR#7) In-Reply-To: <14582.22650.792191.474554@bitdiddle.cnri.reston.va.us> from "Jeremy Hylton" at Apr 13, 2000 07:30:02 PM Message-ID: <200004141715.TAA02492@python.inrialpes.fr> Jeremy Hylton wrote: > > Here it is contextified. One small difference from the previous patch > is that NESTING_LIMIT is now only 1000. I think this is sufficient to > cover commonly occuring nested containers. > > Jeremy > > [patch omitted] Nice. I think you don't need the _PyCompareState_flag. Like in trashcan, _PyCompareState_nesting is enough to enter the sections of the code that depend on _PyCompareState_flag. -- Vladimir MARANGOZOV | Vladimir.Marangozov@inrialpes.fr http://sirac.inrialpes.fr/~marangoz | tel:(+33-4)76615277 fax:76615252 From jeremy@cnri.reston.va.us Fri Apr 14 20:18:53 2000 From: jeremy@cnri.reston.va.us (Jeremy Hylton) Date: Fri, 14 Apr 2000 15:18:53 -0400 (EDT) Subject: [Patches] Re: Comparison of cyclic objects (was RE: [Python-Dev] trashcan and PR#7) In-Reply-To: <200004141715.TAA02492@python.inrialpes.fr> References: <14582.22650.792191.474554@bitdiddle.cnri.reston.va.us> <200004141715.TAA02492@python.inrialpes.fr> Message-ID: <14583.28445.105079.446201@bitdiddle.cnri.reston.va.us> >>>>> "VM" == Vladimir Marangozov writes: VM> Jeremy Hylton wrote: >> Here it is contextified. One small difference from the previous >> patch is that NESTING_LIMIT is now only 1000. I think this is >> sufficient to cover commonly occuring nested containers. >> >> Jeremy >> >> [patch omitted] VM> Nice. VM> I think you don't need the _PyCompareState_flag. Like in VM> trashcan, _PyCompareState_nesting is enough to enter the VM> sections of the code that depend on _PyCompareState_flag. Right. Thanks for the suggestion, and thanks to Barry & Fred for theirs. I've checked in the changes. Jeremy From cgw@fnal.gov Fri Apr 14 21:42:19 2000 From: cgw@fnal.gov (Charles G Waldman) Date: Fri, 14 Apr 2000 15:42:19 -0500 (CDT) Subject: [Patches] Memory leaks in Python 1.6 Message-ID: <14583.33451.120821.695270@buffalo.fnal.gov> I've been running a small script I wrote called "leaktest" (attached below) which runs tests from the the Python/Lib/test directory in a loop, while watching the memory use of the process. I've found quite a few memory leaks this way, and am working on fixing them. I will be submitting a bunch of patches to the patches list over the next several days. Script: leaktest.py #!/usr/bin/env python """ Runs tests repeatedly, looking for memory leaks If you have gnuplot installed you can also get nice plots of memory usage vs. time Usage: leaktest [-max max] [-min min] [-check check] [testname] [testname]... runs one or more tests repeatedly, looking for memory leaks The tests can be specified as module name (test_gzip) or file name (/path/to/test_gzip.py) memory usage is checked every "check" iterations of the test. at least "min" readings are taken, and at most "max" readings. If no memory leak is detected after "min", the test stops. If "DO_LOG" is set to 1, memory usage will be logged to a file. If "DO_PLOT" is set to 1, pretty pictures will be drawn. If "VERBOSE" is set to 1, memory usage will be printed during the test """ import sys import os import time import string DO_LOG=1 DO_PLOT=1 VERBOSE=0 def open_file(name): if os.path.exists(name): os.system("cp -b %s %s.bak"%(name,name)) f=open(name,'w') return f def mem_usage(pid): p=os.popen('ps uwp %s'%pid) lines=p.readlines() status=p.close() if status or len(lines)!=2: return None return int(string.split(lines[1])[4]) def no_increase(l): for i in xrange(1,len(l)): if l[i]>l[i-1]: return 0 return 1 def run_test(testname, min_readings=10, max_readings=50, check_interval=10): print "RUN %s min %d max %d check %d"%(testname,min_readings, max_readings, check_interval) if DO_LOG: log = open_file('%s.log'%testname) logdata=[] ret=1 pid=os.getpid() stdout, stderr = sys.stdout, sys.stderr sys.stdout, sys.stderr = open_file('%s.out'%testname), open_file('%s.err'%testname) for loop_readings in xrange(max_readings): mem = mem_usage(pid) if not mem: break if VERBOSE: stdout.write('%s\n'%mem) logdata.append(mem) if DO_LOG: log.write('%s\n'%mem) log.flush() for n in xrange(check_interval): try: if loop_readings==0: exec "import test.%s"%testname else: exec('reload(test.%s)'%testname) except: ret=-1 break if ret<0: break if len(logdata)>=min_readings and no_increase(logdata[-min_readings:]): ret=0 break sys.stdout.close() sys.stderr.close() sys.stdout, sys.stderr = stdout, stderr if DO_LOG: log.close() return ret, logdata def do_plot(testname): cmdfile=open('%s.gnuplot' % testname, 'w') template='set nokey\nset xlabel "Iterations"\nset ylabel "Memory Use (KB)"\n\ set title "%s\nplot "%s" with lines\npause 60\n' cmdfile.write(template % (testname, testname+'.log')) cmdfile.close() os.system("gnuplot %s.gnuplot &"%testname) def main(args): check_interval=10 min_readings=10 max_readings=50 while args: arg = args.pop(0) if arg=='-min': min_readings = int(args.pop(0)) continue if arg=='-max': max_readings = int(args.pop(0)) continue if arg=='-check': check_interval = int(args.pop(0)) continue ## allow the test module names to be specified as full pathnames ## for ease in calling this from shellscripts arg = os.path.split(arg)[1] arg = os.path.splitext(arg)[0] status, data=run_test(arg, min_readings, max_readings, check_interval) if status<0: print "test", arg, "did not run" elif status==0: print arg, "no memory leak detected", data else: print arg, "leaks memory", data if DO_PLOT: do_plot(arg) if __name__ == '__main__': main(sys.argv[1:]) From cgw@fnal.gov Fri Apr 14 22:00:08 2000 From: cgw@fnal.gov (Charles G Waldman) Date: Fri, 14 Apr 2000 16:00:08 -0500 (CDT) Subject: [Patches] Fix for memory leak in test_cpickle Message-ID: <14583.34520.183725.620111@buffalo.fnal.gov> Problem description: Run the following script: import test.test_cpickle for x in xrange(1000000): reload(test.test_cpickle) Watch Python's memory use go up up and away! In the course of debugging this I also saw that cPickle is inconsistent with pickle - if you attempt a pickle.load or pickle.dump on a closed file, you get a ValueError, whereas the corresponding cPickle operations give an IOError. Since cPickle is advertised as being compatible with pickle, I changed these exceptions to match. Index: Modules/cPickle.c =================================================================== RCS file: /projects/cvsroot/python/dist/src/Modules/cPickle.c,v retrieving revision 2.39 diff -c -r2.39 cPickle.c *** cPickle.c 2000/03/10 23:11:40 2.39 --- cPickle.c 2000/04/14 20:55:20 *************** *** 2151,2169 **** Py_INCREF(file); else file=Pdata_New(); ! ! self->file = file; ! UNLESS (self->memo = PyDict_New()) { ! Py_XDECREF((PyObject *)self); ! return NULL; ! } if (PyFile_Check(file)) { self->fp = PyFile_AsFile(file); if (self->fp == NULL) { ! PyErr_SetString(PyExc_IOError, "output file closed"); ! return NULL; } self->write_func = write_file; } --- 2151,2168 ---- Py_INCREF(file); else file=Pdata_New(); ! ! UNLESS (self->file = file) ! goto err; ! UNLESS (self->memo = PyDict_New()) ! goto err; if (PyFile_Check(file)) { self->fp = PyFile_AsFile(file); if (self->fp == NULL) { ! PyErr_SetString(PyExc_ValueError, "I/O operation on closed file"); ! goto err; } self->write_func = write_file; } *************** *** 4054,4063 **** self->safe_constructors = NULL; self->find_class = NULL; ! UNLESS (self->memo = PyDict_New()) { ! Py_XDECREF((PyObject *)self); ! return NULL; ! } Py_INCREF(f); self->file = f; --- 4053,4060 ---- self->safe_constructors = NULL; self->find_class = NULL; ! UNLESS (self->memo = PyDict_New()) ! goto err; Py_INCREF(f); self->file = f; *************** *** 4066,4073 **** if (PyFile_Check(f)) { self->fp = PyFile_AsFile(f); if (self->fp == NULL) { ! PyErr_SetString(PyExc_IOError, "input file closed"); ! return NULL; } self->read_func = read_file; self->readline_func = readline_file; --- 4063,4070 ---- if (PyFile_Check(f)) { self->fp = PyFile_AsFile(f); if (self->fp == NULL) { ! PyErr_SetString(PyExc_ValueError, "I/O operation on closed file"); ! goto err; } self->read_func = read_file; self->readline_func = readline_file; Index: Lib/test/test_cpickle.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/test/test_cpickle.py,v retrieving revision 1.4 diff -c -r1.4 test_cpickle.py *** test_cpickle.py 1999/07/13 15:23:42 1.4 --- test_cpickle.py 2000/04/14 20:55:30 *************** *** 79,96 **** f.close() try: cPickle.dump(123, f) ! except IOError: pass else: ! print "dump to closed file should raise IOError" f = open(fn, "r") f.close() try: cPickle.load(f) ! except IOError: pass else: ! print "load from closed file should raise IOError" os.remove(fn) # Test specific bad cases --- 79,96 ---- f.close() try: cPickle.dump(123, f) ! except ValueError: pass else: ! print "dump to closed file should raise ValueError" f = open(fn, "r") f.close() try: cPickle.load(f) ! except ValueError: pass else: ! print "load from closed file should raise ValueError" os.remove(fn) # Test specific bad cases Disclaimer: I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. From mhammond@skippinet.com.au Sat Apr 15 02:49:16 2000 From: mhammond@skippinet.com.au (Mark Hammond) Date: Sat, 15 Apr 2000 11:49:16 +1000 Subject: [Patches] Making modules callable when they have the attribute "__call__" In-Reply-To: <14583.17649.904861.454848@rama.research.nokia.com> Message-ID: > Mark Hammond writes: > > >> Attached you find patches that make modules > >> callable when they have > >> an attribute "__call__". I think that this makes > >> Python mode > >> orthogonal. YMMV. > > >Wouldnt a better patch be to fill out the tp_call slot > for the module? > > Nope. Unless you want to make a module without > __call__ attribute > also callable. I would have thought so, yes. Sort-of. You mention your motiviation as making Python more orthogonal - then IMO, calling a module with no __call__ attribute should raise an attribute error, just like attempting to call an instance with no __call__ attribute. Mark. From Pekka.Pessi@nokia.com Sat Apr 15 09:27:56 2000 From: Pekka.Pessi@nokia.com (Pekka Pessi) Date: Sat, 15 Apr 2000 11:27:56 +0300 (EEST) Subject: [Patches] Making modules callable when they have the attribute "__call__" In-Reply-To: <14583.19185.200179.572807@seahag.cnri.reston.va.us> References: <14583.13335.672195.314564@rama.research.nokia.com> <14583.14659.40548.466043@beluga.mojam.com> <14583.17536.445303.206607@rama.research.nokia.com> <14583.19185.200179.572807@seahag.cnri.reston.va.us> <14583.14659.40548.466043@beluga.mojam.com> <14583.17536.445303.206607@rama.research.nokia.com> <14583.19185.200179.572807@seahag.cnri.reston.va.us> Message-ID: <14584.10252.273754.530946@rama.research.nokia.com> Fred L. Drake, Jr. writes: >Pekka Pessi writes: > > If we have a simple extension module, say, md5, that basically > > defines one class/object type, say, md5, it is much cleaner to > > define that class/object type also as __call__. Now the single > > object type is sometimes called "new", sometimes something else. > So you're looking for: > import md5 > hasher = md5('my data') > digest = hasher.digest() Actually, I'm looking something like import socket s = socket(socket.AF_INET6, socket.SOCK_SECKPACKET) where the __call__ in the socket module is something like a factory. ... > This seems confusing. I don't know of other languages which make >modules into anything other than containers/namespaces. What is a Python instance but a container/namespace? Pekka From gstein@lyra.org Sat Apr 15 18:35:15 2000 From: gstein@lyra.org (Greg Stein) Date: Sat, 15 Apr 2000 10:35:15 -0700 (PDT) Subject: [Patches] Proposal To Modifying Map Function in 1.6 In-Reply-To: <14583.12058.856533.820813@beluga.mojam.com> Message-ID: On Fri, 14 Apr 2000, Skip Montanaro wrote: > > Zaur wrote: > > ... patch for map() change ... > > ... another view on map() ... > > Given the somewhat arbitrary nature of choosing any of these three rules, > you might as well stay with the status quo to avoid code breakage in the > code that relies on the current semantics. There would be serious breakage should the definition of map() change. Zaur: one way to do what you'd like: map(func, List, [arg]*len(List)) Cheers, -g -- Greg Stein, http://www.lyra.org/ From cgw@alum.mit.edu Sat Apr 15 23:12:03 2000 From: cgw@alum.mit.edu (Charles G Waldman) Date: Sat, 15 Apr 2000 17:12:03 -0500 (CDT) Subject: [Patches] Fix for memory leak in _PyResize_Tuple Message-ID: <14584.59699.721573.716990@sirius.net.home> In the course of testing for memory leaks I found this gem in test_extcall (there are actually several different memory leaks triggered by test_extcall, this is only the first of several fixes, which I am submitting as separate patches). Test Case: run the following code: class Nothing: def __len__(self): return 5 def __getitem__(self, i): if i < 3: return i else: raise IndexError, i def g(a,*b,**c): return for x in xrange(1000000): g(*Nothing()) and watch Python's memory use go up and up. Diagnosis: The analysis begins with the call to PySequence_Tuple at line 1641 in ceval.c - the argument to g is seen to be a sequence but not a tuple, so it needs to be converted from an abstract sequence to a concrete tuple. PySequence_Tuple starts off by creating a new tuple of length 5 (line 1122 in abstract.c). Then at line 1149, since only 3 elements were assigned, _PyTuple_Resize is called to make the 5-tuple into a 3-tuple. When we're all done the 3-tuple is decrefed, but rather than being freed it is placed on the free_tuples cache. The basic problem is that the 3-tuples are being added to the cache but never picked up again, since _PyTuple_Resize doesn't make use of the free_tuples cache. If you are resizing a 5-tuple to a 3-tuple and there is already a 3-tuple in free_tuples[3], instead of using this tuple, _PyTuple_Resize will realloc the 5-tuple to a 3-tuple. It would more efficient to use the existing 3-tuple and cache the 5-tuple. By making _PyTuple_Resize aware of the free_tuples (just as PyTuple_New), we not only save a few calls to realloc, but also prevent this misbehavior whereby tuples are being added to the free_tuples list but never properly "recycled". Patch: Index: Objects/tupleobject.c =================================================================== RCS file: /projects/cvsroot/python/dist/src/Objects/tupleobject.c,v retrieving revision 2.30 diff -c -r2.30 tupleobject.c *** tupleobject.c 2000/03/13 16:01:29 2.30 --- tupleobject.c 2000/04/15 22:08:27 *************** *** 469,482 **** Py_XDECREF(v->ob_item[i]); v->ob_item[i] = NULL; } ! sv = (PyTupleObject *) ! realloc((char *)v, ! sizeof(PyTupleObject) + newsize * sizeof(PyObject *)); ! *pv = (PyObject *) sv; ! if (sv == NULL) { ! PyMem_DEL(v); ! PyErr_NoMemory(); ! return -1; } _Py_NewReference((PyObject *)sv); for (i = sv->ob_size; i < newsize; i++) --- 469,515 ---- Py_XDECREF(v->ob_item[i]); v->ob_item[i] = NULL; } ! #if MAXSAVESIZE > 0 ! if (newsize == 0 && free_tuples[0]) { ! sv = free_tuples[0]; ! sv->ob_size = 0; ! Py_INCREF(sv); ! #ifdef COUNT_ALLOCS ! tuple_zero_allocs++; ! #endif ! _Py_Dealloc((PyObject*)v); ! *pv = (PyObject*) sv; ! return 0; ! } ! if (0 < newsize && newsize < MAXSAVESIZE && ! (sv = free_tuples[newsize]) != NULL) ! { ! free_tuples[newsize] = (PyTupleObject *) sv->ob_item[0]; ! #ifdef COUNT_ALLOCS ! fast_tuple_allocs++; ! #endif ! #ifdef Py_TRACE_REFS ! sv->ob_type = &PyTuple_Type; ! #endif ! for (i = 0; i < newsize; ++i){ ! sv->ob_item[i] = v->ob_item[i]; ! v->ob_item[i] = NULL; ! } ! sv->ob_size = v->ob_size; ! _Py_Dealloc((PyObject*)v); ! *pv = (PyObject *) sv; ! } else ! #endif ! { ! sv = (PyTupleObject *) ! realloc((char *)v, ! sizeof(PyTupleObject) + newsize * sizeof(PyObject *)); ! *pv = (PyObject *) sv; ! if (sv == NULL) { ! PyMem_DEL(v); ! PyErr_NoMemory(); ! return -1; ! } } _Py_NewReference((PyObject *)sv); for (i = sv->ob_size; i < newsize; i++) Disclaimer: I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. From jeremy@alum.mit.edu Sun Apr 16 21:53:43 2000 From: jeremy@alum.mit.edu (Jeremy Hylton) Date: Sun, 16 Apr 2000 16:53:43 -0400 (EDT) Subject: [Patches] Fix for memory leak in _PyResize_Tuple In-Reply-To: <14584.59699.721573.716990@sirius.net.home> References: <14584.59699.721573.716990@sirius.net.home> Message-ID: <14586.10327.527863.292916@bitdiddle.cnri.reston.va.us> >>>>> "CGW" == Charles G Waldman writes: CGW> The basic problem is that the 3-tuples are being added to the CGW> cache but never picked up again, since _PyTuple_Resize doesn't CGW> make use of the free_tuples cache. If you are resizing a CGW> 5-tuple to a 3-tuple and there is already a 3-tuple in CGW> free_tuples[3], instead of using this tuple, _PyTuple_Resize CGW> will realloc the 5-tuple to a 3-tuple. It would more efficient CGW> to use the existing 3-tuple and cache the 5-tuple. CGW> By making _PyTuple_Resize aware of the free_tuples (just as CGW> PyTuple_New), we not only save a few calls to realloc, but also CGW> prevent this misbehavior whereby tuples are being added to the CGW> free_tuples list but never properly "recycled". Question about this patch: Is it always more efficient to re-use a tuple (and update all the ob_item pointers)? Or are there cases where it would be more efficient to realloc and avoid the cost of updating the pointers? There's another problem with the current strategy for reusing tuples that we might fix at the same time. If a program creates a large number of tuples, later releases them all, and never creates any more tuples of the same size, that memory will live forever on the free list. If I have a program that creates a million 3-tuples at one blow, that memory will never get freed. It should be possible to fix this problem by keeping track of the size of each freelist and never letting it exceed some maximum size. If it actually ends up being more efficient to realloc than copy, then this patch would limit the amount of loss caused by oddball cases like calling PyObject_Sequence on an instance that overstates its size. Jeremy Index: Objects/tupleobject.c =================================================================== RCS file: /projects/cvsroot/python/dist/src/Objects/tupleobject.c,v retrieving revision 2.30 diff -c -r2.30 tupleobject.c *** tupleobject.c 2000/03/13 16:01:29 2.30 --- tupleobject.c 2000/04/16 20:51:36 *************** *** 42,47 **** --- 42,49 ---- tuple () of which at most one instance will be allocated. */ static PyTupleObject *free_tuples[MAXSAVESIZE]; + static int free_length[MAXSAVESIZE]; + #define MAX_FREE_LENGTH 100 #endif #ifdef COUNT_ALLOCS int fast_tuple_allocs; *************** *** 71,76 **** --- 73,79 ---- (op = free_tuples[size]) != NULL) { free_tuples[size] = (PyTupleObject *) op->ob_item[0]; + free_length[size]--; #ifdef COUNT_ALLOCS fast_tuple_allocs++; #endif *************** *** 178,186 **** while (--i >= 0) Py_XDECREF(op->ob_item[i]); #if MAXSAVESIZE > 0 ! if (op->ob_size < MAXSAVESIZE) { op->ob_item[0] = (PyObject *) free_tuples[op->ob_size]; free_tuples[op->ob_size] = op; goto done; /* return */ } #endif --- 181,195 ---- while (--i >= 0) Py_XDECREF(op->ob_item[i]); #if MAXSAVESIZE > 0 ! if ((op->ob_size < MAXSAVESIZE) ! && (free_tuples[op->ob_size] != NULL ! && free_length[op->ob_size] < MAX_FREE_LENGTH)) { op->ob_item[0] = (PyObject *) free_tuples[op->ob_size]; free_tuples[op->ob_size] = op; + if (free_tuples[op->ob_size] == NULL) + free_length[op->ob_size] = 1; + else + free_length[op->ob_size]++; goto done; /* return */ } #endif From cgw@fnal.gov Mon Apr 17 03:19:19 2000 From: cgw@fnal.gov (Charles G Waldman) Date: Sun, 16 Apr 2000 21:19:19 -0500 (CDT) Subject: [Patches] Fix for memory leak in _PyResize_Tuple In-Reply-To: <14586.10327.527863.292916@bitdiddle.cnri.reston.va.us> References: <14584.59699.721573.716990@sirius.net.home> <14586.10327.527863.292916@bitdiddle.cnri.reston.va.us> Message-ID: <14586.29863.886669.766779@buffalo.fnal.gov> Jeremy Hylton writes: > > Question about this patch: Is it always more efficient to re-use a > tuple (and update all the ob_item pointers)? Or are there cases where > it would be more efficient to realloc and avoid the cost of updating > the pointers? According to Webster's, "efficient" has two meanings: 1: immediately effecting 2: productive of desired effects; esp : productive without waste Realloc might be (?) more efficient in sense 1 (speed), but certainly not in sense 2 (waste). It just seems ecologically wrong to be keeping this heap of used tuples around for recycling, then going to the store and buying a new one when your old one doesn't fit any more, instead of looking on the recycling heap first. If speed is a great concern, the updating of the ob_item pointers could be done with a memcpy (I thought about doing it this way but the for-loop seemed clearer). > There's another problem with the current strategy for reusing tuples > that we might fix at the same time. If a program creates a large > number of tuples, later releases them all, and never creates any more > tuples of the same size, that memory will live forever on the free > list. If I have a program that creates a million 3-tuples at one > blow, that memory will never get freed. Making a limit on the size of the recycling heap is a different issue and maybe that should be done as well, but I don't think that's a reason not to fix _PyTuple_Resize. I thought about adding this too, but chose not to for the following 4 reasons: (1) I have to choose an arbitrary value for the cut-off and I don't like to impose arbitrary limits. Do you want to keep 42 free tuples? 137? 1024? Somebody else come up with the number and I'll put that in too, except that (2) I am not really 100% sure that the behavior you describe is a problem. Maybe the function that creates the million 3-tuples will run again and need to create another million 3-tuples and having them all cached will be advantageous. Or maybe not. But (4) I have been thinking about memory leaks and "ecology" and it seems to me to be a desirable property that you be able to call a function f() then call it again and again and not use up more memory on each call. (Of course I'm assuming you use the same parameters and f isn't deliberately constructed to consume memory...) To me, continuing to leak a little bit of memory on each call is worse than doing a huge alloc one time.... it's OK if the high-water mark goes up way high and doesn't recede, as long as it doesn't keep inching up. When I iterate the tests in the Python Lib/test package and plot the interpreter's memory footprint vs. iteration number, I see two distinct patterns - a monotone increasing ramp, or a "mesa". If I see the ramp, I know right away that there is leaky behavior, and I can try to fix it. (Right now I see this with the modules test_cpickle, test_extcall, test_nis, and test_unicode, and I hope to fix all of these leaks, time permitting). With a limit on the number of tuples in the freelist, there would be a third type of pattern - a ramp which flattens off when a hard-limit is reached. This seems like it would be harder to detect if you are doing memory-leak testing. > It should be possible to fix this problem by keeping track of the size > of each freelist and never letting it exceed some maximum size. If it > actually ends up being more efficient to realloc than copy, then this > patch would limit the amount of loss caused by oddball cases like > calling PyObject_Sequence on an instance that overstates its size. Yes, it's an oddball case, but it came from Python's own test suite! (I'm not devious enough to have come up with this one, I don't think). Ideally, no matter what you throw at it, you should be able to get Python to exhibit signs of insidious memory leaks, especially not running the built-in test suite. "Limiting the loss" is less elegant than not allowing it to happen in the first place. If the limit was 1024 I could run the "text_extcall" test 1000 times and think I saw a memory leak. From jeremy@cnri.reston.va.us Mon Apr 17 04:31:39 2000 From: jeremy@cnri.reston.va.us (Jeremy Hylton) Date: Sun, 16 Apr 2000 23:31:39 -0400 (EDT) Subject: [Patches] Fix for memory leak in _PyResize_Tuple In-Reply-To: <14586.29863.886669.766779@buffalo.fnal.gov> References: <14584.59699.721573.716990@sirius.net.home> <14586.10327.527863.292916@bitdiddle.cnri.reston.va.us> <14586.29863.886669.766779@buffalo.fnal.gov> Message-ID: <14586.34203.790440.916175@bitdiddle.cnri.reston.va.us> >>>>> "CGW" == Charles G Waldman writes: CGW> Jeremy Hylton writes: >> Question about this patch: Is it always more efficient to re-use >> a tuple (and update all the ob_item pointers)? Or are there >> cases where it would be more efficient to realloc and avoid the >> cost of updating the pointers? CGW> According to Webster's, "efficient" has two meanings: 1: CGW> immediately effecting 2: productive of desired effects; esp : CGW> productive without waste CGW> Realloc might be (?) more efficient in sense 1 (speed), but CGW> certainly not in sense 2 (waste). It just seems ecologically CGW> wrong to be keeping this heap of used tuples around for CGW> recycling, then going to the store and buying a new one when CGW> your old one doesn't fit any more, instead of looking on the CGW> recycling heap first. If speed is a great concern, the CGW> updating of the ob_item pointers could be done with a memcpy (I CGW> thought about doing it this way but the for-loop seemed CGW> clearer). The list of free tuples is, I assume, a speed optimization. If speed were not an issue, it would be simplest by far to use malloc and free each time. If the free list is a speed optimization, it seems sensible to consider that issue. I think your proposed patch looks reasonable, but I didn't know what values to use for the cost model. (How frequently does realloc move the pointer? How much does that cost? How much does the pointer update cost?) Performance may not be a crucial issue here, since _PyTuple_Resize is used three times in the Python core, but seems worth considering. >> There's another problem with the current strategy for reusing >> tuples that we might fix at the same time. If a program creates >> a large number of tuples, later releases them all, and never >> creates any more tuples of the same size, that memory will live >> forever on the free list. If I have a program that creates a >> million 3-tuples at one blow, that memory will never get freed. CGW> Making a limit on the size of the recycling heap is a different CGW> issue and maybe that should be done as well, but I don't think CGW> that's a reason not to fix _PyTuple_Resize. It's a related issue. If the cost of the patch is much greater than the cost of realloc (not saying that it is), then it may be worth leaving realloc alone. CGW> I thought about adding this too, but chose not to for the CGW> following 4 reasons: (1) I have to choose an arbitrary value CGW> for the cut-off and I don't like to impose arbitrary limits. CGW> Do you want to keep 42 free tuples? 137? 1024? Somebody else CGW> come up with the number and I'll put that in too, except that Yes. Arbitrary constants are worrisome, but I think not worrisome enough to leave 2,000,000 unused 10-tuples on the free list indefinitely :-). CGW> (2) I am not really 100% sure that the behavior you describe is CGW> a problem. Maybe the function that creates the million CGW> 3-tuples will run again and need to create another million CGW> 3-tuples and having them all cached will be advantageous. Or I think it's a bug because it is a surprising effect. If you create and then free a lot of tuples, it seems unfortunate that a speed optimization causes memory utilization to stay high. CGW> maybe not. But (4) I have been thinking about memory leaks and CGW> "ecology" and it seems to me to be a desirable property that CGW> you be able to call a function f() then call it again and again CGW> and not use up more memory on each call. (Of course I'm CGW> assuming you use the same parameters and f isn't deliberately CGW> constructed to consume memory...) To me, continuing to leak a CGW> little bit of memory on each call is worse than doing a huge CGW> alloc one time.... it's OK if the high-water mark goes up way CGW> high and doesn't recede, as long as it doesn't keep inching up. I'm not sure I'm convinced. I don't think it matters who the tank fills up (a little at a time or all at once), if the program doesn't need the memory it should remain in use because of some detail of the language implementation. CGW> When I iterate the tests in the Python Lib/test package and CGW> plot the interpreter's memory footprint vs. iteration number, I CGW> see two distinct patterns - a monotone increasing ramp, or a CGW> "mesa". If I see the ramp, I know right away that there is CGW> leaky behavior, and I can try to fix it. (Right now I see this CGW> with the modules test_cpickle, test_extcall, test_nis, and CGW> test_unicode, and I hope to fix all of these leaks, time CGW> permitting). Great! >> It should be possible to fix this problem by keeping track of the >> size of each freelist and never letting it exceed some maximum >> size. If it actually ends up being more efficient to realloc >> than copy, then this patch would limit the amount of loss caused >> by oddball cases like calling PyObject_Sequence on an instance >> that overstates its size. CGW> Yes, it's an oddball case, but it came from Python's own test CGW> suite! (I'm not devious enough to have come up with this one, CGW> I don't think). I'll take that as a compliment! I was feeling devious when I wrote it :-). CGW> Ideally, no matter what you throw at it, you CGW> should be able to get Python to exhibit signs of insidious CGW> memory leaks, especially not running the built-in test suite. Yes. CGW> "Limiting the loss" is less elegant than not allowing it to CGW> happen in the first place. If the limit was 1024 I could run CGW> the "text_extcall" test 1000 times and think I saw a memory CGW> leak. I think "limiting the loss" is a less elegant solution to the problem you discovered, but I think the second problem is worth solving, too. Jeremy From anthony@interlink.com.au Mon Apr 17 06:37:17 2000 From: anthony@interlink.com.au (Anthony Baxter) Date: Mon, 17 Apr 2000 15:37:17 +1000 Subject: [Patches] support for writing pre-formatted ULAW samples in sunau. Message-ID: <200004170537.PAA03485@mbuna.arbhome.com.au> The sunau module's write objects assume that the data that's coming in is always in linear format. When taking some existing data that's in ULAW, and writing it out as ULAW, you have to use audioop.ulaw2lin, then let the sunau module convert it back - not exactly the most pleasant approach (I also find a loss of quality). As a workaround for this, I added a formatted_ flag to writeframes() and writeframesraw() - if this is set, it doesn't do the audioop conversion. Couple of questions: Is this appropriate to add to the library (I think so, but... ?) Is this the best way? Which other modules should be similarly modified, if this is appropriate? (aifc, wave)? I'm willing to fix these to match, if this is deemed an appropriate change... ta, Anthony *** /opt/python152/lib/python1.5/sunau.py Tue May 25 22:26:50 1999 --- sunau.py Mon Apr 17 15:29:56 2000 *************** *** 377,394 **** def tell(self): return self._nframeswritten ! def writeframesraw(self, data): self._ensure_header_written() nframes = len(data) / self._framesize ! if self._comptype == 'ULAW': import audioop data = audioop.lin2ulaw(data, self._sampwidth) self._file.write(data) self._nframeswritten = self._nframeswritten + nframes self._datawritten = self._datawritten + len(data) ! def writeframes(self, data): ! self.writeframesraw(data) if self._nframeswritten != self._nframes or \ self._datalength != self._datawritten: self._patchheader() --- 377,394 ---- def tell(self): return self._nframeswritten ! def writeframesraw(self, data, formatted_=0): self._ensure_header_written() nframes = len(data) / self._framesize ! if self._comptype == 'ULAW' and not formatted_: import audioop data = audioop.lin2ulaw(data, self._sampwidth) self._file.write(data) self._nframeswritten = self._nframeswritten + nframes self._datawritten = self._datawritten + len(data) ! def writeframes(self, data, formatted_=0): ! self.writeframesraw(data, formatted_) if self._nframeswritten != self._nframes or \ self._datalength != self._datawritten: self._patchheader() I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. -- Anthony Baxter It's never too late to have a happy childhood. From brian@garage.co.jp Tue Apr 18 03:13:32 2000 From: brian@garage.co.jp (Brian Hooper) Date: Tue, 18 Apr 2000 02:13:32 GMT Subject: [Patches] trailing backslash breaks os.stat Message-ID: <20000418021332.91759.qmail@hotmail.com> This is a multi-part message in MIME format. ------=_NextPart_000_1bdd1a90_126466dd$11a6c204 Content-Type: text/plain; format=flowed posixmodule's posix_do_stat simply calls the underlying OS's stat function, so it's really the underlying OS's fault, but a trailing backslash in the path on a call to os.stat on NT returns an error rather than the file info; this seems inconsistent with stat on other platforms, where a trailing forward slash is OK. A dos 'dir \temp\' with a trailing backslash, for example, also works, but stat on that same directory will fail. A path which is too long will also blow up the library call. The patch attempts to correct the above two issues. The patch was written by Don Bennett (dpb@infoseek.com), and only tweaked by me. --Brian Hooper ---- I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. ______________________________________________________ Get Your Private, Free Email at http://www.hotmail.com ------=_NextPart_000_1bdd1a90_126466dd$11a6c204 Content-Type: text/plain; name="posixmodule.patch.txt"; format=flowed Content-Transfer-Encoding: 8bit Content-Disposition: attachment; filename="posixmodule.patch.txt" *** Modules/posixmodule.c Thu Apr 13 08:20:40 2000 --- Modules.new/posixmodule.c Mon Apr 17 16:09:09 2000 *************** *** 549,556 **** --- 549,577 ---- struct stat st; char *path; int res; + + #ifdef MS_WIN32 + int pathlen; + #endif /* MS_WIN32 */ + if (!PyArg_ParseTuple(args, format, &path)) return NULL; + + #ifdef MS_WIN32 + pathlen = strlen(path); + /* the library call can blow up if the file name is too long! */ + if (pathlen > MAX_PATH) { + errno = ENAMETOOLONG; + return posix_error(); + } + + if (!((pathlen==3) && (path[1] == ':') && (path[2] == '\\'))) { + if ((pathlen > 0) && (path[pathlen-1] == '\\')) { + path[pathlen-1] = 0; /* nuke the trailing backslash */ + } + } + #endif /* MS_WIN32 */ + Py_BEGIN_ALLOW_THREADS res = (*statfunc)(path, &st); Py_END_ALLOW_THREADS ------=_NextPart_000_1bdd1a90_126466dd$11a6c204-- From cgw@fnal.gov Tue Apr 18 23:52:02 2000 From: cgw@fnal.gov (Charles G Waldman) Date: Tue, 18 Apr 2000 17:52:02 -0500 (CDT) Subject: [Patches] Revised patch for _PyResize_Tuple memory leak Message-ID: <14588.59154.860973.528863@buffalo.fnal.gov> This patch replaces my submission of Sun, 16 Apr and addresses Jeremy Hylton's suggestions that we also limit the size of the free tuple list. I chose 2000 as the maximum number of tuples of any particular size to save. There was also a problem with the previous version of this patch causing a core dump if Python was built with Py_TRACE_REFS. This is fixed in the below version of the patch, which uses tupledealloc instead of _Py_Dealloc. Disclaimer: I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. Index: Objects/tupleobject.c =================================================================== RCS file: /projects/cvsroot/python/dist/src/Objects/tupleobject.c,v retrieving revision 2.30 diff -c -r2.30 tupleobject.c *** tupleobject.c 2000/03/13 16:01:29 2.30 --- tupleobject.c 2000/04/18 20:36:10 *************** *** 33,47 **** #include "Python.h" #ifndef MAXSAVESIZE ! #define MAXSAVESIZE 20 #endif #if MAXSAVESIZE > 0 ! /* Entries 1 upto MAXSAVESIZE are free lists, entry 0 is the empty tuple () of which at most one instance will be allocated. */ static PyTupleObject *free_tuples[MAXSAVESIZE]; #endif #ifdef COUNT_ALLOCS int fast_tuple_allocs; --- 33,52 ---- #include "Python.h" + /* Speed optimization to avoid frequent malloc/free of small tuples */ #ifndef MAXSAVESIZE ! #define MAXSAVESIZE 20 /* Largest tuple to save on free list */ #endif + #ifndef MAXSAVEDTUPLES + #define MAXSAVEDTUPLES 2000 /* Maximum number of tuples of each size to save */ + #endif #if MAXSAVESIZE > 0 ! /* Entries 1 up to MAXSAVESIZE are free lists, entry 0 is the empty tuple () of which at most one instance will be allocated. */ static PyTupleObject *free_tuples[MAXSAVESIZE]; + static int num_free_tuples[MAXSAVESIZE]; #endif #ifdef COUNT_ALLOCS int fast_tuple_allocs; *************** *** 71,76 **** --- 76,82 ---- (op = free_tuples[size]) != NULL) { free_tuples[size] = (PyTupleObject *) op->ob_item[0]; + num_free_tuples[size]--; #ifdef COUNT_ALLOCS fast_tuple_allocs++; #endif *************** *** 104,109 **** --- 110,116 ---- #if MAXSAVESIZE > 0 if (size == 0) { free_tuples[0] = op; + ++num_free_tuples[0]; Py_INCREF(op); /* extra INCREF so that this is never freed */ } #endif *************** *** 171,186 **** register PyTupleObject *op; { register int i; ! Py_TRASHCAN_SAFE_BEGIN(op) ! if (op->ob_size > 0) { ! i = op->ob_size; while (--i >= 0) Py_XDECREF(op->ob_item[i]); #if MAXSAVESIZE > 0 ! if (op->ob_size < MAXSAVESIZE) { ! op->ob_item[0] = (PyObject *) free_tuples[op->ob_size]; ! free_tuples[op->ob_size] = op; goto done; /* return */ } #endif --- 178,194 ---- register PyTupleObject *op; { register int i; ! register int len = op->ob_size; Py_TRASHCAN_SAFE_BEGIN(op) ! if (len > 0) { ! i = len; while (--i >= 0) Py_XDECREF(op->ob_item[i]); #if MAXSAVESIZE > 0 ! if (len < MAXSAVESIZE && num_free_tuples[len] < MAXSAVEDTUPLES) { ! op->ob_item[0] = (PyObject *) free_tuples[len]; ! num_free_tuples[len]++; ! free_tuples[len] = op; goto done; /* return */ } #endif *************** *** 469,482 **** Py_XDECREF(v->ob_item[i]); v->ob_item[i] = NULL; } ! sv = (PyTupleObject *) ! realloc((char *)v, ! sizeof(PyTupleObject) + newsize * sizeof(PyObject *)); ! *pv = (PyObject *) sv; ! if (sv == NULL) { ! PyMem_DEL(v); ! PyErr_NoMemory(); ! return -1; } _Py_NewReference((PyObject *)sv); for (i = sv->ob_size; i < newsize; i++) --- 477,525 ---- Py_XDECREF(v->ob_item[i]); v->ob_item[i] = NULL; } ! #if MAXSAVESIZE > 0 ! if (newsize == 0 && free_tuples[0]) { ! num_free_tuples[0]--; ! sv = free_tuples[0]; ! sv->ob_size = 0; ! Py_INCREF(sv); ! #ifdef COUNT_ALLOCS ! tuple_zero_allocs++; ! #endif ! tupledealloc(v); ! *pv = (PyObject*) sv; ! return 0; ! } ! if (0 < newsize && newsize < MAXSAVESIZE && ! (sv = free_tuples[newsize]) != NULL) ! { ! free_tuples[newsize] = (PyTupleObject *) sv->ob_item[0]; ! num_free_tuples[newsize]--; ! #ifdef COUNT_ALLOCS ! fast_tuple_allocs++; ! #endif ! #ifdef Py_TRACE_REFS ! sv->ob_type = &PyTuple_Type; ! #endif ! for (i = 0; i < newsize; ++i){ ! sv->ob_item[i] = v->ob_item[i]; ! v->ob_item[i] = NULL; ! } ! sv->ob_size = v->ob_size; ! tupledealloc(v); ! *pv = (PyObject *) sv; ! } else ! #endif ! { ! sv = (PyTupleObject *) ! realloc((char *)v, ! sizeof(PyTupleObject) + newsize * sizeof(PyObject *)); ! *pv = (PyObject *) sv; ! if (sv == NULL) { ! PyMem_DEL(v); ! PyErr_NoMemory(); ! return -1; ! } } _Py_NewReference((PyObject *)sv); for (i = sv->ob_size; i < newsize; i++) From tismer@tismer.com Wed Apr 19 12:35:28 2000 From: tismer@tismer.com (Christian Tismer) Date: Wed, 19 Apr 2000 13:35:28 +0200 Subject: [Patches] Revised patch for _PyResize_Tuple memory leak References: <14588.59154.860973.528863@buffalo.fnal.gov> Message-ID: <38FD9A00.C283D205@tismer.com> Charles G Waldman wrote: > > This patch replaces my submission of Sun, 16 Apr and addresses Jeremy > Hylton's suggestions that we also limit the size of the free tuple > list. I chose 2000 as the maximum number of tuples of any particular > size to save. I think this limit is great. It limits the cashed data to about 540000 words. K, L = 3+1, 3+20 ; print reduce(lambda x,y:x+y, range(K, L+1))*2000 This makes me think of integers which are cashed as well. After some big range expressions, we have thousands of thousands of integer slots available, eating memory. In this case, things are more difficult, since integers are alloted in pages. Not so bad, but we might end up with many many pages where only a few ints are used. Any ideas how to limit this acache as well? ciao - chris -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaunstr. 26 : *Starship* http://starship.python.net 14163 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF where do you want to jump today? http://www.stackless.com From mwh21@cam.ac.uk Wed Apr 19 19:28:10 2000 From: mwh21@cam.ac.uk (Michael Hudson) Date: Wed, 19 Apr 2000 19:28:10 +0100 (BST) Subject: [Patches] docstrings for os.spawn* Message-ID: I have written some (rather poor, IMO) docstrings for the new-ish os.spawn* functions - I hope these can either go into the reposistory or provoke someone into writing better ones! I've tried to ape the style of the other docstrings in the standard library - are there any guidelines for how such things should be written? Cheers, M. I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. Index: os.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/os.py,v retrieving revision 1.31 diff -u -r1.31 os.py --- os.py 2000/04/04 19:50:04 1.31 +++ os.py 2000/04/19 18:27:30 @@ -333,17 +333,44 @@ raise error, "Not stopped, signaled or exited???" def spawnv(mode, file, args): + """spawnv(mode, file, args) -> integer + +Execute file with arguments from args in a subprocess. +If mode == P_NOWAIT return the pid of the process. +If mode == P_WAIT return the process's exit code if it exits normally; +otherwise return - (the signal that killed it). """ return _spawnvef(mode, file, args, None, execv) def spawnve(mode, file, args, env): + """spawnve(mode, file, args, env) -> integer + +Execute file with arguments from args in a subprocess with the +specified environment. +If mode == P_NOWAIT return the pid of the process. +If mode == P_WAIT return the process's exit code if it exits normally; +otherwise return -SIG, where SIG is the signal that killed it.. """ return _spawnvef(mode, file, args, env, execve) # Note: spawnvp[e] is't currently supported on Windows def spawnvp(mode, file, args): + """spawnvp(mode, file, args) -> integer + +Execute file (which is looked for along $PATH) with arguments from +args in a subprocess. +If mode == P_NOWAIT return the pid of the process. +If mode == P_WAIT return the process's exit code if it exits normally; +otherwise return -SIG, where SIG is the signal that killed it.. """ return _spawnvef(mode, file, args, None, execvp) def spawnvpe(mode, file, args, env): + """spawnvpe(mode, file, args, env) -> integer + +Execute file (which is looked for along $PATH) with arguments from +args in a subprocess with the supplied environment. +If mode == P_NOWAIT return the pid of the process. +If mode == P_WAIT return the process's exit code if it exits normally; +otherwise return -SIG, where SIG is the signal that killed it.. """ return _spawnvef(mode, file, args, env, execvpe) if _exists("spawnv"): @@ -351,9 +378,22 @@ # but can be easily implemented in Python def spawnl(mode, file, *args): + """spawnl(mode, file, *args) -> integer + +Execute file with arguments from args in a subprocess. +If mode == P_NOWAIT return the pid of the process. +If mode == P_WAIT return the process's exit code if it exits normally; +otherwise return -SIG, where SIG is the signal that killed it. """ return spawnv(mode, file, args) def spawnle(mode, file, *args): + """spawnle(mode, file, *args, env) -> integer + +Execute file with arguments from args in a subprocess with the +supplied environment. +If mode == P_NOWAIT return the pid of the process. +If mode == P_WAIT return the process's exit code if it exits normally; +otherwise return -SIG, where SIG is the signal that killed it. """ env = args[-1] return spawnve(mode, file, args[:-1], env) @@ -361,8 +401,24 @@ # At the moment, Windows doesn't implement spawnvp[e], # so it won't have spawnlp[e] either. def spawnlp(mode, file, *args): + """spawnlp(mode, file, *args, env) -> integer + +Execute file (which is looked for along $PATH) with arguments from +args in a subprocess with the supplied environment. +If mode == P_NOWAIT return the pid of the process. +If mode == P_WAIT return the process's exit code if it exits normally; +otherwise return -SIG, where SIG is the signal that killed it. """ return spawnvp(mode, file, args) def spawnlpe(mode, file, *args): + """spawnlpe(mode, file, *args, env) -> integer + +Execute file (which is looked for along $PATH) with arguments from +args in a subprocess with the supplied environment. +If mode == P_NOWAIT return the pid of the process. +If mode == P_WAIT return the process's exit code if it exits normally; +otherwise return -SIG, where SIG is the signal that killed it. """ env = args[-1] return spawnvpe(mode, file, args[:-1], env) + + From brian@garage.co.jp Thu Apr 20 02:31:56 2000 From: brian@garage.co.jp (Brian Hooper) Date: Thu, 20 Apr 2000 01:31:56 GMT Subject: [Patches] Py_BuildValue Unicode support Message-ID: <20000420013156.77083.qmail@hotmail.com> This is a multi-part message in MIME format. ------=_NextPart_000_55bdc2c8_12bfb28d$6d08a67 Content-Type: text/plain; format=flowed Hi there - There might be a nicer way to do this, but I wanted to be able to use Py_BuildValue to produce Unicode objects, so I added a few lines to modsupport to do this. Each Unicode object requires two arguments, the raw Py_UNICODE string and the length as an integer. I think since all Python Unicode strings are 0 terminated, it might be nice to make this into "U#" and also allow a plain "U" to mean a (double) null-terminated Unicode string as input; however, I'll leave that up to you all to determine (I would personally like to see this option). Bye! Brian Hooper I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. ______________________________________________________ Get Your Private, Free Email at http://www.hotmail.com ------=_NextPart_000_55bdc2c8_12bfb28d$6d08a67 Content-Type: text/plain; name="modsupport.diff.txt"; format=flowed Content-Transfer-Encoding: 8bit Content-Disposition: attachment; filename="modsupport.diff.txt" diff -c Python/modsupport.c Python.new/modsupport.c *** Python/modsupport.c Mon Apr 17 13:24:25 2000 --- Python.new/modsupport.c Wed Apr 19 17:21:52 2000 *************** *** 295,301 **** case 'L': return PyLong_FromLongLong((LONG_LONG)va_arg(*p_va, LONG _LONG)); #endif ! case 'f': case 'd': return PyFloat_FromDouble( --- 295,306 ---- case 'L': return PyLong_FromLongLong((LONG_LONG)va_arg(*p_va, LONG _LONG)); #endif ! case 'U': ! { ! Py_UNICODE *u = va_arg(*p_va, Py_UNICODE *); ! int ulen = va_arg(*p_va, int); ! return PyUnicode_FromUnicode(u, ulen); ! } case 'f': case 'd': return PyFloat_FromDouble( ------=_NextPart_000_55bdc2c8_12bfb28d$6d08a67-- From mhammond@skippinet.com.au Fri Apr 21 12:04:01 2000 From: mhammond@skippinet.com.au (Mark Hammond) Date: Fri, 21 Apr 2000 21:04:01 +1000 Subject: [Patches] Update to compiler for extended call syntax. Message-ID: Attached is a set of diffs for the .py compiler that adds support for the new extended call syntax. Jeremy - please pay close attention to the stack depth checking and lineno changes I made - these tests all complete and I think they are correct, but it is worth mentioning. NOTE - many of these files have inconsistent indentation. Time for another visit from the tabnanny! :-) I havent addressed the whitespace at all. compile.py: On Windows, use 'nul' instead of '/dev/null'. test.py: Use double-quotes for the command-line, as Windows doesnt recognise singles. compiler/ast.py: CallFunc node gets 2 new children to support extended call syntax - "star_args" (for "*args") and "dstar_args" (for "**args") compiler/pyassem.py It appear that self.lnotab is supposed to be responsible for tracking line numbers, but self.firstlineno was still hanging around. Removed self.firstlineno completely. NOTE - I didnt actually test that the generated code has the correct line numbers!! Stack depth tracking appeared a little broken - the checks never made it beyond the "self.patterns" check - thus, the custom methods were never called! Fixed this. Added support for the new extended call syntax opcodes for depth calculations. compiler/pycodegen.py Added support for the new extended call syntax opcodes. compiler/transformer.py Added support for the new extended call syntax. tests/test_func.py Added tests of the new extended call syntax. Release info: I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. Mark. begin 666 compiler_diffs.txt M26YD97@Z(&-O;7!I;&4N<'D-"CT]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T] M/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T-"E)# M4R!F:6QE.B O<')O:F5C=',O8W9S71H;VXO;F]N9&ES="]S2QV#0IR971R:65V:6YG(')E=FES:6]N(#$N M,0T*9&EF9B M8R M,R M0DR,# P+S S+S V(#$Y.C$S.C(Q"3$N,0T*+2TM(&-O;7!I;&4N<'D),C P M,"\P-"\R,2 Q,#HT-3HT,PT**BHJ*BHJ*BHJ*BHJ*BHJ#0HJ*BH@,3$L,3<@ M*BHJ*@T*(" @(" @(" @(" @("!615)"3U-%(#T@,0T*(" @(" @(" @(" @ M("!V:7-I=&]R+D%35%9I7,N<&QA=&9O0DR,# P M+S R+S$P(#$W.C,T.C$R"3$N- T*+2TM('1E71H;VX@+BXO8V]M<&EL92YP>2 M<2 E7-T96TH(F1I9F8@ M+6,@)7,@)7,B("4@*"(E'0B("4@*&]U='!U=$1I71H M;VX@+6,@(FEM<&]R=" E7=O7=O7=O#H@8V]M<&EL97(O<'EA0T*/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T] M/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/0T*4D-3(&9I;&4Z("]P6%S6%S0DR,# P+S T M+S(Q(#$P.C0U.C0U#0HJ*BHJ*BHJ*BHJ*BHJ*BH-"BHJ*B Q-#DL,34U("HJ M*BH-"B @"2 @("!S96QF+F9L86=S(#T@0T]?3U!424U)6D5$('P@0T]?3D57 M3$]#04Q3( T*(" )96QS93H-"B @"2 @("!S96QF+F9L86=S(#T@, T*+2 ) M2QV#0IR971R:65V:6YG M(')E=FES:6]N(#$N,3D-"F1I9F8@+6,@+3,@+7(Q+C$Y('!Y8V]D96=E;BYP M>0T**BHJ('!Y8V]D96=E;BYP>0DR,# P+S S+S$V(#(P.C V.C4Y"3$N,3D- M"BTM+2!P>6-O9&5G96XN<'D),C P,"\P-"\R,2 Q,#HT-3HT-@T**BHJ*BHJ M*BHJ*BHJ*BHJ#0HJ*BH@.2PQ-" J*BHJ#0HM+2T@.2PR,B M+2TM#0H@(&9R M;VT@8V]M<&EL97(@:6UP;W)T('!Y87-S96TL(&UI6%SPT* M*R @(" @(R H2&%V92 J87)G0T*/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T] M/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/0T*4D-3(&9I;&4Z("]P2QV#0IR971R:65V:6YG(')E=FES:6]N(#$N M.0T*9&EF9B M8R M,R M0T**BHJ('1R86YS M9F]R;65R+G!Y"3(P,# O,#,O,38@,C Z,#,Z,#0),2XY#0HM+2T@=')A;G-F M;W)M97(N<'D),C P,"\P-"\R,2 Q,#HT-3HT.0T**BHJ*BHJ*BHJ*BHJ*BHJ M#0HJ*BH@.3@T+#DY,R J*BHJ#0H@(" @(" @(')E='5R;B!.;V1E*"=C86QL M7V9U;F,G+"!P4YO9&4L(%L@72D-"B @(" @(&%R9W,@/2!;(%T- M"B @(" @(&MW(#T@, T*(2 @(" @;&5N7VYO9&5L:7-T(#T@;&5N*&YO9&5L M:7-T*0T*(2 @(" @9F]R(&D@:6X@6YT87A%6YT87A%7!E.B E4YO9&4L(&%R9W,L('-T87)?;F]D92P@9'-T M87)?;F]D92D-"B @#0H@(" @9&5F(&-O;5]A0T*/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T] M/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/0T*4D-3(&9I;&4Z("]PR=Y)SHP+" G>B"X-"BL@(" @('!R:6YT('1E3TP+'H],"P@*F%R9W,I#0HK(" @("!K=V%R9W,@/2![)V$G M.C$L("=C)SHT?0T**R @(" @<')I;G0@=&5S=#$H("HJ:W=A References: <20000420013156.77083.qmail@hotmail.com> Message-ID: <200004211832.OAA16628@eric.cnri.reston.va.us> > There might be a nicer way to do this, but I wanted to be able to > use Py_BuildValue to produce Unicode objects, so I added a few > lines to modsupport to do this. Each Unicode object requires > two arguments, the raw Py_UNICODE string and the length as an > integer. I think since all Python Unicode strings are 0 terminated, > it might be nice to make this into "U#" and also allow a plain "U" > to mean a (double) null-terminated Unicode string as input; however, > I'll leave that up to you all to determine (I would personally like > to see this option). Yes, what you coded here should be called U#. --Guido van Rossum (home page: http://www.python.org/~guido/) From guido@python.org Fri Apr 21 19:50:02 2000 From: guido@python.org (Guido van Rossum) Date: Fri, 21 Apr 2000 14:50:02 -0400 Subject: [Patches] trailing backslash breaks os.stat In-Reply-To: Your message of "Tue, 18 Apr 2000 02:13:32 GMT." <20000418021332.91759.qmail@hotmail.com> References: <20000418021332.91759.qmail@hotmail.com> Message-ID: <200004211850.OAA16684@eric.cnri.reston.va.us> Brian, Thanks for this patch. As presented, it's got one flaw: it modifies an incoming string object. I've changed this by making a copy in a buffer on the stack. I'm also taking the liberty to swap the tests for trailing backslash with the test for the drive root (and add a comment to the latter). Here's the modified patch, which I'll check in in a bit: Index: posixmodule.c =================================================================== RCS file: /projects/cvsroot/python/dist/src/Modules/posixmodule.c,v retrieving revision 2.130 diff -c -r2.130 posixmodule.c *** posixmodule.c 2000/04/13 15:20:40 2.130 --- posixmodule.c 2000/04/21 18:48:42 *************** *** 549,556 **** --- 549,584 ---- struct stat st; char *path; int res; + + #ifdef MS_WIN32 + int pathlen; + char pathcopy[MAX_PATH]; + #endif /* MS_WIN32 */ + if (!PyArg_ParseTuple(args, format, &path)) return NULL; + + #ifdef MS_WIN32 + pathlen = strlen(path); + /* the library call can blow up if the file name is too long! */ + if (pathlen > MAX_PATH) { + errno = ENAMETOOLONG; + return posix_error(); + } + + if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) { + /* exception for drive root */ + if (!((pathlen == 3) && + (path[1] == ':') && + (path[2] == '\\' || path[2] == '/'))) + { + strncpy(pathcopy, path, pathlen); + pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */ + path = pathcopy; + } + } + #endif /* MS_WIN32 */ + Py_BEGIN_ALLOW_THREADS res = (*statfunc)(path, &st); Py_END_ALLOW_THREADS --Guido van Rossum (home page: http://www.python.org/~guido/) From guido@python.org Fri Apr 21 20:15:20 2000 From: guido@python.org (Guido van Rossum) Date: Fri, 21 Apr 2000 15:15:20 -0400 Subject: [Patches] support for writing pre-formatted ULAW samples in sunau. In-Reply-To: Your message of "Mon, 17 Apr 2000 15:37:17 +1000." <200004170537.PAA03485@mbuna.arbhome.com.au> References: <200004170537.PAA03485@mbuna.arbhome.com.au> Message-ID: <200004211915.PAA16728@eric.cnri.reston.va.us> > The sunau module's write objects assume that the data that's coming > in is always in linear format. When taking some existing data that's in > ULAW, and writing it out as ULAW, you have to use audioop.ulaw2lin, then > let the sunau module convert it back - not exactly the most pleasant > approach (I also find a loss of quality). You're right, a quick test shows that ulaw2lin + lin2ulaw changes two of the data bytes! These are the extreme values 0 and 127; somehow 0 gets mapped to 2 instead of to 0 and 127 gets mapped to 255 instead of to 127. There's explicit code in the lin2ulaw code that traps a zero output byte and replaces it with 2. This is conditional code and called "CCITT trap"; in addition, it is enabled with a comment "per MIL-STD". I wonder what this is about? Maybe it should be disabled? It turns the loudest negative value into the third-loudest negative value. This doesn't make sense to me. That explains the change of 0 -> 2. The change from 127 to 255 shouldn't make a difference: both the 127 and the 255 ULAW value map to 0 in linear space, and I understand that the reverse mapping has to pick one. It shouldn't sound any difference because of this. > As a workaround for this, I added a formatted_ flag to writeframes() and > writeframesraw() - if this is set, it doesn't do the audioop conversion. > > Couple of questions: > > Is this appropriate to add to the library (I think so, but... ?) I'm not sure. When you're just copying ULAW data, you might be better off bypassing the entire sunau module altogether; alternatively, you might subclass the Au_write class to do what you want. > Is this the best way? Not my preference. Also note that you didn't bother to add a similar feature to the readframes method. My guess is that it's a hack, not a well-thought-out feature. > Which other modules should be similarly modified, if this is appropriate? > (aifc, wave)? I'm willing to fix these to match, if this is deemed an > appropriate change... The afc.py module has similar ULAW support. But I'm not thrilled by this patch. (BTW why did you name the argument with a trailing underscore?) --Guido van Rossum (home page: http://www.python.org/~guido/) From guido@python.org Fri Apr 21 21:43:42 2000 From: guido@python.org (Guido van Rossum) Date: Fri, 21 Apr 2000 16:43:42 -0400 Subject: [Patches] Fix for memory leak in _PyResize_Tuple In-Reply-To: Your message of "Sun, 16 Apr 2000 23:31:39 EDT." <14586.34203.790440.916175@bitdiddle.cnri.reston.va.us> References: <14584.59699.721573.716990@sirius.net.home> <14586.10327.527863.292916@bitdiddle.cnri.reston.va.us> <14586.29863.886669.766779@buffalo.fnal.gov> <14586.34203.790440.916175@bitdiddle.cnri.reston.va.us> Message-ID: <200004212043.QAA17297@eric.cnri.reston.va.us> Did this ever get resolved? I personally am in Charles' camp: the problem he fixes is more serious than the problem that Jeremy wants to fix at the same time. I thought about the latter problem when I coded the free list, long ago. I decided not to lose sleep over it: it seems more likely that code which allocates a million small tuples and then releases them all will do so again soon; or will exit soon. But Charles' problem surprised me: that a simple loop like that can leak memory was not at all expected. So I propose to use Charles' patch. --Guido van Rossum (home page: http://www.python.org/~guido/) From cgw@fnal.gov Fri Apr 21 21:58:27 2000 From: cgw@fnal.gov (Charles G Waldman) Date: Fri, 21 Apr 2000 15:58:27 -0500 (CDT) Subject: [Patches] memory leaks triggered by "test_extcall" Message-ID: <14592.49395.596576.170304@buffalo.fnal.gov> Running "test_extcall" repeatedly results in memory leaks. One of these can't be fixed (at least not easily!), it happens since this code: def saboteur(**kw): kw['x'] = locals() d = {} saboteur(a=1, **d) creates a circular reference - d['x']['d']==d The others are due to some missing decrefs in ceval.c, fixed by the patch attached below. Note: I originally wrote this without the "goto", just adding the missing decref's where needed. But I think the goto is justified in keeping the executable code size of ceval as small as possible. By the way, this section of ceval is not indented according to ccpy "python" style, which makes editing it in Emacs somewhat cumbersome. I avoided re-indenting so as not to send a monster patch. What is the rule on re-indenting C sources? Disclaimer: I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. Patch: Index: Python/ceval.c =================================================================== RCS file: /projects/cvsroot/python/dist/src/Python/ceval.c,v retrieving revision 2.175 diff -c -r2.175 ceval.c *** ceval.c 2000/04/10 12:45:10 2.175 --- ceval.c 2000/04/21 20:52:04 *************** *** 1623,1630 **** if (!PyDict_Check(kwdict)) { PyErr_SetString(PyExc_TypeError, "** argument must be a dictionary"); ! x = NULL; ! break; } } if (flags & 1) { --- 1623,1629 ---- if (!PyDict_Check(kwdict)) { PyErr_SetString(PyExc_TypeError, "** argument must be a dictionary"); ! goto extcall_fail; } } if (flags & 1) { *************** *** 1632,1670 **** if (!PySequence_Check(stararg)) { PyErr_SetString(PyExc_TypeError, "* argument must be a sequence"); ! x = NULL; ! break; } /* Convert abstract sequence to concrete tuple */ if (!PyTuple_Check(stararg)) { PyObject *t = NULL; t = PySequence_Tuple(stararg); if (t == NULL) { ! x = NULL; ! break; } Py_DECREF(stararg); stararg = t; } nstar = PyTuple_GET_SIZE(stararg); if (nstar < 0) { ! x = NULL; ! break; } } if (nk > 0) { if (kwdict == NULL) { kwdict = PyDict_New(); if (kwdict == NULL) { ! x = NULL; ! break; } } else { PyObject *d = PyDict_Copy(kwdict); if (d == NULL) { ! x = NULL; ! break; } Py_DECREF(kwdict); kwdict = d; --- 1631,1664 ---- if (!PySequence_Check(stararg)) { PyErr_SetString(PyExc_TypeError, "* argument must be a sequence"); ! goto extcall_fail; } /* Convert abstract sequence to concrete tuple */ if (!PyTuple_Check(stararg)) { PyObject *t = NULL; t = PySequence_Tuple(stararg); if (t == NULL) { ! goto extcall_fail; } Py_DECREF(stararg); stararg = t; } nstar = PyTuple_GET_SIZE(stararg); if (nstar < 0) { ! goto extcall_fail; } } if (nk > 0) { if (kwdict == NULL) { kwdict = PyDict_New(); if (kwdict == NULL) { ! goto extcall_fail; } } else { PyObject *d = PyDict_Copy(kwdict); if (d == NULL) { ! goto extcall_fail; } Py_DECREF(kwdict); kwdict = d; *************** *** 1680,1686 **** PyString_AsString(key)); Py_DECREF(key); Py_DECREF(value); ! break; } err = PyDict_SetItem(kwdict, key, value); Py_DECREF(key); --- 1674,1680 ---- PyString_AsString(key)); Py_DECREF(key); Py_DECREF(value); ! goto extcall_fail; } err = PyDict_SetItem(kwdict, key, value); Py_DECREF(key); *************** *** 1689,1695 **** break; } if (err) { ! Py_DECREF(kwdict); break; } } --- 1683,1693 ---- break; } if (err) { ! extcall_fail: ! Py_XDECREF(kwdict); ! Py_XDECREF(stararg); ! Py_DECREF(func); ! x=NULL; break; } } *************** *** 2382,2387 **** --- 2380,2386 ---- if (kw != NULL && !PyDict_Check(kw)) { PyErr_SetString(PyExc_TypeError, "keyword list must be a dictionary"); + Py_DECREF(arg); return NULL; } From tismer@tismer.com Fri Apr 21 22:07:22 2000 From: tismer@tismer.com (Christian Tismer) Date: Fri, 21 Apr 2000 23:07:22 +0200 Subject: [Patches] memory leaks triggered by "test_extcall" References: <14592.49395.596576.170304@buffalo.fnal.gov> Message-ID: <3900C30A.439B562C@tismer.com> Charles G Waldman wrote: > > Running "test_extcall" repeatedly results in memory leaks. > > One of these can't be fixed (at least not easily!), it happens since > this code: > > def saboteur(**kw): > kw['x'] = locals() > d = {} > saboteur(a=1, **d) > > creates a circular reference - d['x']['d']==d Yes, but aren't we going to implant Neil's GC, soon? ciao - chris p.s.: Stackless will have it probably after Easter. -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaunstr. 26 : *Starship* http://starship.python.net 14163 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF where do you want to jump today? http://www.stackless.com From guido@python.org Fri Apr 21 22:09:38 2000 From: guido@python.org (Guido van Rossum) Date: Fri, 21 Apr 2000 17:09:38 -0400 Subject: [Patches] memory leaks triggered by "test_extcall" In-Reply-To: Your message of "Fri, 21 Apr 2000 23:07:22 +0200." <3900C30A.439B562C@tismer.com> References: <14592.49395.596576.170304@buffalo.fnal.gov> <3900C30A.439B562C@tismer.com> Message-ID: <200004212109.RAA17737@eric.cnri.reston.va.us> > Charles G Waldman wrote: > > > > Running "test_extcall" repeatedly results in memory leaks. > > > > One of these can't be fixed (at least not easily!), it happens since > > this code: > > > > def saboteur(**kw): > > kw['x'] = locals() > > d = {} > > saboteur(a=1, **d) > > > > creates a circular reference - d['x']['d']==d Christian Tismer: > Yes, but aren't we going to implant Neil's GC, soon? Maybe -- I'm a little worried that it will destabilize 1.6. Or am I too worried? Has anyone tried this yet in large amounts of production code? It *would* be nice, and Neil even mailed me the release form with a wet signature. --Guido van Rossum (home page: http://www.python.org/~guido/) From hylton@jagunet.com Fri Apr 21 22:33:15 2000 From: hylton@jagunet.com (Jeremy Hylton) Date: Fri, 21 Apr 2000 17:33:15 -0400 (EDT) Subject: [Patches] Re: Update to compiler for extended call syntax. In-Reply-To: References: Message-ID: <14592.51445.10558.56447@walden> Thanks for the patches, Mark! I won't get a chance to look at them before I leave for the weekend, but I'll get to them first thing next week. Jeremy From guido@python.org Fri Apr 21 22:37:20 2000 From: guido@python.org (Guido van Rossum) Date: Fri, 21 Apr 2000 17:37:20 -0400 Subject: [Patches] Please review before applying In-Reply-To: Your message of "Tue, 11 Apr 2000 14:25:36 +0200." <200004111225.OAA31234@localhost.localdomain> References: <200004111225.OAA31234@localhost.localdomain> Message-ID: <200004212137.RAA18210@eric.cnri.reston.va.us> Wanted: reviews for this patch! It seems usable but (as the author admits) needs another careful eye before I can apply it. --Guido van Rossum (home page: http://www.python.org/~guido/) (Fred Gansevles wrote:) > This (mega-)patch updates all the modules in the standard-module (all > Lib/*.py files) to use the new string-methods instead of the old string > module. > Most of the changes are simple translations, i.e.: > > string.split (s, sep) --> s.split (sep) > > Some of the changes also take the context into account, see: > - cgi.py > - formatter.py > - imaplib.py > > Both 'make test' and 'Lib/compileall.py Lib' produced no error-output > so I'd expect no big problems. From skip@mojam.com (Skip Montanaro) Fri Apr 21 22:42:10 2000 From: skip@mojam.com (Skip Montanaro) (Skip Montanaro) Date: Fri, 21 Apr 2000 16:42:10 -0500 (CDT) Subject: [Patches] Please review before applying In-Reply-To: <200004212137.RAA18210@eric.cnri.reston.va.us> References: <200004111225.OAA31234@localhost.localdomain> <200004212137.RAA18210@eric.cnri.reston.va.us> Message-ID: <14592.52018.694281.166186@beluga.mojam.com> Guido> Wanted: reviews for this patch! It seems usable but (as the Guido> author admits) needs another careful eye before I can apply it. I don't have time to review it, but I recall thinking when it went by that distutils might (not "will", "might") be affected by this. I know Greg is trying to make sure distutils will still work with 1.5.1. It's worth spending a few seconds considering, especially if any of Fred's patches are to the distutils subdirectory. Skip From tismer@tismer.com Fri Apr 21 22:50:39 2000 From: tismer@tismer.com (Christian Tismer) Date: Fri, 21 Apr 2000 23:50:39 +0200 Subject: [Patches] Please review before applying References: <200004111225.OAA31234@localhost.localdomain> <200004212137.RAA18210@eric.cnri.reston.va.us> Message-ID: <3900CD2F.55E35F16@tismer.com> Guido van Rossum wrote: > > Wanted: reviews for this patch! It seems usable but (as the author > admits) needs another careful eye before I can apply it. I begun skimming over it and stumbled here: --- 236,242 ---- elif requestline[-1:] == '\n': requestline = requestline[:-1] self.requestline = requestline ! words = requestline.split() if len(words) == 3: [command, path, version] = words if version[:5] != 'HTTP/': *************** Shouldn't we be consequent and use the new startswith methods as well, instead of if version[:5] != 'HTTP/' ? I think it would be better to do this all in one big shot. ciao - chris -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaunstr. 26 : *Starship* http://starship.python.net 14163 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF where do you want to jump today? http://www.stackless.com From guido@python.org Fri Apr 21 22:46:01 2000 From: guido@python.org (Guido van Rossum) Date: Fri, 21 Apr 2000 17:46:01 -0400 Subject: [Patches] Please review before applying In-Reply-To: Your message of "Fri, 21 Apr 2000 23:50:39 +0200." <3900CD2F.55E35F16@tismer.com> References: <200004111225.OAA31234@localhost.localdomain> <200004212137.RAA18210@eric.cnri.reston.va.us> <3900CD2F.55E35F16@tismer.com> Message-ID: <200004212146.RAA18313@eric.cnri.reston.va.us> > > Wanted: reviews for this patch! It seems usable but (as the author > > admits) needs another careful eye before I can apply it. > > I begun skimming over it and stumbled here: > > --- 236,242 ---- > elif requestline[-1:] == '\n': > requestline = requestline[:-1] > self.requestline = requestline > ! words = requestline.split() > if len(words) == 3: > [command, path, version] = words > if version[:5] != 'HTTP/': > *************** > > Shouldn't we be consequent and use the new startswith methods > as well, instead of if version[:5] != 'HTTP/' ? > I think it would be better to do this all in one big shot. No, I think it's fine to do it in one fell swoop. You can either make many of this kind of changes to one module or make one type of change to many modules; if you try both, you'll touch too much and start making mistakes. --Guido van Rossum (home page: http://www.python.org/~guido/) From gansevle@cs.utwente.nl Fri Apr 21 22:50:05 2000 From: gansevle@cs.utwente.nl (Fred Gansevles) Date: Fri, 21 Apr 2000 23:50:05 +0200 Subject: [Patches] Please review before applying In-Reply-To: Your message of Fri, 21 Apr 2000 16:42:10 CDT Message-ID: <200004212150.XAA32590@localhost.localdomain> > > Guido> Wanted: reviews for this patch! It seems usable but (as the > Guido> author admits) needs another careful eye before I can apply it. > > I don't have time to review it, but I recall thinking when it went by that > distutils might (not "will", "might") be affected by this. I know Greg is > trying to make sure distutils will still work with 1.5.1. It's worth > spending a few seconds considering, especially if any of Fred's patches are > to the distutils subdirectory. I only patched the Lib/*.py files, no files from: Lib/distutils Lib/dos-8x3 Lib/encodings Lib/lib-old Lib/lib-stdwin Lib/lib-tk Lib/plat-aix3 Lib/plat-aix4 Lib/plat-beos Lib/plat-freebsd2 Lib/plat-freebsd3 Lib/plat-generic Lib/plat-irix5 Lib/plat-irix6 Lib/plat-linux1 Lib/plat-linux2 Lib/plat-netbsd1 Lib/plat-next3 Lib/plat-sunos4 Lib/plat-sunos5 Lib/plat-win Lib/site-packages Lib/test > > Skip ____________________________________________________________________________ Fred Gansevles Phone: +31 53 489 4613 >>> Your one-stop-shop for Linux/WinNT/NetWare <<< Org.: Twente University, Fac. of CS, Box 217, 7500 AE Enschede, Netherlands "Bill needs more time to learn Linux" - Steve B. From gansevle@cs.utwente.nl Fri Apr 21 22:55:43 2000 From: gansevle@cs.utwente.nl (Fred Gansevles) Date: Fri, 21 Apr 2000 23:55:43 +0200 Subject: [Patches] Please review before applying In-Reply-To: Your message of Fri, 21 Apr 2000 17:46:01 EDT Message-ID: <200004212155.XAA32664@localhost.localdomain> > > > Wanted: reviews for this patch! It seems usable but (as the author > > > admits) needs another careful eye before I can apply it. > > > > I begun skimming over it and stumbled here: > > > > --- 236,242 ---- > > elif requestline[-1:] == '\n': > > requestline = requestline[:-1] > > self.requestline = requestline > > ! words = requestline.split() > > if len(words) == 3: > > [command, path, version] = words > > if version[:5] != 'HTTP/': > > *************** > > > > Shouldn't we be consequent and use the new startswith methods > > as well, instead of if version[:5] != 'HTTP/' ? > > I think it would be better to do this all in one big shot. > > No, I think it's fine to do it in one fell swoop. You can either make > many of this kind of changes to one module or make one type of change > to many modules; if you try both, you'll touch too much and start > making mistakes. > Mainly this consideration made me ask for a deeper review (and it never hurts to let someone look closely at a patch to find typo-s :-). At a few points I've made some changes to the code, more than just a simple translation. > --Guido van Rossum (home page: http://www.python.org/~guido/) ____________________________________________________________________________ Fred Gansevles Phone: +31 53 489 4613 >>> Your one-stop-shop for Linux/WinNT/NetWare <<< Org.: Twente University, Fac. of CS, Box 217, 7500 AE Enschede, Netherlands "Bill needs more time to learn Linux" - Steve B. From Jack.Jansen@oratrix.com Sat Apr 22 00:07:24 2000 From: Jack.Jansen@oratrix.com (Jack Jansen) Date: Sat, 22 Apr 2000 01:07:24 +0200 Subject: [Patches] Patch to myselect.h Message-ID: <3900DF2D.AA9AC625@oratrix.nl> This is a multi-part message in MIME format. --------------5F9F63D9205AB44C4BEC667D Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Here's a patch to myselect.h. The GUSI 2.0 I/O library (which is used on the Mac) doesn't use the special header file for select anymore. ---- I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. --------------5F9F63D9205AB44C4BEC667D Content-Type: text/plain; charset=us-ascii; x-mac-type="54455854"; x-mac-creator="522A6368"; name="patch-myselect" Content-Transfer-Encoding: 7bit Content-Description: Unknown Document Content-Disposition: inline; filename="patch-myselect" Index: myselect.h =================================================================== RCS file: /projects/cvsroot/python/dist/src/Include/myselect.h,v retrieving revision 2.9 diff -c -r2.9 myselect.h *** myselect.h 1998/09/28 22:05:22 2.9 --- myselect.h 2000/04/21 23:03:40 *************** *** 51,57 **** #else /* !HAVE_SYS_SELECT_H */ ! #ifdef USE_GUSI /* If we don't have sys/select the definition may be in unistd.h */ #include #endif --- 51,57 ---- #else /* !HAVE_SYS_SELECT_H */ ! #ifdef USE_GUSI1 /* If we don't have sys/select the definition may be in unistd.h */ #include #endif --------------5F9F63D9205AB44C4BEC667D-- From Jack.Jansen@oratrix.com Sat Apr 22 00:15:15 2000 From: Jack.Jansen@oratrix.com (Jack Jansen) Date: Sat, 22 Apr 2000 01:15:15 +0200 Subject: [Patches] Patch to import.c and dynload_mac.c Message-ID: <3900E103.61B9DBBE@oratrix.nl> This is a multi-part message in MIME format. --------------6363959758E67113C45E8563 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Here's patches to import.c and dynload_mac.c. The new version of the GUSI i/o library on the Macintosh has a few slightly different calls from the old one. --- I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. --------------6363959758E67113C45E8563 Content-Type: text/plain; charset=us-ascii; x-mac-type="54455854"; x-mac-creator="522A6368"; name="patch-import" Content-Transfer-Encoding: 7bit Content-Description: Unknown Document Content-Disposition: inline; filename="patch-import" Index: dynload_mac.c =================================================================== RCS file: /projects/cvsroot/python/dist/src/Python/dynload_mac.c,v retrieving revision 2.3 diff -c -r2.3 dynload_mac.c *** dynload_mac.c 2000/02/14 17:58:25 2.3 --- dynload_mac.c 2000/04/21 23:00:54 *************** *** 40,46 **** #define CFragConnectionID ConnectionID #define kLoadCFrag 0x01 #endif ! #ifdef USE_GUSI #include "TFileSpec.h" /* for Path2FSSpec() */ #endif #include --- 40,46 ---- #define CFragConnectionID ConnectionID #define kLoadCFrag 0x01 #endif ! #ifdef USE_GUSI1 #include "TFileSpec.h" /* for Path2FSSpec() */ #endif #include *************** *** 78,84 **** Ptr mainAddr; Str255 errMessage; OSErr err; ! #ifndef USE_GUSI Boolean isfolder, didsomething; #endif char buf[512]; --- 78,84 ---- Ptr mainAddr; Str255 errMessage; OSErr err; ! #ifndef USE_GUSI1 Boolean isfolder, didsomething; #endif char buf[512]; *************** *** 87,93 **** CFragSymbolClass class; /* First resolve any aliases to find the real file */ ! #ifdef USE_GUSI err = Path2FSSpec(pathname, &libspec); #else (void)FSMakeFSSpec(0, 0, Pstring(pathname), &libspec); --- 87,93 ---- CFragSymbolClass class; /* First resolve any aliases to find the real file */ ! #ifdef USE_GUSI1 err = Path2FSSpec(pathname, &libspec); #else (void)FSMakeFSSpec(0, 0, Pstring(pathname), &libspec); Index: import.c =================================================================== RCS file: /projects/cvsroot/python/dist/src/Python/import.c,v retrieving revision 2.129 diff -c -r2.129 import.c *** import.c 2000/02/29 13:59:29 2.129 --- import.c 2000/04/21 23:00:55 *************** *** 1087,1093 **** #ifdef macintosh #include ! #ifdef USE_GUSI #include "TFileSpec.h" /* for Path2FSSpec() */ #endif static int --- 1087,1093 ---- #ifdef macintosh #include ! #ifdef USE_GUSI1 #include "TFileSpec.h" /* for Path2FSSpec() */ #endif static int *************** *** 1095,1101 **** { FSSpec fss; OSErr err; ! #ifndef USE_GUSI err = FSMakeFSSpec(0, 0, Pstring(buf), &fss); #else /* GUSI's Path2FSSpec() resolves all possible aliases nicely on --- 1095,1101 ---- { FSSpec fss; OSErr err; ! #ifndef USE_GUSI1 err = FSMakeFSSpec(0, 0, Pstring(buf), &fss); #else /* GUSI's Path2FSSpec() resolves all possible aliases nicely on --------------6363959758E67113C45E8563-- From Jack.Jansen@oratrix.com Sat Apr 22 00:16:09 2000 From: Jack.Jansen@oratrix.com (Jack Jansen) Date: Sat, 22 Apr 2000 01:16:09 +0200 Subject: [Patches] Patch to thread.c Message-ID: <3900E13A.B82AB94C@oratrix.nl> This is a multi-part message in MIME format. --------------E2C6AC962320E5BCAA1B5032 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Here's a patch to thread.c. Posix threads are now supported on the Macintosh too. --- I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. --------------E2C6AC962320E5BCAA1B5032 Content-Type: text/plain; charset=us-ascii; x-mac-type="54455854"; x-mac-creator="522A6368"; name="patch-thread" Content-Transfer-Encoding: 7bit Content-Description: Unknown Document Content-Disposition: inline; filename="patch-thread" Index: thread.c =================================================================== RCS file: /projects/cvsroot/python/dist/src/Python/thread.c,v retrieving revision 2.27 diff -c -r2.27 thread.c *** thread.c 1999/04/07 16:07:23 2.27 --- thread.c 2000/04/21 23:00:55 *************** *** 88,93 **** --- 88,97 ---- #define SUN_LWP #endif + #ifdef __MWERKS__ + #define _POSIX_THREADS + #endif + #endif /* _POSIX_THREADS */ #ifdef __STDC__ --------------E2C6AC962320E5BCAA1B5032-- From Jack.Jansen@oratrix.com Sat Apr 22 00:17:11 2000 From: Jack.Jansen@oratrix.com (Jack Jansen) Date: Sat, 22 Apr 2000 01:17:11 +0200 Subject: [Patches] Patch to tools/begn/bgen/macsupport.py Message-ID: <3900E178.4807A843@oratrix.nl> This is a multi-part message in MIME format. --------------5A9DE3FAC9FAC97D504AD2EE Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit A few new types needed by new API calls. --- I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. --------------5A9DE3FAC9FAC97D504AD2EE Content-Type: text/plain; charset=us-ascii; x-mac-type="54455854"; x-mac-creator="522A6368"; name="patch-macsupport" Content-Transfer-Encoding: 7bit Content-Description: Unknown Document Content-Disposition: inline; filename="patch-macsupport" Index: macsupport.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Tools/bgen/bgen/macsupport.py,v retrieving revision 1.16 diff -c -r1.16 macsupport.py *** macsupport.py 2000/01/20 20:49:28 1.16 --- macsupport.py 2000/04/21 22:55:20 *************** *** 15,21 **** ScriptCode = Type("ScriptCode", "h") Size = Type("Size", "l") Style = Type("Style", "b") ! StyleParameter = Type("Style", "h") CharParameter = Type("CharParameter", "h") TextEncoding = Type("TextEncoding", "l") --- 15,21 ---- ScriptCode = Type("ScriptCode", "h") Size = Type("Size", "l") Style = Type("Style", "b") ! StyleParameter = Type("StyleParameter", "h") CharParameter = Type("CharParameter", "h") TextEncoding = Type("TextEncoding", "l") *************** *** 31,37 **** Str255 = OpaqueArrayType("Str255", "PyMac_BuildStr255", "PyMac_GetStr255") # File System Specifications ! FSSpec = FSSpec_ptr = OpaqueType("FSSpec", "PyMac_BuildFSSpec", "PyMac_GetFSSpec") # OSType and ResType: 4-byte character strings def OSTypeType(typename): --- 31,38 ---- Str255 = OpaqueArrayType("Str255", "PyMac_BuildStr255", "PyMac_GetStr255") # File System Specifications ! FSSpec_ptr = OpaqueType("FSSpec", "PyMac_BuildFSSpec", "PyMac_GetFSSpec") ! FSSpec = OpaqueByValueType("FSSpec", "PyMac_BuildFSSpec", "PyMac_GetFSSpec") # OSType and ResType: 4-byte character strings def OSTypeType(typename): *************** *** 85,90 **** --- 86,92 ---- # Various buffer types InBuffer = VarInputBufferType('char', 'long', 'l') # (buf, len) + OptionalInBuffer = OptionalVarInputBufferType('char', 'long', 'l') # (buf, len) InOutBuffer = HeapInputOutputBufferType('char', 'long', 'l') # (inbuf, outbuf, len) VarInOutBuffer = VarHeapInputOutputBufferType('char', 'long', 'l') # (inbuf, outbuf, &len) *************** *** 151,159 **** # This requires that the OSErr type (defined above) has a non-trivial # errorCheck method. class OSErrMixIn: ! "Mix-in class to treat OSErr return values special" def makereturnvar(self): ! if self.returntype is OSErr: return Variable(self.returntype, "_err", ErrorMode) else: return Variable(self.returntype, "_rv", OutMode) --- 153,161 ---- # This requires that the OSErr type (defined above) has a non-trivial # errorCheck method. class OSErrMixIn: ! "Mix-in class to treat OSErr/OSStatus return values special" def makereturnvar(self): ! if self.returntype.__class__ == OSErrType: return Variable(self.returntype, "_err", ErrorMode) else: return Variable(self.returntype, "_rv", OutMode) --------------5A9DE3FAC9FAC97D504AD2EE-- From Jack.Jansen@oratrix.com Sat Apr 22 00:19:08 2000 From: Jack.Jansen@oratrix.com (Jack Jansen) Date: Sat, 22 Apr 2000 01:19:08 +0200 Subject: [Patches] Patch to socketmodule.c Message-ID: <3900E1EC.A6CAA0C5@oratrix.nl> This is a multi-part message in MIME format. --------------2A0D8785DD8F008DF00A99BD Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit The GUSI 2.0 I/O library used on the Mac uses the socklen_t (unsigned int) for most size parameters. Apparently this is part of the UNIX 98 standard, but for now the code is #ifdeffed with USE_GUSI. --- I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. --------------2A0D8785DD8F008DF00A99BD Content-Type: text/plain; charset=us-ascii; x-mac-type="54455854"; x-mac-creator="522A6368"; name="patch-socketmodule" Content-Transfer-Encoding: 7bit Content-Description: Unknown Document Content-Disposition: inline; filename="patch-socketmodule" Index: socketmodule.c =================================================================== RCS file: /projects/cvsroot/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.103 diff -c -r1.103 socketmodule.c *** socketmodule.c 2000/04/21 20:33:00 1.103 --- socketmodule.c 2000/04/21 22:59:54 *************** *** 172,178 **** #ifdef __BEOS__ #include #else ! #ifndef macintosh #include #endif #endif --- 172,178 ---- #ifdef __BEOS__ #include #else ! #ifndef USE_GUSI1 #include #endif #endif *************** *** 192,202 **** #define O_NDELAY O_NONBLOCK /* For QNX only? */ #endif ! #ifdef USE_GUSI /* fdopen() isn't declared in stdio.h (sigh) */ #include #endif #ifdef USE_SSL #include "rsa.h" #include "crypto.h" --- 192,209 ---- #define O_NDELAY O_NONBLOCK /* For QNX only? */ #endif ! #ifdef USE_GUSI1 /* fdopen() isn't declared in stdio.h (sigh) */ #include #endif + #ifndef USE_GUSI2 + /* GUSI socket library seems to be the only one to define socklen_t. + ** And it defines it as an unsigned int too. + */ + typedef int socklen_t; + #endif + #ifdef USE_SSL #include "rsa.h" #include "crypto.h" *************** *** 664,670 **** BUILD_FUNC_DEF_2(PySocketSock_accept,PySocketSockObject *,s, PyObject *,args) { char addrbuf[256]; ! int addrlen, newfd; PyObject *sock = NULL; PyObject *addr = NULL; PyObject *res = NULL; --- 671,678 ---- BUILD_FUNC_DEF_2(PySocketSock_accept,PySocketSockObject *,s, PyObject *,args) { char addrbuf[256]; ! int newfd; ! socklen_t addrlen; PyObject *sock = NULL; PyObject *addr = NULL; PyObject *res = NULL; *************** *** 808,814 **** int optname; int res; PyObject *buf; ! int buflen = 0; #ifdef __BEOS__ /* We have incomplete socket support. */ --- 816,822 ---- int optname; int res; PyObject *buf; ! socklen_t buflen = 0; #ifdef __BEOS__ /* We have incomplete socket support. */ *************** *** 822,828 **** if (buflen == 0) { int flag = 0; ! int flagsize = sizeof flag; res = getsockopt(s->sock_fd, level, optname, (ANY *)&flag, &flagsize); if (res < 0) --- 830,836 ---- if (buflen == 0) { int flag = 0; ! socklen_t flagsize = sizeof flag; res = getsockopt(s->sock_fd, level, optname, (ANY *)&flag, &flagsize); if (res < 0) *************** *** 1010,1016 **** BUILD_FUNC_DEF_2(PySocketSock_getsockname,PySocketSockObject *,s, PyObject *,args) { char addrbuf[256]; ! int addrlen, res; if (!PyArg_ParseTuple(args, ":getsockname")) return NULL; if (!getsockaddrlen(s, &addrlen)) --- 1018,1026 ---- BUILD_FUNC_DEF_2(PySocketSock_getsockname,PySocketSockObject *,s, PyObject *,args) { char addrbuf[256]; ! int res; ! socklen_t addrlen; ! if (!PyArg_ParseTuple(args, ":getsockname")) return NULL; if (!getsockaddrlen(s, &addrlen)) *************** *** 1038,1044 **** BUILD_FUNC_DEF_2(PySocketSock_getpeername,PySocketSockObject *,s, PyObject *,args) { char addrbuf[256]; ! int addrlen, res; if (!PyArg_ParseTuple(args, ":getpeername")) return NULL; if (!getsockaddrlen(s, &addrlen)) --- 1048,1056 ---- BUILD_FUNC_DEF_2(PySocketSock_getpeername,PySocketSockObject *,s, PyObject *,args) { char addrbuf[256]; ! int res; ! socklen_t addrlen; ! if (!PyArg_ParseTuple(args, ":getpeername")) return NULL; if (!getsockaddrlen(s, &addrlen)) *************** *** 1177,1183 **** PyObject *addr = NULL; PyObject *ret = NULL; ! int addrlen, len, n, flags = 0; if (!PyArg_ParseTuple(args, "i|i:recvfrom", &len, &flags)) return NULL; if (!getsockaddrlen(s, &addrlen)) --- 1189,1196 ---- PyObject *addr = NULL; PyObject *ret = NULL; ! int len, n, flags = 0; ! socklen_t addrlen; if (!PyArg_ParseTuple(args, "i|i:recvfrom", &len, &flags)) return NULL; if (!getsockaddrlen(s, &addrlen)) *************** *** 1882,1888 **** if (!PyArg_ParseTuple(args, "s:inet_aton", &ip_addr)) { return NULL; } ! #ifdef macintosh packed_addr = (long)inet_addr(ip_addr).s_addr; #else packed_addr = inet_addr(ip_addr); --- 1895,1901 ---- if (!PyArg_ParseTuple(args, "s:inet_aton", &ip_addr)) { return NULL; } ! #ifdef USE_GUSI1 packed_addr = (long)inet_addr(ip_addr).s_addr; #else packed_addr = inet_addr(ip_addr); --------------2A0D8785DD8F008DF00A99BD-- From Jack.Jansen@oratrix.com Sat Apr 22 00:22:23 2000 From: Jack.Jansen@oratrix.com (Jack Jansen) Date: Sat, 22 Apr 2000 01:22:23 +0200 Subject: [Patches] Patch to timemodule.c Message-ID: <3900E2B0.AD10EE6D@oratrix.nl> On the Macintosh the C library (gmtime, localtime, ctime) uses the ANSI-C standard epoch of 1-Jan-1900, but the I/O library (time, stat, etc) uses the Mac epoch of 1-Jan-1904. We offset the values so the Python code always sees the Mac standard. --- I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. From gstein@lyra.org Sat Apr 22 02:06:27 2000 From: gstein@lyra.org (Greg Stein) Date: Fri, 21 Apr 2000 18:06:27 -0700 (PDT) Subject: [Patches] Patch to timemodule.c In-Reply-To: <3900E2B0.AD10EE6D@oratrix.nl> Message-ID: You forgot to append the patch. -g On Sat, 22 Apr 2000, Jack Jansen wrote: > On the Macintosh the C library (gmtime, localtime, ctime) uses the ANSI-C > standard epoch of 1-Jan-1900, > but the I/O library (time, stat, etc) uses the Mac epoch of 1-Jan-1904. We > offset the values so the Python > code always sees the Mac standard. > --- > I confirm that, to the best of my knowledge and belief, this > contribution is free of > any claims of third parties under > copyright, patent or > other rights or interests ("claims"). To > the extent that I have > any such claims, I hereby grant to CNRI a > nonexclusive, > irrevocable, royalty-free, worldwide license to > reproduce, distribute, > perform and/or display publicly, prepare > derivative versions, and > otherwise use this contribution as part > of the Python software > and its related documentation, or any > derivative versions > thereof, at no cost to CNRI or its licensed > users, and to authorize > others to do so. > > I acknowledge that CNRI > may, at its sole discretion, decide > whether or not to > incorporate this contribution in the Python > software and its related > documentation. I further grant CNRI > permission to use my > name and other identifying information > provided to CNRI by me > for use in connection with the Python > software and its related documentation. > > _______________________________________________ > Patches mailing list > Patches@python.org > http://www.python.org/mailman/listinfo/patches > -- Greg Stein, http://www.lyra.org/ From mhammond@skippinet.com.au Sat Apr 22 04:39:21 2000 From: mhammond@skippinet.com.au (Mark Hammond) Date: Sat, 22 Apr 2000 13:39:21 +1000 Subject: [Patches] Correction for error in my last mmap.dsp patch. Message-ID: Ooops - I think I know how this happened. This patch fixes a linker error on mmap.pyd - the "0x" before the base address was missing... Release info: I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. Mark. begin 666 mmap.dsp M(R!-:6-R;W-O9G0@1&5V96QO<&5R(%-T=61I;R!0# Q,#(- M"@T*0T9'/6UM87 @+2!7:6XS,B!$96)U9PT*(4U%4U-!1T4@5&AI'!O2!A(&-O;F9I9W5R871I;VX@=VAE;B!R=6YN:6YG($Y-04M%#0HA3453 M4T%'12!B>2!D969I;FEN9R!T:&4@;6%C&%M<&QE.@T*(4U%4U-!1T4@#0HA34534T%'12!.34%+ M12 O9B B;6UA<"YM86LB($-&1STB;6UA<" M(%=I;C,R($1E8G5G(@T*(4U% M4U-!1T4@#0HA34534T%'12!0;W-S:6)L92!C:&]I8V5S(&9O&4-"E)30SUR8RYE>&4-"@T*(4E&(" B)"A#1D7!L:6(R,#,@+W=I;C,R#0HC($%$1"!-5$P@+VYO;&]G M;R O1" B3D1%0E5'(B O;6MT>7!L:6(R,#,@+W=I;C,R#0HC($%$1"!"05-% M(%)30R O;" P>&,P.2 O9" B3D1%0E5'(@T*(R!!1$0@4E-#("]L(#!X8S Y M("]D(").1$5"54&4-"B,@041$($)!4T4@3$E.2S,R(&ME60B#0H-"B%%3%-%248@("(D*$-&1RDB(#T](")M;6%P("T@5VEN,S(@ M1&5B=67!E.G-E<'0-"B,@041$ M($Q)3DLS,B!K97)N96PS,BYL:6(@=7-E#%E,48P,# P(B O9&QL M("]D96)U9R O;6%C:&EN93I),S@V("]O=70Z(BXO;6UA<%]D+G!Y9"(@+W!D M8G1Y<&4Z This is a multi-part message in MIME format. ------=_NextPart_000_0023_01BFAC54.BBF6B080 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable this patch removes a few explicit UTF-8 references from the Python internals, moving them into a single support function: PyUnicode_ToString -- converts a unicode string to an 8-bit string using the standard encoding (currently UTF-8, just as before). to convert the other way, use PyUnicode_FromObject. I confirm that, to the best of my knowledge and belief, this = contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related = documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. =20 I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. ------=_NextPart_000_0023_01BFAC54.BBF6B080 Content-Type: application/octet-stream; name="unicode-patch-1" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="unicode-patch-1" --- Python/bak/getargs.c Tue Mar 28 22:09:47 2000 +++ Python/getargs.c Sat Apr 22 11:47:31 2000 @@ -589,7 +589,8 @@ if (PyString_Check(arg)) *p = PyString_AS_STRING(arg); else if (PyUnicode_Check(arg)) { - arg = PyUnicode_AsUTF8String(arg); + /* XXX: this leaks, doesn't it? */ + arg = PyUnicode_ToString(arg); if (arg == NULL) return "unicode conversion error"; *p = PyString_AS_STRING(arg); @@ -634,7 +635,8 @@ else if (PyString_Check(arg)) *p = PyString_AsString(arg); else if (PyUnicode_Check(arg)) { - arg = PyUnicode_AsUTF8String(arg); + /* XXX: this leaks, doesn't it? */ + arg = PyUnicode_ToString(arg); if (arg == NULL) return "unicode conversion error"; *p = PyString_AS_STRING(arg); --- Objects/bak/unicodeobject.c Mon Apr 17 17:57:09 2000 +++ Objects/unicodeobject.c Sat Apr 22 12:06:03 2000 @@ -367,9 +367,16 @@ Py_INCREF(unicode_empty); return (PyObject *)unicode_empty; } + /* default encoding is UTF-8 */ return PyUnicode_DecodeUTF8(s, len, "strict"); } +PyObject *PyUnicode_ToString(register PyObject *obj) +{ + /* default encoding is UTF-8 */ + return PyUnicode_AsUTF8String(obj); +} + PyObject *PyUnicode_Decode(const char *s, int size, const char *encoding, @@ -2012,7 +2019,7 @@ continue; } if (0 < ch && ch < 256) { - *output++ = ch; + *output++ = (char) ch; continue; } /* All other characters are considered invalid */ ------=_NextPart_000_0023_01BFAC54.BBF6B080-- From Fredrik Lundh" Message-ID: <003301bfac50$469fc460$34aab5d4@hagrid> this patch must be installed on top of part 1. changes: PyUnicode_ToString is changed to PyUnicode_AsString (turned out that the right thing here was to change the code to match the name, not vice versa) fixed reference leak in getargs (AsUTF8 returns a unique reference, not a shared reference) internal changes to unicodeobject to make it easier to change the default encoding coming up next: replacing AsUTF8 with ToUTF8 (this includes plugging a few more leaks...) I confirm that, to the best of my knowledge and belief, this = contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related = documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. =20 I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. From Fredrik Lundh" This is a multi-part message in MIME format. ------=_NextPart_000_003D_01BFAC61.30B90420 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable (forgot the patch ;-) this patch must be installed on top of part 1. changes: PyUnicode_ToString is changed to PyUnicode_AsString (turned out that the right thing here was to change the code to match the name, not vice versa) fixed reference leak in getargs (AsUTF8 returns a unique reference, not a shared reference) internal changes to unicodeobject to make it easier to change the default encoding coming up next: replacing AsUTF8 with ToUTF8 (this includes plugging a few more leaks...) I confirm that, to the best of my knowledge and belief, this = contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related = documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. =20 I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. ------=_NextPart_000_003D_01BFAC61.30B90420 Content-Type: application/octet-stream; name="unicode-patch-2" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="unicode-patch-2" --- Include/bak/unicodeobject.h Sat Apr 22 13:38:39 2000 +++ Include/unicodeobject.h Sat Apr 22 13:24:41 2000 @@ -182,7 +182,7 @@ int length; /* Length of raw Unicode data in buffer */ Py_UNICODE *str; /* Raw Unicode buffer */ long hash; /* Hash value; -1 if not set */ - PyObject *utf8str; /* UTF-8 encoded version as Python string, + PyObject *utf8str; /* 8-bit encoded version as Python string, or NULL */ } PyUnicodeObject; @@ -279,11 +279,16 @@ register PyObject *obj /* Object */ ); -/* Convert Unicode object to 8-bit string using the default 8-bit - encoding (currently UTF-8). Returns NULL if conversion fails, - caller must decref */ +/* Return a shared reference to a String object holding an 8-bit + encoding of the Unicode object (currently UTF-8). -extern DL_IMPORT(PyObject*) PyUnicode_ToString( + Note that the reference is owned by the Unicode object, and is + guaranteed to live at least as long as the Unicode object itself. + The caller must not decref this reference. + + This function returns NULL if the conversion fails. */ + +extern DL_IMPORT(PyObject*) PyUnicode_AsString( register PyObject *obj /* Object */ ); --- Python/bak/getargs.c Sat Apr 22 11:47:31 2000 +++ Python/getargs.c Sat Apr 22 13:03:17 2000 @@ -589,8 +589,7 @@ if (PyString_Check(arg)) *p = PyString_AS_STRING(arg); else if (PyUnicode_Check(arg)) { - /* XXX: this leaks, doesn't it? */ - arg = PyUnicode_ToString(arg); + arg = PyUnicode_AsString(arg); if (arg == NULL) return "unicode conversion error"; *p = PyString_AS_STRING(arg); @@ -635,8 +634,7 @@ else if (PyString_Check(arg)) *p = PyString_AsString(arg); else if (PyUnicode_Check(arg)) { - /* XXX: this leaks, doesn't it? */ - arg = PyUnicode_ToString(arg); + arg = PyUnicode_AsString(arg); if (arg == NULL) return "unicode conversion error"; *p = PyString_AS_STRING(arg); --- Objects/bak/unicodeobject.c Sat Apr 22 12:06:03 2000 +++ Objects/unicodeobject.c Sat Apr 22 13:24:21 2000 @@ -371,10 +371,48 @@ return PyUnicode_DecodeUTF8(s, len, "strict"); } -PyObject *PyUnicode_ToString(register PyObject *obj) +/* Return a Python string holding an 8-bit encoded value of the + Unicode object. + + The resulting string is cached in the Unicode object for subsequent + usage by this function. The cached version is needed to implement + the character buffer interface. + + The refcount of the string is *not* incremented. + +*/ + +static PyObject *as_string(register PyUnicodeObject *self) { + PyObject *v = self->utf8str; + + if (!v) { + + /* default encoding is UTF-8 */ + v = PyUnicode_EncodeUTF8( + PyUnicode_AS_UNICODE(self), + PyUnicode_GET_SIZE(self), + NULL); /* strict */ + + /* XXX: note that if we change this to an encoding that may + fail, the encode function will be called over and over + again. in that case, utf8str should probably be set to None */ + + self->utf8str = v; + + } + + return v; +} + +PyObject *PyUnicode_AsString(register PyObject *obj) +{ + if (!PyUnicode_Check(obj)) { + PyErr_BadArgument(); + return NULL; + } /* default encoding is UTF-8 */ - return PyUnicode_AsUTF8String(obj); + return as_string((PyUnicodeObject *) obj); } PyObject *PyUnicode_Decode(const char *s, @@ -709,33 +747,6 @@ return NULL; } -/* Return a Python string holding the UTF-8 encoded value of the - Unicode object. - - The resulting string is cached in the Unicode object for subsequent - usage by this function. The cached version is needed to implement - the character buffer interface. - - The refcount of the string is *not* incremented. - -*/ - -static -PyObject *utf8_string(PyUnicodeObject *self, - const char *errors) -{ - PyObject *v = self->utf8str; - - if (v) - return v; - v = PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(self), - PyUnicode_GET_SIZE(self), - errors); - if (v && errors == NULL) - self->utf8str = v; - return v; -} - PyObject *PyUnicode_AsUTF8String(PyObject *unicode) { PyObject *str; @@ -744,7 +755,9 @@ PyErr_BadArgument(); return NULL; } - str = utf8_string((PyUnicodeObject *)unicode, NULL); + /* XXX: this breaks down if we change the default encoding + to something that isn't UTF-8 */ + str = as_string((PyUnicodeObject *)unicode); if (str == NULL) return NULL; Py_INCREF(str); @@ -3179,21 +3192,21 @@ unicode_hash(PyUnicodeObject *self) { long hash; - PyObject *utf8; + PyObject *str; - /* Since Unicode objects compare equal to their UTF-8 string - counterparts, they should also use the UTF-8 strings as basis + /* Since Unicode objects compare equal to their 8-bit string + counterparts, they should also use the 8-bit strings as basis for their hash value. This is needed to assure that strings and Unicode objects behave in the same way as dictionary keys. Unfortunately, this costs some performance and also some - memory if the cached UTF-8 representation is not used later + memory if the cached 8-bit representation is not used later on. */ if (self->hash != -1) return self->hash; - utf8 = utf8_string(self, NULL); - if (utf8 == NULL) + str = as_string(self); + if (str == NULL) return -1; - hash = PyObject_Hash(utf8); + hash = PyObject_Hash(str); if (hash == -1) return -1; self->hash = hash; @@ -3812,7 +3825,9 @@ static PyObject *unicode_str(PyUnicodeObject *self) { - return PyUnicode_AsUTF8String((PyObject *)self); + PyObject* str = as_string(self); + Py_XINCREF(str); + return str; } static char strip__doc__[] = @@ -4094,7 +4109,7 @@ "accessing non-existent unicode segment"); return -1; } - str = utf8_string(self, NULL); + str = as_string(self); if (str == NULL) return -1; *ptr = (void *) PyString_AS_STRING(str); ------=_NextPart_000_003D_01BFAC61.30B90420-- From Fredrik Lundh" This is a multi-part message in MIME format. ------=_NextPart_000_0067_01BFAC69.3C3F7B00 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable this patch must be installed on top of parts 1 and 2. changes: PyUnicode_AsEncodedString and PyUnicode_AsUTF8String both use as_string directly, to save some code. fixed reference leak in _tkinter.c (AsUTF8 increments the reference count, despite what the name implies) (I think most PyUnicode_As functions should be renamed to PyUnicode_To, but I'll leave that for another patch) this is the last part in this round. the forth part changes as_string to use 8-bit unicode (and puts utf8_string back in again), but I won't post that one just yet. I confirm that, to the best of my knowledge and belief, this = contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related = documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. =20 I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. ------=_NextPart_000_0067_01BFAC69.3C3F7B00 Content-Type: application/octet-stream; name="unicode-patch-3" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="unicode-patch-3" *** Objects/bak/unicodeobject.c Sat Apr 22 13:24:21 2000 --- Objects/unicodeobject.c Sat Apr 22 14:22:43 2000 *************** *** 389,398 **** if (!v) { /* default encoding is UTF-8 */ ! v = PyUnicode_EncodeUTF8( ! PyUnicode_AS_UNICODE(self), ! PyUnicode_GET_SIZE(self), ! NULL); /* strict */ /* XXX: note that if we change this to an encoding that may fail, the encode function will be called over and over --- 389,397 ---- if (!v) { /* default encoding is UTF-8 */ ! v = PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(self), ! PyUnicode_GET_SIZE(self), ! NULL); /* strict */ /* XXX: note that if we change this to an encoding that may fail, the encode function will be called over and over *************** *** 474,484 **** PyErr_BadArgument(); goto onError; } ! /* Shortcut for the default encoding UTF-8 */ if ((encoding == NULL || (strcmp(encoding, "utf-8") == 0)) && ! errors == NULL) ! return PyUnicode_AsUTF8String(unicode); /* Encode via the codec registry */ v = PyCodec_Encode(unicode, encoding, errors); --- 473,488 ---- PyErr_BadArgument(); goto onError; } ! ! /* Shortcut for the built-in encoding UTF-8 */ if ((encoding == NULL || (strcmp(encoding, "utf-8") == 0)) && ! errors == NULL) { ! /* default encoding is UTF-8 */ ! v = as_string((PyUnicodeObject*) unicode); ! Py_XINCREF(v); ! return v; ! } /* Encode via the codec registry */ v = PyCodec_Encode(unicode, encoding, errors); *************** *** 755,766 **** PyErr_BadArgument(); return NULL; } ! /* XXX: this breaks down if we change the default encoding ! to something that isn't UTF-8 */ str = as_string((PyUnicodeObject *)unicode); ! if (str == NULL) ! return NULL; ! Py_INCREF(str); return str; } --- 759,767 ---- PyErr_BadArgument(); return NULL; } ! /* default encoding is UTF-8 */ str = as_string((PyUnicodeObject *)unicode); ! Py_XINCREF(str); return str; } *** Modules/bak/_tkinter.c Fri Mar 31 12:08:53 2000 --- Modules/_tkinter.c Sat Apr 22 14:15:39 2000 *************** *** 550,560 **** return result; } else if (PyUnicode_Check(value)) { ! PyObject* utf8 = PyUnicode_AsUTF8String (value); if (!utf8) return 0; ! return Tcl_NewStringObj (PyString_AS_STRING (utf8), ! PyString_GET_SIZE (utf8)); } else { PyObject *v = PyObject_Str(value); --- 550,562 ---- return result; } else if (PyUnicode_Check(value)) { ! PyObject* utf8 = PyUnicode_AsUTF8String(value); if (!utf8) return 0; ! result = Tcl_NewStringObj(PyString_AS_STRING(utf8), ! PyString_GET_SIZE(utf8)); ! Py_DECREF(utf8); ! return result; } else { PyObject *v = PyObject_Str(value); ------=_NextPart_000_0067_01BFAC69.3C3F7B00-- From Fredrik Lundh" Message-ID: <009201bfac5a$36d62060$34aab5d4@hagrid> > this patch must be installed on top of parts 1 and 2. just figured out why my cvs diff script didn't work. if you want a "composite patch" instead, drop me a line. From Fredrik Lundh" This is a multi-part message in MIME format. ------=_NextPart_000_00BC_01BFAC74.5C77C480 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable as currently implemented, the urllib module allows you to post with a single content type (x-www-form-urlencoded). this patch modifies urllib to accept either a string or a (subclass of) the urllib.RequestBody class. usage: import urllib body =3D urllib.RequestBody(mydata, "text/xml") result =3D urllib.urlopen(host, body) or: body =3D urllib.RequestBody(name=3D"fredrik", = email=3D"effbot@telia.com") result =3D urllib.urlopen(host, body) I confirm that, to the best of my knowledge and belief, this = contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related = documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. =20 I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. ------=_NextPart_000_00BC_01BFAC74.5C77C480 Content-Type: application/octet-stream; name="urllib-patch-1" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="urllib-patch-1" Index: Lib/urllib.py =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /projects/cvsroot/python/dist/src/Lib/urllib.py,v retrieving revision 1.91 diff -d -c -r1.91 urllib.py *** urllib.py 2000/02/04 15:28:41 1.91 --- urllib.py 2000/04/22 14:03:03 *************** *** 69,75 **** --- 69,93 ---- if _urlopener: _urlopener.cleanup() =20 + class RequestBody: + """Class to hold a POST request body""" + def __init__(self, body, = type=3D'application/x-www-form-urlencoded'): + self.body =3D body + self.type =3D type + def gettype(self): + return self.type + def getbody(self): + return self.body =20 + class Form(RequestBody): + """Class to hold a POST form request""" + def __init__(self, dict, **extra): + dict =3D dict.copy() + dict.update(extra) + RequestBody.__init__(self, dict) + def getbody(self): + return urlencode(self.body) +=20 ftpcache =3D {} class URLopener: """Class to open URLs. *************** *** 256,264 **** auth =3D None h =3D httplib.HTTP(host) if data is not None: h.putrequest('POST', selector) ! h.putheader('Content-type', = 'application/x-www-form-urlencoded') ! h.putheader('Content-length', '%d' % len(data)) else: h.putrequest('GET', selector) if auth: h.putheader('Authorization', 'Basic %s' % auth) --- 274,285 ---- auth =3D None h =3D httplib.HTTP(host) if data is not None: + if type(data) is type(''): + data =3D RequestBody(data) + body =3D data.getbody() h.putrequest('POST', selector) ! h.putheader('Content-type', data.gettype()) ! h.putheader('Content-length', str(len(body))) else: h.putrequest('GET', selector) if auth: h.putheader('Authorization', 'Basic %s' % auth) *************** *** 266,272 **** for args in self.addheaders: apply(h.putheader, args) h.endheaders() if data is not None: ! h.send(data + '\r\n') errcode, errmsg, headers =3D h.getreply() fp =3D h.getfile() if errcode =3D=3D 200: --- 287,293 ---- for args in self.addheaders: apply(h.putheader, args) h.endheaders() if data is not None: ! h.send(body + '\r\n') errcode, errmsg, headers =3D h.getreply() fp =3D h.getfile() if errcode =3D=3D 200: ------=_NextPart_000_00BC_01BFAC74.5C77C480-- From Fredrik Lundh" Message-ID: <00da01bfac64$090fca00$34aab5d4@hagrid> bzzt. the second example was supposed to be: body =3D urllib.Form(name=3D"fredrik", email=3D"effbot@telia.com") result =3D urllib.urlopen(host, body) From mal@lemburg.com Sat Apr 22 16:04:16 2000 From: mal@lemburg.com (M.-A. Lemburg) Date: Sat, 22 Apr 2000 17:04:16 +0200 Subject: [Patches] Py_BuildValue Unicode support References: <20000420013156.77083.qmail@hotmail.com> <200004211832.OAA16628@eric.cnri.reston.va.us> Message-ID: <3901BF70.DE9C8F03@lemburg.com> Guido van Rossum wrote: > > > There might be a nicer way to do this, but I wanted to be able to > > use Py_BuildValue to produce Unicode objects, so I added a few > > lines to modsupport to do this. Each Unicode object requires > > two arguments, the raw Py_UNICODE string and the length as an > > integer. I think since all Python Unicode strings are 0 terminated, > > it might be nice to make this into "U#" and also allow a plain "U" > > to mean a (double) null-terminated Unicode string as input; however, > > I'll leave that up to you all to determine (I would personally like > > to see this option). > > Yes, what you coded here should be called U#. Perhaps the naming should be "u#" and "u" rather than "U#" and "U" !? This would be in sync with "s#" and "s" for 8-bit strings. -- Marc-Andre Lemburg ______________________________________________________________________ Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ From tismer@tismer.com Sat Apr 22 17:49:23 2000 From: tismer@tismer.com (Christian Tismer) Date: Sat, 22 Apr 2000 18:49:23 +0200 Subject: [Patches] Review (was: Please review before applying) References: <200004111225.OAA31234@localhost.localdomain> <14579.6375.601339.630742@beluga.mojam.com> Message-ID: <3901D813.D2148C44@tismer.com> So, 4 hours later, here's my review. (pffffft) Skip Montanaro wrote: > > >From the changes to Lib/BaseHTTPServer.py: > > Fred> # The Python system version, truncated to its first component. > Fred> ! sys_version = "Python/" + sys.version.split[0] > > The change here should be to > > sys.version.split()[0] > > This suggests to me that the BaseHTTPRequestHandler class isn't tested by > 'make test'. Found this one, and then saw your message. Markup of this document: --- starts a section with a comment, but no change request +++ also comment, with mild change request *** starts a section with a real bug. The latter also suggests to update the test suite! More bugs or just comments: ---/+++ cgi.py, line 704 you are changing plist = map(string.strip, string.splitfields(line, ';')) into plist = map(lambda s: s.strip(), line.split(';')) I don't the extra lambda-ness and the extra frames generated here are an advantage. Guido, while dropping the string module, wouldn't it make sense to provide a way to get at the "unbound methods" of strings, like so? : plist = map("".string.strip, line.split(';')) or plist = map("".__class__.strip, line.split(';')) or something alike? Or is this just a case where string definately should be used? --- cgi.py, Line 711 minor cosmetic glitch: name = p[:i].strip().lower () should read name = p[:i].strip().lower() *** dospath.py, line 18 This is a real bug. I think the tests do not test normcase(). return s.replace(s, "/", "\\").lower() should read return s.replace("/", "\\").lower() according to the rest of the style of the source. +++ formatter.py This module still uses string. This contradicts Fred's claim of """ This (mega-)patch updates all the modules in the standard-module (all Lib/*.py files) to use the new string-methods instead of the old string module. """ The claim suggests that string is always no longer imported. I suggest to add a note that the string module is still used for some constants in some modules. --- formatter.py, line 171 minor cosmetic glitch: data = ' '.join (data.split()) should read data = ' '.join(data.split()) according to the rest of the style of the source. --- gzip.py, line 140 minor cosmetic glitch: self.write(' '.join (lines)) should read self.write(' '.join(lines)) according to the rest of the style of the source. --- imaplib.py, line 1001 cosmetic glitch with space after join (no source shown here) --- macpath.py, line 10 cosmetic glitch with space after lower (no source shown here) --- multifile.py, nturlpath.py, re.py uses string, see comment for formatter.py --- rfc822.py, line 465 cosmetic glitch with space after replace (no source shown here) --- sgmllib.py, traceback.py, urllib.py uses string, see comment for formatter.py --- urllib2.py, line 820 uses lambdaness, see cgi.py --- urlparse.py, xmllib.py uses string, see comment for formatter.py Summary: -------- I cannot find more than two real bugs. I suggest to correct these, and perhaps to think of changing the extra lambdas back to use string. After that, I'm +1 on applying this patch. Congrats for the huge work - chris -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaunstr. 26 : *Starship* http://starship.python.net 14163 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF where do you want to jump today? http://www.stackless.com From gstein@lyra.org Sat Apr 22 20:16:02 2000 From: gstein@lyra.org (Greg Stein) Date: Sat, 22 Apr 2000 12:16:02 -0700 (PDT) Subject: [Patches] Review (was: Please review before applying) In-Reply-To: <3901D813.D2148C44@tismer.com> Message-ID: On Sat, 22 Apr 2000, Christian Tismer wrote: >... > ---/+++ cgi.py, line 704 > you are changing > plist = map(string.strip, string.splitfields(line, ';')) > into > plist = map(lambda s: s.strip(), line.split(';')) > > I don't the extra lambda-ness and the extra frames generated here > are an advantage. No... use the lambda. string.strip is a function that is equal to that lambda. Therefore, it is better to avoid the string module altogether and to use the lambda. Cheers, -g -- Greg Stein, http://www.lyra.org/ From gstein@lyra.org Sat Apr 22 20:32:39 2000 From: gstein@lyra.org (Greg Stein) Date: Sat, 22 Apr 2000 12:32:39 -0700 (PDT) Subject: [Patches] Please review before applying In-Reply-To: <200004212146.RAA18313@eric.cnri.reston.va.us> Message-ID: On Fri, 21 Apr 2000, Guido van Rossum wrote: >... > > Shouldn't we be consequent and use the new startswith methods > > as well, instead of if version[:5] != 'HTTP/' ? > > I think it would be better to do this all in one big shot. > > No, I think it's fine to do it in one fell swoop. You can either make > many of this kind of changes to one module or make one type of change > to many modules; if you try both, you'll touch too much and start > making mistakes. I'm with Guido on this one. If you are making a *large* set of patches, then it is best to stick with a single type of change. Fred's patch is generally a simple translation: string.foo(s, ...) => s.foo(...) Any more than that, and your brain has to keep changing gears. A second round of patching can easily go through and make use of the new .startswith(). Cheers, -g -- Greg Stein, http://www.lyra.org/ From tismer@tismer.com Sat Apr 22 21:25:39 2000 From: tismer@tismer.com (Christian Tismer) Date: Sat, 22 Apr 2000 22:25:39 +0200 Subject: [Patches] Please review before applying References: Message-ID: <39020AC3.B5762381@tismer.com> Greg Stein wrote: > > On Fri, 21 Apr 2000, Guido van Rossum wrote: > >... > > > Shouldn't we be consequent and use the new startswith methods > > > as well, instead of if version[:5] != 'HTTP/' ? > > > I think it would be better to do this all in one big shot. > > > > No, I think it's fine to do it in one fell swoop. You can either make > > many of this kind of changes to one module or make one type of change > > to many modules; if you try both, you'll touch too much and start > > making mistakes. > > I'm with Guido on this one. If you are making a *large* set of patches, > then it is best to stick with a single type of change. Fred's patch is > generally a simple translation: string.foo(s, ...) => s.foo(...) > > Any more than that, and your brain has to keep changing gears. > > A second round of patching can easily go through and make use of the new > .startswith(). Yeah. And you bet how my brain exploded already with this "small" one. :-) ciao - chris -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaunstr. 26 : *Starship* http://starship.python.net 14163 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF where do you want to jump today? http://www.stackless.com From tismer@tismer.com Sat Apr 22 21:44:37 2000 From: tismer@tismer.com (Christian Tismer) Date: Sat, 22 Apr 2000 22:44:37 +0200 Subject: [Patches] Trashcan at its best Message-ID: <39020F35.14D02423@tismer.com> This is a multi-part message in MIME format. --------------B49D064F71B53523C347932D Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit This is a patch for a very much improved version of trashcan - secure destruction of deeply nested objects. The affected files are object.c and object.h only. Improvements: - does no longer need any extra memory - has no relationship to tstate - works in debug mode - can easily be modified for free threading (hi Greg:) Side effects: Trashcan does change the order of object destruction. Prevending that would be quite an immense effort, as my attempts have shown. This version works always the same, with debug mode or not. The slightly changed destruction order should therefore be no problem. Algorithm: While the old idea of delaying the destruction of some obejcts at a certain recursion level was kept, we now no longer aloocate an object to hold these objects. The delayed objects are instead chained together via their ob_type field. The type is encoded via ob_refcnt. When it comes to the destruction of the chain of waiting objects, the topmost object is popped off the chain and revived with type and refcount 1, then it gets a normal Py_DECREF. I am confident that this solution is near optimum for minimizing side effects and code bloat. ciao - chris I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaunstr. 26 : *Starship* http://starship.python.net 14163 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF where do you want to jump today? http://www.stackless.com --------------B49D064F71B53523C347932D Content-Type: text/plain; charset=us-ascii; name="object.h.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="object.h.diff" *** python/dist/src/Include/object.h Wed Apr 19 20:52:02 2000 --- python/spc/src/Include/object.h Sat Apr 22 19:27:52 2000 *************** *** 536,541 **** --- 536,546 ---- Also, we could do an exact stack measure then. Unfortunately, deallocations also take place when the thread state is undefined. + + CT 2k0422 complete rewrite. + There is no need to allocate new objects. + Everything is done vialob_refcnt and ob_type now. + Adding support for free-threading should be easy, too. */ #define PyTrash_UNWIND_LEVEL 50 *************** *** 551,561 **** _PyTrash_deposit_object((PyObject*)op);\ --_PyTrash_delete_nesting; \ if (_PyTrash_delete_later && _PyTrash_delete_nesting <= 0) \ ! _PyTrash_destroy_list(); \ } \ extern DL_IMPORT(void) _PyTrash_deposit_object Py_PROTO((PyObject*)); ! extern DL_IMPORT(void) _PyTrash_destroy_list Py_PROTO(()); extern DL_IMPORT(int) _PyTrash_delete_nesting; extern DL_IMPORT(PyObject *) _PyTrash_delete_later; --- 556,566 ---- _PyTrash_deposit_object((PyObject*)op);\ --_PyTrash_delete_nesting; \ if (_PyTrash_delete_later && _PyTrash_delete_nesting <= 0) \ ! _PyTrash_destroy_chain(); \ } \ extern DL_IMPORT(void) _PyTrash_deposit_object Py_PROTO((PyObject*)); ! extern DL_IMPORT(void) _PyTrash_destroy_chain Py_PROTO(()); extern DL_IMPORT(int) _PyTrash_delete_nesting; extern DL_IMPORT(PyObject *) _PyTrash_delete_later; *************** *** 564,569 **** --- 569,575 ---- #define xxPy_TRASHCAN_SAFE_BEGIN(op) #define xxPy_TRASHCAN_SAFE_END(op) ; + #ifdef __cplusplus } #endif --------------B49D064F71B53523C347932D Content-Type: text/plain; charset=us-ascii; name="object.c.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="object.c.diff" *** python/dist/src/Objects/object.c Wed Apr 19 20:52:12 2000 --- python/spc/src/Objects/object.c Sat Apr 22 21:35:04 2000 *************** *** 33,38 **** --- 33,43 ---- #include "Python.h" + /* just for trashcan: */ + #include "compile.h" + #include "frameobject.h" + #include "traceback.h" + #if defined( Py_TRACE_REFS ) || defined( Py_REF_DEBUG ) DL_IMPORT(long) _Py_RefTotal; #endif *************** *** 822,828 **** { destructor dealloc = op->ob_type->tp_dealloc; _Py_ForgetReference(op); ! op->ob_type = NULL; (*dealloc)(op); } --- 707,714 ---- { destructor dealloc = op->ob_type->tp_dealloc; _Py_ForgetReference(op); ! if (_PyTrash_delete_nesting < PyTrash_UNWIND_LEVEL-1) ! op->ob_type = NULL; (*dealloc)(op); } *************** *** 1045,1081 **** CT 2k0325 added better safe than sorry check for threadstate */ int _PyTrash_delete_nesting = 0; PyObject * _PyTrash_delete_later = NULL; void _PyTrash_deposit_object(op) PyObject *op; { ! PyObject *error_type, *error_value, *error_traceback; ! ! if (PyThreadState_GET() != NULL) ! PyErr_Fetch(&error_type, &error_value, &error_traceback); ! if (!_PyTrash_delete_later) ! _PyTrash_delete_later = PyList_New(0); ! if (_PyTrash_delete_later) ! PyList_Append(_PyTrash_delete_later, (PyObject *)op); ! if (PyThreadState_GET() != NULL) ! PyErr_Restore(error_type, error_value, error_traceback); } void ! _PyTrash_destroy_list() { while (_PyTrash_delete_later) { PyObject *shredder = _PyTrash_delete_later; ! _PyTrash_delete_later = NULL; ++_PyTrash_delete_nesting; Py_DECREF(shredder); --_PyTrash_delete_nesting; } } --- 931,1007 ---- CT 2k0325 added better safe than sorry check for threadstate + + CT 2k0422 + complete rewrite. We now build a chain via ob_type + and save the limited number of types in ob_refcnt. + This is perfect since we don't need any memory. + A patch for free-threading would need just a lock. */ + #define Py_TRASHCAN_TUPLE 1 + #define Py_TRASHCAN_LIST 2 + #define Py_TRASHCAN_DICT 3 + #define Py_TRASHCAN_FRAME 4 + #define Py_TRASHCAN_TRACEBACK 5 + /* extend here if other objects want protection */ + int _PyTrash_delete_nesting = 0; + PyObject * _PyTrash_delete_later = NULL; void _PyTrash_deposit_object(op) PyObject *op; { ! int typecode; ! PyObject *hold = _PyTrash_delete_later; ! if (PyTuple_Check(op)) ! typecode = Py_TRASHCAN_TUPLE; ! else if (PyList_Check(op)) ! typecode = Py_TRASHCAN_LIST; ! else if (PyDict_Check(op)) ! typecode = Py_TRASHCAN_DICT; ! else if (PyFrame_Check(op)) ! typecode = Py_TRASHCAN_FRAME; ! else if (PyTraceBack_Check(op)) ! typecode = Py_TRASHCAN_TRACEBACK; ! op->ob_refcnt = typecode; ! op->ob_type = (PyTypeObject*)_PyTrash_delete_later; ! _PyTrash_delete_later = op; } void ! _PyTrash_destroy_chain() { while (_PyTrash_delete_later) { PyObject *shredder = _PyTrash_delete_later; ! _PyTrash_delete_later = (PyObject*) shredder->ob_type; ! ! switch (shredder->ob_refcnt) { ! case Py_TRASHCAN_TUPLE: ! shredder->ob_type = &PyTuple_Type; ! break; ! case Py_TRASHCAN_LIST: ! shredder->ob_type = &PyList_Type; ! break; ! case Py_TRASHCAN_DICT: ! shredder->ob_type = &PyDict_Type; ! break; ! case Py_TRASHCAN_FRAME: ! shredder->ob_type = &PyFrame_Type; ! break; ! case Py_TRASHCAN_TRACEBACK: ! shredder->ob_type = &PyTraceBack_Type; ! break; ! } ! _Py_NewReference(shredder); ! ++_PyTrash_delete_nesting; Py_DECREF(shredder); --_PyTrash_delete_nesting; } } + --------------B49D064F71B53523C347932D-- From brian@garage.co.jp Sat Apr 22 23:31:23 2000 From: brian@garage.co.jp (Brian Hooper) Date: Sat, 22 Apr 2000 22:31:23 GMT Subject: [Patches] Py_BuildValue Unicode support Message-ID: <20000422223123.17511.qmail@hotmail.com> I just did "U" because I seem to remember seeing big "U" in PyArg_ParseTuple. Do you like the idea of having a version that can be used without length as long as the input Unicode data is null-terminated? From the playing around that I have been doing up to this point, I think this would be convenient to have. --Brian >From: "M.-A. Lemburg" >To: Guido van Rossum >CC: brian@garage.co.jp, patches@python.org >Subject: Re: [Patches] Py_BuildValue Unicode support >Date: Sat, 22 Apr 2000 17:04:16 +0200 > >Guido van Rossum wrote: > > > > > There might be a nicer way to do this, but I wanted to be able to > > > use Py_BuildValue to produce Unicode objects, so I added a few > > > lines to modsupport to do this. Each Unicode object requires > > > two arguments, the raw Py_UNICODE string and the length as an > > > integer. I think since all Python Unicode strings are 0 terminated, > > > it might be nice to make this into "U#" and also allow a plain "U" > > > to mean a (double) null-terminated Unicode string as input; however, > > > I'll leave that up to you all to determine (I would personally like > > > to see this option). > > > > Yes, what you coded here should be called U#. > >Perhaps the naming should be "u#" and "u" rather than "U#" and >"U" !? This would be in sync with "s#" and "s" for 8-bit strings. > >-- >Marc-Andre Lemburg >______________________________________________________________________ >Business: http://www.lemburg.com/ >Python Pages: http://www.lemburg.com/python/ > > ________________________________________________________________________ Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com From mhammond@skippinet.com.au Sun Apr 23 03:34:59 2000 From: mhammond@skippinet.com.au (Mark Hammond) Date: Sun, 23 Apr 2000 12:34:59 +1000 Subject: [Patches] RE: Trashcan at its best In-Reply-To: <39020F35.14D02423@tismer.com> Message-ID: > This is a patch for a very much improved > version of trashcan - secure destruction of > deeply nested objects. Cool. > The delayed objects are instead chained together > via their ob_type field. The type is encoded via > ob_refcnt. When it comes to the destruction of the > chain of waiting objects, the topmost object is popped > off the chain and revived with type and refcount 1, > then it gets a normal Py_DECREF. Eeek!!! Erm - Im glad Im not the one having the final say on this :-) =20 FYI - I did _not_ review the patch, but did apply it. It appears to = leave my machine running fine, including the deeply recursive code that = blew this up in the first place... Should this status change, I'll let = you know ;-) Mark. From gward@mems-exchange.org Sun Apr 23 04:13:53 2000 From: gward@mems-exchange.org (Greg Ward) Date: Sat, 22 Apr 2000 23:13:53 -0400 Subject: [Patches] Review (was: Please review before applying) In-Reply-To: ; from gstein@lyra.org on Sat, Apr 22, 2000 at 12:16:02PM -0700 References: <3901D813.D2148C44@tismer.com> Message-ID: <20000422231352.A9588@mems-exchange.org> On 22 April 2000, Greg Stein said: > On Sat, 22 Apr 2000, Christian Tismer wrote: > >... > > ---/+++ cgi.py, line 704 > > you are changing > > plist = map(string.strip, string.splitfields(line, ';')) > > into > > plist = map(lambda s: s.strip(), line.split(';')) > > > > I don't the extra lambda-ness and the extra frames generated here > > are an advantage. > > No... use the lambda. string.strip is a function that is equal to that > lambda. Therefore, it is better to avoid the string module altogether and > to use the lambda. No way! Christian is *totally* right here. I'll let Christian be the expert on the cost of creating a new stack frame or a new function object -- he should know -- but two non-propellor-head arguments are completely compelling: * string.split is implemented in C, "lambda s: s.string()" is not * understanding "map (string.split, ...)" requires approximately zero brainpower; understanding "map (lambda s: ...)" requires a good second or so of bouncing around the expression trying to figure out what gets plugged in where. Greg -- Greg Ward - software developer gward@mems-exchange.org MEMS Exchange / CNRI voice: +1-703-262-5376 Reston, Virginia, USA fax: +1-703-262-5367 From mhammond@skippinet.com.au Sun Apr 23 05:57:38 2000 From: mhammond@skippinet.com.au (Mark Hammond) Date: Sun, 23 Apr 2000 14:57:38 +1000 Subject: [Patches] Change to reference-dump procedure at shutdown Message-ID: This patch only affects debug builds with Py_TRACE_REFS defined. This = is the default for debug builds on Windows. At shutdown, Python offers to dump the remaining references. This = upsets a few programs, such as debug COM servers, or any program that = uses 'sys.executable' to launch a child-process. The process never = terminates, as it is waiting to find out if you want the references = dumped. Further, simply starting and closing the Python interpreter on Windows = results in over 2000 references - its unlikely people want to print them = that often :-) The patch below only offers to dump the references if the environment = variable PYTHONDUMPREFS is set. Otherwise, it still prints the number = of references, but immediately terminates. If this patch is acceptable and it is felt this variable should be = documented, let me know, and I will try and hunt down all the relevant = places - but IMO, anyone who really needs these references dumped is = likely to see this code :-) diff -c -r2.92 pythonrun.c *** pythonrun.c 2000/04/14 19:13:24 2.92 --- pythonrun.c 2000/04/23 04:49:05 *************** *** 242,248 **** #endif =20 #ifdef Py_TRACE_REFS ! if (_Py_AskYesNo("Print left references?")) { _Py_PrintReferences(stderr); } #endif /* Py_TRACE_REFS */ --- 242,249 ---- #endif =20 #ifdef Py_TRACE_REFS ! if (getenv("PYTHONDUMPREFS") &&=20 ! _Py_AskYesNo("Print left references?")) { _Py_PrintReferences(stderr); } #endif /* Py_TRACE_REFS */ Release info: I confirm that, to the best of my knowledge and belief, this = contribution is free of any claims of third parties under copyright, = patent or other rights or interests ("claims"). To the extent that I = have any such claims, I hereby grant to CNRI a nonexclusive, = irrevocable, royalty-free, worldwide license to reproduce, distribute, = perform and/or display publicly, prepare derivative versions, and = otherwise use this contribution as part of the Python software and its = related documentation, or any derivative versions thereof, at no cost to = CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or = not to incorporate this contribution in the Python software and its = related documentation. I further grant CNRI permission to use my name = and other identifying information provided to CNRI by me for use in = connection with the Python software and its related documentation. Mark. From Moshe Zadka Sun Apr 23 06:11:46 2000 From: Moshe Zadka (Moshe Zadka) Date: Sun, 23 Apr 2000 08:11:46 +0300 (IDT) Subject: [Patches] Review (was: Please review before applying) In-Reply-To: <20000422231352.A9588@mems-exchange.org> Message-ID: On Sat, 22 Apr 2000, Greg Ward wrote: > No way! Christian is *totally* right here. I'll let Christian be the > expert on the cost of creating a new stack frame or a new function > object -- he should know -- but two non-propellor-head arguments are > completely compelling: > > * string.split is implemented in C, "lambda s: s.string()" is not Ummm....Isn't string.split implemented in Python, and just calls the .split method of it's first argument? oldstring.split is implemented in C, but is deprecated. > * understanding "map (string.split, ...)" requires approximately > zero brainpower; understanding "map (lambda s: ...)" requires > a good second or so of bouncing around the expression trying > to figure out what gets plugged in where. That's probably a better excuse anything-to-get-rid-of-lambdas-ly y'rs, Z. -- Moshe Zadka . http://www.oreilly.com/news/prescod_0300.html http://www.linux.org.il -- we put the penguin in .com From skip@mojam.com (Skip Montanaro) Sun Apr 23 13:23:50 2000 From: skip@mojam.com (Skip Montanaro) (Skip Montanaro) Date: Sun, 23 Apr 2000 07:23:50 -0500 (CDT) Subject: [Patches] Review (was: Please review before applying) In-Reply-To: <20000422231352.A9588@mems-exchange.org> References: <3901D813.D2148C44@tismer.com> <20000422231352.A9588@mems-exchange.org> Message-ID: <14594.60246.161584.33770@beluga.mojam.com> Greg> * string.split is implemented in C, "lambda s: s.string()" is not If you look at string.py now you'll see that string.split actually calls a Python function (essentially the same function as executing the lambda statement generates), unlike the old days where string would have imported split from the strop extension module. In short, calling string.* generally will incur an extra function call than in 1.5. Greg> * understanding "map (string.split, ...)" requires approximately Greg> zero brainpower; understanding "map (lambda s: ...)" requires Greg> a good second or so of bouncing around the expression trying Greg> to figure out what gets plugged in where. Since this particular code is in cgi.parse_header, which isn't going to be a performance bottleneck (leave that to forking the CGI script or doing the script's real work), if clarity is in question let me suggest that the map be replaced with a for loop, something like: plist = line.split(';') for i in range(len(plist)): plist[i] = plist[i].split() -- Skip Montanaro | http://www.mojam.com/ skip@mojam.com | http://www.musi-cal.com/ From tismer@tismer.com Sun Apr 23 15:43:03 2000 From: tismer@tismer.com (Christian Tismer) Date: Sun, 23 Apr 2000 16:43:03 +0200 Subject: [Patches] Re: Trashcan at its best References: Message-ID: <39030BF7.D353146E@tismer.com> Mark Hammond wrote: > > > This is a patch for a very much improved > > version of trashcan - secure destruction of > > deeply nested objects. > > Cool. > > > The delayed objects are instead chained together > > via their ob_type field. The type is encoded via > > ob_refcnt. When it comes to the destruction of the > > chain of waiting objects, the topmost object is popped > > off the chain and revived with type and refcount 1, > > then it gets a normal Py_DECREF. > > Eeek!!! > > Erm - Im glad Im not the one having the final say on this :-) Oh, this isn't so different from the first version: It appended dead objects to a list, therefore reviving them. Now this is done explicitly, by _PyNew_Reference, that's just fine. Or do you mean that refcount abuse? It is just an integer, and I switch with a case. No, I think this belongs to some of my cleanest code snippets. > FYI - I did _not_ review the patch, but did apply it. It appears to leave my machine running fine, including the deeply recursive code that blew this up in the first place... Should this status change, I'll let you know ;-) I knew that it would work. I did an extra debug build for you and tested things hard until I sent it out. Especially the right condition on when to clear the ob_type field was not so obvious to find in the first place. -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaunstr. 26 : *Starship* http://starship.python.net 14163 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF where do you want to jump today? http://www.stackless.com From guido@python.org Sun Apr 23 17:02:42 2000 From: guido@python.org (Guido van Rossum) Date: Sun, 23 Apr 2000 12:02:42 -0400 Subject: [Patches] Py_BuildValue Unicode support In-Reply-To: Your message of "Sat, 22 Apr 2000 22:31:23 GMT." <20000422223123.17511.qmail@hotmail.com> References: <20000422223123.17511.qmail@hotmail.com> Message-ID: <200004231602.MAA19202@eric.cnri.reston.va.us> > I just did "U" because I seem to remember seeing big "U" in > PyArg_ParseTuple. The difference there is that it takes a Unicode *object*, like O and S -- not a unicode data pointer, like s#. > Do you like the idea of having a version that can be used without > length as long as the input Unicode data is null-terminated? From > the playing around that I have been doing up to this point, I think > this would be convenient to have. Sure. --Guido van Rossum (home page: http://www.python.org/~guido/) From gstein@lyra.org Mon Apr 24 04:49:45 2000 From: gstein@lyra.org (Greg Stein) Date: Sun, 23 Apr 2000 20:49:45 -0700 (PDT) Subject: [Patches] Review (was: Please review before applying) In-Reply-To: <14594.60246.161584.33770@beluga.mojam.com> Message-ID: On Sun, 23 Apr 2000, Skip Montanaro wrote: > Greg> * string.split is implemented in C, "lambda s: s.string()" is not > > If you look at string.py now you'll see that string.split actually calls a > Python function (essentially the same function as executing the lambda > statement generates), unlike the old days where string would have imported > split from the strop extension module. In short, calling string.* generally > will incur an extra function call than in 1.5. Exactly. This is why I recommended avoiding string.* (note the lambda in question is to call s.strip()) > Greg> * understanding "map (string.split, ...)" requires approximately > Greg> zero brainpower; understanding "map (lambda s: ...)" requires > Greg> a good second or so of bouncing around the expression trying > Greg> to figure out what gets plugged in where. > > Since this particular code is in cgi.parse_header, which isn't going to be a > performance bottleneck (leave that to forking the CGI script or doing the > script's real work), if clarity is in question let me suggest that the map > be replaced with a for loop, something like: > > plist = line.split(';') > for i in range(len(plist)): > plist[i] = plist[i].split() And it should generally be faster, too, since there aren't function invocations in the main loop. The main point is to avoid string.*. Cheers, -g -- Greg Stein, http://www.lyra.org/ From tismer@trixie.triqs.com Mon Apr 24 13:49:11 2000 From: tismer@trixie.triqs.com (Christian Tismer) Date: Mon, 24 Apr 2000 14:49:11 +0200 Subject: [Patches] Review (was: Please review before applying) References: Message-ID: <390442C7.F30179D9@trixie.triqs.com> Greg Stein wrote: ... > The main point is to avoid string.*. Agreed. Also replacing map by a loop might not even be slower. What remains as open question: Several modules need access to string constants, and they therefore still have to import string. Is there an elegant solution to this? That's why i asked for some way to access "".__class__ or whatever, to get into some common namespace with the constants. ciao - chris -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaunstr. 26 : *Starship* http://starship.python.net 14163 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF where do you want to jump today? http://www.stackless.com From guido@python.org Mon Apr 24 14:50:57 2000 From: guido@python.org (Guido van Rossum) Date: Mon, 24 Apr 2000 09:50:57 -0400 Subject: [Patches] Change to reference-dump procedure at shutdown In-Reply-To: Your message of "Sun, 23 Apr 2000 14:57:38 +1000." References: Message-ID: <200004241350.JAA20387@eric.cnri.reston.va.us> > This patch only affects debug builds with Py_TRACE_REFS defined. This is the default for debug builds on Windows. > > At shutdown, Python offers to dump the remaining references. This upsets a few programs, such as debug COM servers, or any program that uses 'sys.executable' to launch a child-process. The process never terminates, as it is waiting to find out if you want the references dumped. > > Further, simply starting and closing the Python interpreter on Windows results in over 2000 references - its unlikely people want to print them that often :-) > > The patch below only offers to dump the references if the environment variable PYTHONDUMPREFS is set. Otherwise, it still prints the number of references, but immediately terminates. > > If this patch is acceptable and it is felt this variable should be documented, let me know, and I will try and hunt down all the relevant places - but IMO, anyone who really needs these references dumped is likely to see this code :-) Mark, shouldn't this be enclosed in an #ifdef MS_WINDOWS bracket? --Guido van Rossum (home page: http://www.python.org/~guido/) From guido@python.org Mon Apr 24 15:40:36 2000 From: guido@python.org (Guido van Rossum) Date: Mon, 24 Apr 2000 10:40:36 -0400 Subject: [Patches] urllib: POST with arbitrary mime type In-Reply-To: Your message of "Sat, 22 Apr 2000 16:03:54 +0200." <00c201bfac63$b03d2440$34aab5d4@hagrid> References: <00c201bfac63$b03d2440$34aab5d4@hagrid> Message-ID: <200004241440.KAA23325@eric.cnri.reston.va.us> One suggestion -- rather than testing for type(data)==type(''), wouldn't it be better to test for isinstance(data, RequestBody)? Also, it seems that your Form class is broken. It passes a dict as the body argument the the base class constructor, but it is later used as a string. I suggest that you test this one more extensively. Perhaps add some testcases to test_urllib.py? --Guido van Rossum (home page: http://www.python.org/~guido/) From guido@python.org Mon Apr 24 15:42:39 2000 From: guido@python.org (Guido van Rossum) Date: Mon, 24 Apr 2000 10:42:39 -0400 Subject: [Patches] unicode tweaks, part 3 In-Reply-To: Your message of "Sat, 22 Apr 2000 14:44:16 +0200." <006901bfac58$79fd34c0$34aab5d4@hagrid> References: <006901bfac58$79fd34c0$34aab5d4@hagrid> Message-ID: <200004241442.KAA23592@eric.cnri.reston.va.us> In private mail, Marc-Andre mentioned that he thinks Fredrik's patches aren't quite ready for prime time. I suggest that the two hash this out on python-dev before I accept the patch. --Guido van Rossum (home page: http://www.python.org/~guido/) From guido@python.org Mon Apr 24 15:53:13 2000 From: guido@python.org (Guido van Rossum) Date: Mon, 24 Apr 2000 10:53:13 -0400 Subject: [Patches] Patch to socketmodule.c In-Reply-To: Your message of "Sat, 22 Apr 2000 01:19:08 +0200." <3900E1EC.A6CAA0C5@oratrix.nl> References: <3900E1EC.A6CAA0C5@oratrix.nl> Message-ID: <200004241453.KAA25772@eric.cnri.reston.va.us> > Subject: [Patches] Patch to socketmodule.c > The GUSI 2.0 I/O library used on the Mac uses the socklen_t (unsigned int) for > most size parameters. > Apparently this is part of the UNIX 98 standard, but for now the code is > #ifdeffed with USE_GUSI. Alas, it breaks on Solaris (SunOS 5.7). I guess I'll have to add a test for it to configure.in. Sigh. I'll check in the correct fix. --Guido van Rossum (home page: http://www.python.org/~guido/) From Fredrik Lundh" <200004241440.KAA23325@eric.cnri.reston.va.us> Message-ID: <00e301bfae14$4d21c160$34aab5d4@hagrid> Guido wrote: > One suggestion -- rather than testing for type(data)=3D=3Dtype(''), > wouldn't it be better to test for isinstance(data, RequestBody)? that would make it impossible to drop in an object implementing the same protocol (gettype and getbody) -- and the old code only worked for strings anyway... but sure, I can change this. how about: if isinstance(data, RequestBody): body =3D data else: body =3D RequestBody(str(data)) > Also, it seems that your Form class is broken. It passes a dict as > the body argument the the base class constructor, but it is later used > as a string. note that it also overrides the getbody() function. but alright, I probably don't need to optimize for the case where httplib.HOST fails to connect ;-) btw, what about making the class even more flexible? how about something like: class RequestBody: ... def gettype(self): return "application/x-www-form-urlencoded" def getrequest(self): return "POST" def sendheader(self, http): http.putrequest(self.getrequest()) http.putheader("Content-type", self.gettype()) http.putheader("Content-length", str(self.bytes)) def sendbody(self, http) -> send http.send(self.data) > I suggest that you test this one more extensively. Perhaps add some > testcases to test_urllib.py? gotta create that one first, right? From guido@python.org Mon Apr 24 18:42:30 2000 From: guido@python.org (Guido van Rossum) Date: Mon, 24 Apr 2000 13:42:30 -0400 Subject: [Patches] urllib: POST with arbitrary mime type In-Reply-To: Your message of "Mon, 24 Apr 2000 19:41:17 +0200." <00e301bfae14$4d21c160$34aab5d4@hagrid> References: <00c201bfac63$b03d2440$34aab5d4@hagrid> <200004241440.KAA23325@eric.cnri.reston.va.us> <00e301bfae14$4d21c160$34aab5d4@hagrid> Message-ID: <200004241742.NAA29359@eric.cnri.reston.va.us> Yes. --Guido van Rossum (home page: http://www.python.org/~guido/) From cgw@fnal.gov Mon Apr 24 20:38:20 2000 From: cgw@fnal.gov (Charles G Waldman) Date: Mon, 24 Apr 2000 14:38:20 -0500 (CDT) Subject: [Patches] why not just apply Garbage Collection patch? Message-ID: <14596.41644.182242.918286@buffalo.fnal.gov> Neil's GC is an excellent piece of work, and I hope it makes it into 1.6. I spent a lot of time this Easter weekend reading the code and playing around with it. I'll do what I can to test it on large volumes of production code (I have plenty of machines at my disposal...) Unfortunately, with my recent changes to tupleobject.c and Christian's recent changes to the Trashcan, the gc patch no longer applies cleanly, and after hand-patching, it doesn't seem to work (Python hangs forever on startup, after printing a lone gc: collectable message. When I get some time, I'll try to find out why this is happening. In the meanwhile, I propose that Neil's patch be applied to the main CVS sources. Since you have to enable it on the configure line with "--with-cycle-gc" it seems harmless enough to just check the patches in. Then we don't have the problem of the GC stuff getting out-of-sync with all the other changes that are happening. Furthermore, the earlier it gets into the alpha process, the more people will be encouraged to play around and test it out. If it turns out to be a disaster (I'm not expecting this!) we can just back it all out, right? Everything is already protected with "#ifdef WITH_CYCLE_GC" anyhow, right? Just my $0.002, -C From guido@python.org Mon Apr 24 21:13:08 2000 From: guido@python.org (Guido van Rossum) Date: Mon, 24 Apr 2000 16:13:08 -0400 Subject: [Patches] why not just apply Garbage Collection patch? In-Reply-To: Your message of "Mon, 24 Apr 2000 14:38:20 CDT." <14596.41644.182242.918286@buffalo.fnal.gov> References: <14596.41644.182242.918286@buffalo.fnal.gov> Message-ID: <200004242013.QAA29938@eric.cnri.reston.va.us> > Neil's GC is an excellent piece of work, and I hope it makes it into > 1.6. I spent a lot of time this Easter weekend reading the code and > playing around with it. > > I'll do what I can to test it on large volumes of production code (I > have plenty of machines at my disposal...) Thanks. I haven't looked at it lately. What do you think of binary compatibility? Could an extension built before this was patched in get in trouble because of changed object lay-out? > Unfortunately, with my recent changes to tupleobject.c and Christian's > recent changes to the Trashcan, the gc patch no longer applies > cleanly, and after hand-patching, it doesn't seem to work (Python > hangs forever on startup, after printing a lone > > gc: collectable > > message. > > When I get some time, I'll try to find out why this is happening. Maybe Neil or Christian can lend a hand? The trashcan stuff is definitely hackish. :-) > In the meanwhile, I propose that Neil's patch be applied to the main > CVS sources. Since you have to enable it on the configure line with > "--with-cycle-gc" it seems harmless enough to just check the patches > in. Then we don't have the problem of the GC stuff getting > out-of-sync with all the other changes that are happening. > Furthermore, the earlier it gets into the alpha process, the more > people will be encouraged to play around and test it out. If it turns > out to be a disaster (I'm not expecting this!) we can just back it all > out, right? Everything is already protected with "#ifdef > WITH_CYCLE_GC" anyhow, right? I'd rather wait until you or Neil submits a new version of the patch that (1) applies cleanly to the current CVS and (2) actually runs. Plus, I owe Vladimir Marangozov a green light to generate a new version of his memory management patches; that will also interfere with the GC patches (and make a few things easier, I believe). Vladimir's patches should preferably be applied before Neil's. --Guido van Rossum (home page: http://www.python.org/~guido/) From mhammond@skippinet.com.au Tue Apr 25 01:33:22 2000 From: mhammond@skippinet.com.au (Mark Hammond) Date: Tue, 25 Apr 2000 10:33:22 +1000 Subject: [Patches] Change to reference-dump procedure at shutdown In-Reply-To: <200004241350.JAA20387@eric.cnri.reston.va.us> Message-ID: > > If this patch is acceptable and it is felt this=20 > variable should be documented, let me know, and I will=20 > try and hunt down all the relevant places - but IMO,=20 > anyone who really needs these references dumped is likely=20 > to see this code :-) >=20 > Mark, shouldn't this be enclosed in an #ifdef MS_WINDOWS bracket? Quite possibly. However, I was assuming that given there are over 2000 = references outstanding when just starting and stopping the interpreter, = the behaviour made sense for _all_ platforms, not just Windows. Of course, just getting it for Windows still suits me fine... Mark. From mhammond@skippinet.com.au Tue Apr 25 02:38:40 2000 From: mhammond@skippinet.com.au (Mark Hammond) Date: Tue, 25 Apr 2000 11:38:40 +1000 Subject: [Patches] MSVC project change to include winsound as dependency Message-ID: This is a multi-part message in MIME format. ------=_NextPart_000_005D_01BFAEAA.CDBF1A70 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable This updates the MSVC workspace to ensure the winsound project depends = on the core DLL. Ive attached the file complete, rather than a diff, as it is checked in = as binary. Release info: I confirm that, to the best of my knowledge and belief, this = contribution is free of any claims of third parties under copyright, = patent or other rights or interests ("claims"). To the extent that I = have any such claims, I hereby grant to CNRI a nonexclusive, = irrevocable, royalty-free, worldwide license to reproduce, distribute, = perform and/or display publicly, prepare derivative versions, and = otherwise use this contribution as part of the Python software and its = related documentation, or any derivative versions thereof, at no cost to = CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or = not to incorporate this contribution in the Python software and its = related documentation. I further grant CNRI permission to use my name = and other identifying information provided to CNRI by me for use in = connection with the Python software and its related documentation. Mark. ------=_NextPart_000_005D_01BFAEAA.CDBF1A70 Content-Type: application/octet-stream; name="pcbuild.dsw" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="pcbuild.dsw" Microsoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! #########################################################################= ###### Project: "_socket"=3D".\_socket.dsp" - Package Owner=3D<4> Package=3D<5> {{{ }}} Package=3D<4> {{{ Begin Project Dependency Project_Dep_Name python16 End Project Dependency }}} #########################################################################= ###### Project: "_sre"=3D".\_sre.dsp" - Package Owner=3D<4> Package=3D<5> {{{ }}} Package=3D<4> {{{ Begin Project Dependency Project_Dep_Name python16 End Project Dependency }}} #########################################################################= ###### Project: "_tkinter"=3D".\_tkinter.dsp" - Package Owner=3D<4> Package=3D<5> {{{ }}} Package=3D<4> {{{ Begin Project Dependency Project_Dep_Name python16 End Project Dependency }}} #########################################################################= ###### Project: "bsddb"=3D".\bsddb.dsp" - Package Owner=3D<4> Package=3D<5> {{{ }}} Package=3D<4> {{{ Begin Project Dependency Project_Dep_Name python16 End Project Dependency }}} #########################################################################= ###### Project: "mmap"=3D".\mmap.dsp" - Package Owner=3D<4> Package=3D<5> {{{ }}} Package=3D<4> {{{ Begin Project Dependency Project_Dep_Name python16 End Project Dependency }}} #########################################################################= ###### Project: "parser"=3D".\parser.dsp" - Package Owner=3D<4> Package=3D<5> {{{ }}} Package=3D<4> {{{ Begin Project Dependency Project_Dep_Name python16 End Project Dependency }}} #########################################################################= ###### Project: "pyexpat"=3D".\pyexpat.dsp" - Package Owner=3D<4> Package=3D<5> {{{ }}} Package=3D<4> {{{ Begin Project Dependency Project_Dep_Name python16 End Project Dependency }}} #########################################################################= ###### Project: "python"=3D".\python.dsp" - Package Owner=3D<4> Package=3D<5> {{{ }}} Package=3D<4> {{{ Begin Project Dependency Project_Dep_Name python16 End Project Dependency }}} #########################################################################= ###### Project: "python16"=3D".\python16.dsp" - Package Owner=3D<4> Package=3D<5> {{{ }}} Package=3D<4> {{{ }}} #########################################################################= ###### Project: "pythonw"=3D".\pythonw.dsp" - Package Owner=3D<4> Package=3D<5> {{{ }}} Package=3D<4> {{{ Begin Project Dependency Project_Dep_Name python16 End Project Dependency }}} #########################################################################= ###### Project: "select"=3D".\select.dsp" - Package Owner=3D<4> Package=3D<5> {{{ }}} Package=3D<4> {{{ Begin Project Dependency Project_Dep_Name python16 End Project Dependency }}} #########################################################################= ###### Project: "unicodedata"=3D".\unicodedata.dsp" - Package Owner=3D<4> Package=3D<5> {{{ }}} Package=3D<4> {{{ Begin Project Dependency Project_Dep_Name python16 End Project Dependency }}} #########################################################################= ###### Project: "winreg"=3D".\winreg.dsp" - Package Owner=3D<4> Package=3D<5> {{{ }}} Package=3D<4> {{{ Begin Project Dependency Project_Dep_Name python16 End Project Dependency }}} #########################################################################= ###### Project: "winsound"=3D".\winsound.dsp" - Package Owner=3D<4> Package=3D<5> {{{ }}} Package=3D<4> {{{ Begin Project Dependency Project_Dep_Name python16 End Project Dependency }}} #########################################################################= ###### Project: "zlib"=3D".\zlib.dsp" - Package Owner=3D<4> Package=3D<5> {{{ }}} Package=3D<4> {{{ Begin Project Dependency Project_Dep_Name python16 End Project Dependency }}} #########################################################################= ###### Global: Package=3D<5> {{{ }}} Package=3D<3> {{{ }}} #########################################################################= ###### ------=_NextPart_000_005D_01BFAEAA.CDBF1A70-- From tim_one@email.msn.com Tue Apr 25 06:43:54 2000 From: tim_one@email.msn.com (Tim Peters) Date: Tue, 25 Apr 2000 01:43:54 -0400 Subject: [Patches] memory leaks triggered by "test_extcall" In-Reply-To: <200004212109.RAA17737@eric.cnri.reston.va.us> Message-ID: <000501bfae79$40004aa0$152d153f@tim> [Christian Tismer] > Yes, but aren't we going to implant Neil's GC, soon? [Guido] > Maybe -- I'm a little worried that it will destabilize 1.6. Or am I > too worried? IIRC, it was all #ifdef'ed -- leave it off by default, if need be, but get it out there. People will play with it if it's easy to enable, and you'll be worried for just as long as people *don't* play with it . From mwh21@cam.ac.uk Tue Apr 25 09:00:45 2000 From: mwh21@cam.ac.uk (Michael Hudson) Date: Tue, 25 Apr 2000 09:00:45 +0100 (BST) Subject: [Patches] more docstrings for os Message-ID: I think that after this patch, all objects in the os module (with names that don't start with "_") that can have docstrings, do, on Linux at least. Also fix a nit in one of my spawn* docstrings. Cheers, M. I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. Index: os.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/os.py,v retrieving revision 1.32 diff -u -r1.32 os.py --- os.py 2000/04/21 18:35:36 1.32 +++ os.py 2000/04/25 07:57:25 @@ -183,23 +183,51 @@ environ = {} def execl(file, *args): + """execl(file, *args) + + Execute the executable file with argument list args, replacing the + current process. """ execv(file, args) def execle(file, *args): + """execle(file, *args, env) + + Execute the executable file with argument list args and + environment env, replacing the current process. """ env = args[-1] execve(file, args[:-1], env) def execlp(file, *args): + """execlp(file, *args) + + Execute the executable file (which is searched for along $PATH) + with argument list args, replacing the current process. """ execvp(file, args) def execlpe(file, *args): + """execlpe(file, *args, env) + + Execute the executable file (which is searched for along $PATH) + with argument list args and environment env, replacing the current + process. """ env = args[-1] execvpe(file, args[:-1], env) def execvp(file, args): + """execp(file, args) + + Execute the executable file (which is searched for along $PATH) + with argument list args, replacing the current process. + args may be a list or tupe of strings. """ _execvpe(file, args) def execvpe(file, args, env): + """execv(file, args, env) + + Execute the executable file (which is searched for along $PATH) + with argument list args and environment env , replacing the + current process. + args may be a list or tupe of strings. """ _execvpe(file, args, env) _notfound = None @@ -338,7 +366,7 @@ Execute file with arguments from args in a subprocess. If mode == P_NOWAIT return the pid of the process. If mode == P_WAIT return the process's exit code if it exits normally; -otherwise return - (the signal that killed it). """ +otherwise return -SIG, where SIG is the signal that killed it. """ return _spawnvef(mode, file, args, None, execv) def spawnve(mode, file, args, env): From cgw@alum.mit.edu Tue Apr 25 15:51:04 2000 From: cgw@alum.mit.edu (Charles G Waldman) Date: Tue, 25 Apr 2000 09:51:04 -0500 (CDT) Subject: [Patches] Slightly cleaned-up cycle-gc patch Message-ID: <14597.45272.956559.551023@sirius.net.home> DQpUaGUgcHJvYmxlbXMgSSB3YXMgaGF2aW5nIGdldHRpbmcgTmVpbCdzIGN5Y2xpYy1nYyBz dHVmZiB0byB3b3JrIHdpdGgNCnRoZSBsYXRlc3QgQ1ZTIFB5dGhvbiBoYWQgbm90aGluZyB0 byBkbyB3aXRoIFRyYXNoY2FuIC0gc29ycnksDQpDaHJpc3RpYW4hICBJdCB3YXMgbXkgb3du IGNoYW5nZXMgdG8gdHVwbGVvYmplY3QuYy4gIEl0IHR1cm5lZCBvdXQgdG8NCmJlIGEgbGl0 dGxlIHRyaWNreSB0byBnZXQgdGhlIEdDIGluZm8gaGFuZGxlZCBjb3JyZWN0bHkgZHVyaW5n DQpfUHlUdXBsZV9SZXNpemUuICBCZWxvdyBpcyBhIHZlcnNpb24gb2YgTmVpbCdzIHBhdGNo IHRoYXQgYXBwbGllcw0KY2xlYW5seSB0byBjdXJyZW50IENWUyBhbmQgc2VlbXMgdG8gd29y ayBjb3JyZWN0bHkuICBBbGwgY3JlZGl0IGlzIGR1ZQ0KdG8gTmVpbCwgSSBqdXN0IGRpZCBh IHRpbnkgYW1vdW50IG9mIGNsZWFudXAgd29yayBpbiBhIGZldyBwbGFjZXMuDQoNCkRpZmZl cmVuY2VzOiAgDQoNCiAgKDEpIFRoZSBhYm92ZS1tZW50aW9uZWQgX1B5VHVwbGVfUmVzaXpl IGZpeA0KDQogICgyKSBBIGZldyBwcm9ibGVtcyB3ZXJlIGV4cG9zZWQgYnkgYnVpbGRpbmcg d2l0aCBQeV9UUkFDRV9SRUZTDQpkZWZpbmVkLiAgU3BlY2lmaWFsbHksIFB5T2JqZWN0X05l dyBhbmQgUHlPYmplY3RfTmV3VmFyIGFscmVhZHkgZG8gYQ0KX1B5X05ld1JlZmVyZW5jZSBp bnRlcm5hbGx5LCBidXQgaW4gYSBmZXcgcGxhY2VzIFB5T2JqZWN0X05ldyBpcw0KdXNlZCB0 byBjcmVhdGUgYSBuZXcgb2JqZWN0IHdoaWNoIGlzIHRoZW4gX1B5X05ld1JlZmVyZW5jZSdk LiAgSWYNClB5X1RSQUNFX1JFRlMgaXMgbm90IHNldCwgdGhpcyBpcyBtZXJlbHkgcmVkdW5k YW50OyB3aXRoDQpQeV9UUkFDRV9SRUZTIHNldCBpdCBjYXVzZXMgc2VyaW91cyBwcm9ibGVt cyBiZWNhdXNlIHRoZSBvYmplY3QgaXMNCmFkZGVkIHRvIHRoZSByZWZlcmVuY2UgY2hhaW4g dHdpY2UuDQoNCg0KICAgICAgICAgICAgICAgICAgSSBjb25maXJtIHRoYXQsIHRvIHRoZSBi ZXN0IG9mIG15IGtub3dsZWRnZSBhbmQgYmVsaWVmLCB0aGlzDQogICAgICAgICAgICAgICAg ICBjb250cmlidXRpb24gaXMgZnJlZSBvZiBhbnkgY2xhaW1zIG9mIHRoaXJkIHBhcnRpZXMg dW5kZXINCiAgICAgICAgICAgICAgICAgIGNvcHlyaWdodCwgcGF0ZW50IG9yIG90aGVyIHJp Z2h0cyBvciBpbnRlcmVzdHMgKCJjbGFpbXMiKS4gIFRvDQogICAgICAgICAgICAgICAgICB0 aGUgZXh0ZW50IHRoYXQgSSBoYXZlIGFueSBzdWNoIGNsYWltcywgSSBoZXJlYnkgZ3JhbnQg dG8gQ05SSSBhDQogICAgICAgICAgICAgICAgICBub25leGNsdXNpdmUsIGlycmV2b2NhYmxl LCByb3lhbHR5LWZyZWUsIHdvcmxkd2lkZSBsaWNlbnNlIHRvDQogICAgICAgICAgICAgICAg ICByZXByb2R1Y2UsIGRpc3RyaWJ1dGUsIHBlcmZvcm0gYW5kL29yIGRpc3BsYXkgcHVibGlj bHksIHByZXBhcmUNCiAgICAgICAgICAgICAgICAgIGRlcml2YXRpdmUgdmVyc2lvbnMsIGFu ZCBvdGhlcndpc2UgdXNlIHRoaXMgY29udHJpYnV0aW9uIGFzIHBhcnQNCiAgICAgICAgICAg ICAgICAgIG9mIHRoZSBQeXRob24gc29mdHdhcmUgYW5kIGl0cyByZWxhdGVkIGRvY3VtZW50 YXRpb24sIG9yIGFueQ0KICAgICAgICAgICAgICAgICAgZGVyaXZhdGl2ZSB2ZXJzaW9ucyB0 aGVyZW9mLCBhdCBubyBjb3N0IHRvIENOUkkgb3IgaXRzIGxpY2Vuc2VkDQogICAgICAgICAg ICAgICAgICB1c2VycywgYW5kIHRvIGF1dGhvcml6ZSBvdGhlcnMgdG8gZG8gc28uDQoNCiAg ICAgICAgICAgICAgICAgIEkgYWNrbm93bGVkZ2UgdGhhdCBDTlJJIG1heSwgYXQgaXRzIHNv bGUgZGlzY3JldGlvbiwgZGVjaWRlDQogICAgICAgICAgICAgICAgICB3aGV0aGVyIG9yIG5v dCB0byBpbmNvcnBvcmF0ZSB0aGlzIGNvbnRyaWJ1dGlvbiBpbiB0aGUgUHl0aG9uDQogICAg ICAgICAgICAgICAgICBzb2Z0d2FyZSBhbmQgaXRzIHJlbGF0ZWQgZG9jdW1lbnRhdGlvbi4g IEkgZnVydGhlciBncmFudCBDTlJJDQogICAgICAgICAgICAgICAgICBwZXJtaXNzaW9uIHRv IHVzZSBteSBuYW1lIGFuZCBvdGhlciBpZGVudGlmeWluZyBpbmZvcm1hdGlvbg0KICAgICAg ICAgICAgICAgICAgcHJvdmlkZWQgdG8gQ05SSSBieSBtZSBmb3IgdXNlIGluIGNvbm5lY3Rp b24gd2l0aCB0aGUgUHl0aG9uDQogICAgICAgICAgICAgICAgICBzb2Z0d2FyZSBhbmQgaXRz IHJlbGF0ZWQgZG9jdW1lbnRhdGlvbi4NCg0KCQ0KLS0tIFB5dGhvbi1jdnMvSW5jbHVkZS9v YmplY3QuaAlGcmkgTWFyIDI0IDIyOjMyOjE2IDIwMDANCisrKyBQeXRob24tZ2MvSW5jbHVk ZS9vYmplY3QuaAlTYXQgQXByICA4IDAxOjM4OjI1IDIwMDANCkBAIC0xNDUsNiArMTQ1LDEw IEBADQogdHlwZWRlZiBpbnQgKCpnZXRzZWdjb3VudHByb2MpIFB5X1BST1RPKChQeU9iamVj dCAqLCBpbnQgKikpOw0KIHR5cGVkZWYgaW50ICgqZ2V0Y2hhcmJ1ZmZlcnByb2MpIFB5X1BS T1RPKChQeU9iamVjdCAqLCBpbnQsIGNvbnN0IGNoYXIgKiopKTsNCiB0eXBlZGVmIGludCAo Km9iam9ianByb2MpIFB5X1BST1RPKChQeU9iamVjdCAqLCBQeU9iamVjdCAqKSk7DQorI2lm ZGVmIFdJVEhfQ1lDTEVfR0MNCit0eXBlZGVmIGludCAoKnZpc2l0cHJvYykgUHlfUFJPVE8o KFB5T2JqZWN0ICosIHZvaWQgKikpOw0KK3R5cGVkZWYgaW50ICgqcmVjdXJzZXByb2MpIFB5 X1BST1RPKChQeU9iamVjdCAqLCB2aXNpdHByb2MsIHZvaWQgKikpOw0KKyNlbmRpZg0KIA0K IHR5cGVkZWYgc3RydWN0IHsNCiAJYmluYXJ5ZnVuYyBuYl9hZGQ7DQpAQCAtMjQzLDkgKzI0 NywxOCBAQA0KIA0KIAljaGFyICp0cF9kb2M7IC8qIERvY3VtZW50YXRpb24gc3RyaW5nICov DQogDQotCS8qIE1vcmUgc3BhcmVzICovDQorI2lmZGVmIFdJVEhfQ1lDTEVfR0MNCisJLyog Y2FsbCBmdW5jdGlvbiBmb3IgYWxsIGFjY2Vzc2libGUgb2JqZWN0cyAqLw0KKwlyZWN1cnNl cHJvYyB0cF9yZWN1cnNlOw0KKwkNCisJLyogZGVsZXRlIHJlZmVyZW5jZXMgdG8gY29udGFp bmVkIG9iamVjdHMgKi8NCisJaW5xdWlyeSB0cF9jbGVhcjsNCisjZWxzZQ0KIAlsb25nIHRw X3h4eDU7DQogCWxvbmcgdHBfeHh4NjsNCisjZW5kaWYNCisNCisJLyogTW9yZSBzcGFyZXMg Ki8NCiAJbG9uZyB0cF94eHg3Ow0KIAlsb25nIHRwX3h4eDg7DQogDQpAQCAtMzE1LDYgKzMy OCw5IEBADQogDQogLyogUHlTZXF1ZW5jZU1ldGhvZHMgY29udGFpbnMgc3FfY29udGFpbnMg Ki8NCiAjZGVmaW5lIFB5X1RQRkxBR1NfSEFWRV9TRVFVRU5DRV9JTiAoMUw8PDEpDQorDQor LyogT2JqZWN0cyB3aXRoIGEgR0MgaW5mbyBwcmVmaXggKGFsbG9jYXRlZCAqYmVmb3JlKiB0 aGUgb2JqZWN0IGl0c2VsZiEpICovDQorI2RlZmluZSBQeV9UUEZMQUdTX0hBVkVfR0NJTkZP ICgxTDw8MikNCiANCiAjZGVmaW5lIFB5X1RQRkxBR1NfREVGQVVMVCAgKFB5X1RQRkxBR1Nf SEFWRV9HRVRDSEFSQlVGRkVSIHwgXA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg UHlfVFBGTEFHU19IQVZFX1NFUVVFTkNFX0lOKQ0KLS0tIFB5dGhvbi1jdnMvSW5jbHVkZS9v YmppbXBsLmgJVGh1IE1hciAgMiAxNzowMjoyMyAyMDAwDQorKysgUHl0aG9uLWdjL0luY2x1 ZGUvb2JqaW1wbC5oCVNhdCBBcHIgIDggMDM6MTg6MjIgMjAwMA0KQEAgLTM4LDggKzM4LDQy IEBADQogLyoNCiBBZGRpdGlvbmFsIG1hY3JvcyBmb3IgbW9kdWxlcyB0aGF0IGltcGxlbWVu dCBuZXcgb2JqZWN0IHR5cGVzLg0KIFlvdSBtdXN0IGZpcnN0IGluY2x1ZGUgIm9iamVjdC5o Ii4NCisqLw0KKw0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDIA0KKw0KKy8qIFN0cnVjdHVyZSAq cHJlZml4ZWQqIHRvIGNvbnRhaW5lciBvYmplY3RzIHBhcnRpY2lwYXRpbmcgaW4gR0MgKi8g DQordHlwZWRlZiBzdHJ1Y3QgX2djaW5mbyB7DQorCXN0cnVjdCBfZ2NpbmZvICpnY19uZXh0 Ow0KKwlzdHJ1Y3QgX2djaW5mbyAqZ2NfcHJldjsNCisJaW50IGdjX3JlZnM7DQorfSBQeUdD SW5mbzsNCisNCisvKiBUZXN0IGlmIGEgdHlwZSBoYXMgR0MgaW5mbyAqLw0KKyNkZWZpbmUg UFlfVFlQRUlTR0ModCkgUHlUeXBlX0hhc0ZlYXR1cmUoKHQpLCBQeV9UUEZMQUdTX0hBVkVf R0NJTkZPKQ0KKw0KKy8qIFRlc3QgaWYgYW4gb2JqZWN0IGhhcyBHQyBpbmZvICovDQorI2Rl ZmluZSBQWV9JU0dDKG8pIFBZX1RZUEVJU0dDKChvKS0+b2JfdHlwZSkNCisNCisvKiBHZXQg YW4gb2JqZWN0J3MgR0MgaW5mbyAtLSBOVUxMIGlmIHRoZSBvYmplY3QgaGFzIG5vbmUgKi8N CisjZGVmaW5lIFBZX0dDSU5GTyhvKSAoUFlfSVNHQyhvKSA/ICgoUHlHQ0luZm8gKikobykt MSkgOiBOVUxMKQ0KKw0KKy8qIFVuc2FmZSB2ZXJzaW9uIG9mIFBZX0dDSU5GTygpIC0tIG9u bHkgY2FsbCBpZiBQWV9JU0dDKHApIGlzIHRydWUgKi8NCisjZGVmaW5lIFBZX0dDSU5GT19V TlNBRkUobykgKChQeUdDSW5mbyAqKShvKS0xKQ0KKw0KKy8qIEdldCB0aGUgb2JqZWN0IGdp dmVuIHRoZSBQeUdDSW5mbyAqLw0KKyNkZWZpbmUgUFlfR0NPQkooZykgKChQeU9iamVjdCAq KSgoZykrMSkpDQogDQotUHlPYmplY3RfTkVXKHR5cGUsIHR5cGVvYmopIGFsbG9jYXRlcyBt ZW1vcnkgZm9yIGEgbmV3IG9iamVjdCBvZiB0aGUgZ2l2ZW4NCisvKiBBZGQgdGhlIG9iamVj dCBpbnRvIHRoZSBjb250YWluZXIgc2V0ICovDQorZXh0ZXJuIERMX0lNUE9SVCh2b2lkKSBQ eUdDX0luc2VydCBQeV9QUk9UTygoUHlPYmplY3QgKikpOw0KKw0KKy8qIFJlbW92ZSB0aGUg b2JqZWN0IGZyb20gdGhlIGNvbnRhaW5lciBzZXQgKi8NCitleHRlcm4gRExfSU1QT1JUKHZv aWQpIFB5R0NfUmVtb3ZlIFB5X1BST1RPKChQeU9iamVjdCAqKSk7DQorDQorI2VuZGlmDQor DQorLyoNCitQeU9iamVjdF9OZXcodHlwZSwgdHlwZW9iaikgYWxsb2NhdGVzIG1lbW9yeSBm b3IgYSBuZXcgb2JqZWN0IG9mIHRoZSBnaXZlbg0KIHR5cGU7IGhlcmUgJ3R5cGUnIG11c3Qg YmUgdGhlIEMgc3RydWN0dXJlIHR5cGUgdXNlZCB0byByZXByZXNlbnQgdGhlDQogb2JqZWN0 IGFuZCAndHlwZW9iaicgdGhlIGFkZHJlc3Mgb2YgdGhlIGNvcnJlc3BvbmRpbmcgdHlwZSBv YmplY3QuDQogUmVmZXJlbmNlIGNvdW50IGFuZCB0eXBlIHBvaW50ZXIgYXJlIGZpbGxlZCBp bjsgdGhlIHJlc3Qgb2YgdGhlIGJ5dGVzIG9mDQpAQCAtNDcsMzAgKzgxLDI5IEBADQogVGhl IHNpemUgb2YgdGhlIG9iamVjdCBpcyBhY3R1YWxseSBkZXRlcm1pbmVkIGJ5IHRoZSB0cF9i YXNpY3NpemUgZmllbGQNCiBvZiB0aGUgdHlwZSBvYmplY3QuDQogDQotUHlPYmplY3RfTkVX X1ZBUih0eXBlLCB0eXBlb2JqLCBuKSBpcyBzaW1pbGFyIGJ1dCBhbGxvY2F0ZXMgYSB2YXJp YWJsZS1zaXplDQorUHlPYmplY3RfTmV3VmFyKHR5cGUsIHR5cGVvYmosIG4pIGlzIHNpbWls YXIgYnV0IGFsbG9jYXRlcyBhIHZhcmlhYmxlLXNpemUNCiBvYmplY3Qgd2l0aCBuIGV4dHJh IGl0ZW1zLiAgVGhlIHNpemUgaXMgY29tcHV0ZWQgYXMgdHBfYmFzaWNzaXplIHBsdXMNCiBu ICogdHBfaXRlbXNpemUuICBUaGlzIGZpbGxzIGluIHRoZSBvYl9zaXplIGZpZWxkIGFzIHdl bGwuDQogKi8NCiANCi0jaWZuZGVmIE1TX0NPUkVETEwNCiBleHRlcm4gRExfSU1QT1JUKFB5 T2JqZWN0ICopIF9QeU9iamVjdF9OZXcgUHlfUFJPVE8oKFB5VHlwZU9iamVjdCAqKSk7DQog ZXh0ZXJuIERMX0lNUE9SVChQeVZhck9iamVjdCAqKSBfUHlPYmplY3RfTmV3VmFyIFB5X1BS T1RPKChQeVR5cGVPYmplY3QgKiwgaW50KSk7DQorZXh0ZXJuIERMX0lNUE9SVCh2b2lkKSBQ eU9iamVjdF9EZWwgUHlfUFJPVE8oKFB5T2JqZWN0ICopKTsNCiANCi0jZGVmaW5lIFB5T2Jq ZWN0X05FVyh0eXBlLCB0eXBlb2JqKSAoKHR5cGUgKikgX1B5T2JqZWN0X05ldyh0eXBlb2Jq KSkNCi0jZGVmaW5lIFB5T2JqZWN0X05FV19WQVIodHlwZSwgdHlwZW9iaiwgbikgKCh0eXBl ICopIF9QeU9iamVjdF9OZXdWYXIodHlwZW9iaiwgbikpDQotDQotI2Vsc2UNCi0vKiBGb3Ig YW4gTVMtV2luZG93cyBETEwsIHdlIGNoYW5nZSB0aGUgd2F5IGFuIG9iamVjdCBpcyBjcmVh dGVkLCBzbyB0aGF0IHRoZQ0KLSAgIGV4dGVuc2lvbiBtb2R1bGUncyBtYWxsb2MgaXMgdXNl ZCwgcmF0aGVyIHRoYW4gdGhlIGNvcmUgRExMIG1hbGxvYywgYXMgdGhlcmUgaXMNCi0gICBu byBndWFyYW50ZWUgdGhleSB3aWxsIHVzZSB0aGUgc2FtZSBoZWFwDQotKi8NCi1leHRlcm4g RExfSU1QT1JUKFB5T2JqZWN0ICopIF9QeU9iamVjdF9OZXcgUHlfUFJPVE8oKFB5VHlwZU9i amVjdCAqLCBQeU9iamVjdCAqKSk7DQotZXh0ZXJuIERMX0lNUE9SVChQeVZhck9iamVjdCAq KSBfUHlPYmplY3RfTmV3VmFyIFB5X1BST1RPKChQeVR5cGVPYmplY3QgKiwgaW50LCBQeVZh ck9iamVjdCAqKSk7DQotDQotI2RlZmluZSBQeU9iamVjdF9ORVcodHlwZSwgdHlwZW9iaikg KCh0eXBlICopIF9QeU9iamVjdF9OZXcodHlwZW9iaiwoUHlPYmplY3QgKiltYWxsb2MoKHR5 cGVvYmopLT50cF9iYXNpY3NpemUpKSkNCi0jZGVmaW5lIFB5T2JqZWN0X05FV19WQVIodHlw ZSwgdHlwZW9iaiwgbikgKCh0eXBlICopIF9QeU9iamVjdF9OZXdWYXIodHlwZW9iaiwgbiwg KFB5VmFyT2JqZWN0ICopbWFsbG9jKCh0eXBlb2JqKS0+dHBfYmFzaWNzaXplICsgbiAqICh0 eXBlb2JqKS0+dHBfaXRlbXNpemUpKSkNCi0NCi0jZW5kaWYgLyogTVNfQ09SRURMTCAqLw0K Ky8qIEZ1bmN0aW9ucyAqLw0KKyNkZWZpbmUgUHlPYmplY3RfTmV3KHR5cGUsIHR5cGVvYmop IFwNCisJCSgodHlwZSAqKSBfUHlPYmplY3RfTmV3KHR5cGVvYmopKQ0KKyNkZWZpbmUgUHlP YmplY3RfTmV3VmFyKHR5cGUsIHR5cGVvYmosIG4pIFwNCisgICAgICAgICAgICAgICAgKCh0 eXBlICopIF9QeU9iamVjdF9OZXdWYXIoKHR5cGVvYmopLCAobikpKQ0KKw0KKw0KK2V4dGVy biBETF9JTVBPUlQoUHlPYmplY3QgKikgX1B5T2JqZWN0X0Zyb21UeXBlIFB5X1BST1RPKChQ eVR5cGVPYmplY3QgKiwgUHlPYmplY3QgKikpOw0KK2V4dGVybiBETF9JTVBPUlQoUHlWYXJP YmplY3QgKikgX1B5T2JqZWN0X1ZhckZyb21UeXBlIFB5X1BST1RPKChQeVR5cGVPYmplY3Qg KiwgaW50LCBQeVZhck9iamVjdCAqKSk7DQorDQorLyogVGhlc2UgbWFjcm9zIG1heSBub3Qg dXNlIHRoZSBzYW1lIG1hbGxvYyBhcyBQeXRob24uIFRoZXkgY2Fubm90IGJlIHVzZWQNCisg KiBvYmplY3RzIHRoYXQgYXJlIGludm9sdmVkIGluIGdhcmJhZ2UgY29sbGVjdGlvbiAqLw0K KyNkZWZpbmUgUHlPYmplY3RfTkVXKHR5cGUsIHR5cGVvYmopICgodHlwZSAqKSBfUHlPYmpl Y3RfRnJvbVR5cGUodHlwZW9iaiwoUHlPYmplY3QgKiltYWxsb2MoKHR5cGVvYmopLT50cF9i YXNpY3NpemUpKSkNCisjZGVmaW5lIFB5T2JqZWN0X05FV19WQVIodHlwZSwgdHlwZW9iaiwg bikgKCh0eXBlICopIF9QeU9iamVjdF9WYXJGcm9tVHlwZSh0eXBlb2JqLCBuLCAoUHlWYXJP YmplY3QgKiltYWxsb2MoKHR5cGVvYmopLT50cF9iYXNpY3NpemUgKyBuICogKHR5cGVvYmop LT50cF9pdGVtc2l6ZSkpKQ0KIA0KICNpZmRlZiBfX2NwbHVzcGx1cw0KIH0NCi0tLSBQeXRo b24tY3ZzL01vZHVsZXMvY1BpY2tsZS5jCUZyaSBNYXIgMjQgMjI6MzI6MjUgMjAwMA0KKysr IFB5dGhvbi1nYy9Nb2R1bGVzL2NQaWNrbGUuYwlTYXQgQXByICA4IDAyOjEzOjExIDIwMDAN CkBAIC0yODg2LDcgKzI4ODYsNyBAQA0KICAgICAgICAgICAgICAgUHlJbnN0YW5jZU9iamVj dCAqaW5zdDsNCiANCiAgICAgICAgICAgICAgIFB5RXJyX0NsZWFyKCk7DQotICAgICAgICAg ICAgICBVTkxFU1MgKGluc3Q9UHlPYmplY3RfTkVXKFB5SW5zdGFuY2VPYmplY3QsICZQeUlu c3RhbmNlX1R5cGUpKQ0KKyAgICAgICAgICAgICAgVU5MRVNTIChpbnN0PVB5T2JqZWN0X05l dyhQeUluc3RhbmNlT2JqZWN0LCAmUHlJbnN0YW5jZV9UeXBlKSkNCiAgICAgICAgICAgICAg ICAgZ290byBlcnI7DQogICAgICAgICAgICAgICBpbnN0LT5pbl9jbGFzcz0oUHlDbGFzc09i amVjdCopY2xzOw0KICAgICAgICAgICAgICAgUHlfSU5DUkVGKGNscyk7DQpAQCAtMjg5NCw3 ICsyODk0LDkgQEANCiAgICAgICAgICAgICAgICAgUHlfREVDUkVGKGluc3QpOw0KICAgICAg ICAgICAgICAgICBnb3RvIGVycjsNCiAgICAgICAgICAgICAgIH0NCi0NCisjaWZkZWYgV0lU SF9DWUNMRV9HQw0KKyAgICAgICAgICAgICAgUHlHQ19JbnNlcnQoKFB5T2JqZWN0ICopaW5z dCk7DQorI2VuZGlmDQogICAgICAgICAgICAgICByZXR1cm4gKFB5T2JqZWN0ICopaW5zdDsN CiAgICAgICAgICAgICB9DQogICAgICAgICAgIFB5X0RFQ1JFRihfX2dldGluaXRhcmdzX18p Ow0KLS0tIFB5dGhvbi1jdnMvTW9kdWxlcy9uZXdtb2R1bGUuYwlUdWUgRmViIDI5IDE0OjU1 OjA5IDIwMDANCisrKyBQeXRob24tZ2MvTW9kdWxlcy9uZXdtb2R1bGUuYwlTYXQgQXByICA4 IDAyOjEzOjI2IDIwMDANCkBAIC00OSwxMyArNDksMTYgQEANCiAJCQkgICAgICAmUHlDbGFz c19UeXBlLCAma2xhc3MsDQogCQkJICAgICAgJlB5RGljdF9UeXBlLCAmZGljdCkpDQogCQly ZXR1cm4gTlVMTDsNCi0JaW5zdCA9IFB5T2JqZWN0X05FVyhQeUluc3RhbmNlT2JqZWN0LCAm UHlJbnN0YW5jZV9UeXBlKTsNCisJaW5zdCA9IFB5T2JqZWN0X05ldyhQeUluc3RhbmNlT2Jq ZWN0LCAmUHlJbnN0YW5jZV9UeXBlKTsNCiAJaWYgKGluc3QgPT0gTlVMTCkNCiAJCXJldHVy biBOVUxMOw0KIAlQeV9JTkNSRUYoa2xhc3MpOw0KIAlQeV9JTkNSRUYoZGljdCk7DQogCWlu c3QtPmluX2NsYXNzID0gKFB5Q2xhc3NPYmplY3QgKilrbGFzczsNCiAJaW5zdC0+aW5fZGlj dCA9IGRpY3Q7DQorI2lmZGVmIFdJVEhfQ1lDTEVfR0MNCisJUHlHQ19JbnNlcnQoKFB5T2Jq ZWN0ICopaW5zdCk7DQorI2VuZGlmDQogCXJldHVybiAoUHlPYmplY3QgKilpbnN0Ow0KIH0N CiANCi0tLSBQeXRob24tY3ZzL01vZHVsZXMvZ2Ntb2R1bGUuYw0KKysrIFB5dGhvbi1nYy9N b2R1bGVzL2djbW9kdWxlLmMJU2F0IEFwciAgOCAwMzoyNTo1NyAyMDAwDQpAQCAtMCwwICsx LDY3NyBAQA0KKy8qDQorIA0KKyAgUmVmZXJlbmNlIEN5Y2xlIEdhcmJhZ2UgQ29sbGVjdGlv bg0KKyAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQ0KKw0KKyAgTmVpbCBT Y2hlbWVuYXVlciA8bmFzY2hlbWVAZW5tZS51Y2FsZ2FyeS5jYT4NCisNCisgIEJhc2VkIG9u IGEgcG9zdCBvbiB0aGUgcHl0aG9uLWRldiBsaXN0LiAgSWRlYXMgZnJvbSBHdWlkbyB2YW4g Um9zc3VtLA0KKyAgRXJpYyBUaWVkZW1hbm4sIGFuZCB2YXJpb3VzIG90aGVycy4NCisNCisg IGh0dHA6Ly93d3cuZW5tZS5jYWxnYXJ5LmNhL35uYXNjaGVtZS9weXRob24vZ2MuaHRtbA0K KyAgaHR0cDovL3d3dy5weXRob24ub3JnL3BpcGVybWFpbC9weXRob24tZGV2LzIwMDAtTWFy Y2gvMDAzODY5Lmh0bWwNCisgIGh0dHA6Ly93d3cucHl0aG9uLm9yZy9waXBlcm1haWwvcHl0 aG9uLWRldi8yMDAwLU1hcmNoLzAwNDAxMC5odG1sDQorICBodHRwOi8vd3d3LnB5dGhvbi5v cmcvcGlwZXJtYWlsL3B5dGhvbi1kZXYvMjAwMC1NYXJjaC8wMDQwMjIuaHRtbA0KKw0KKyAg Rm9yIGEgaGlnaGxldmVsIHZpZXcgb2YgdGhlIGNvbGxlY3Rpb24gcHJvY2VzcywgcmVhZCB0 aGUgY29sbGVjdA0KKyAgZnVuY3Rpb24uDQorDQorICBUT0RPOg0KKwl1c2UgYSBkaWZmZXJl bnQgaW50ZXJmYWNlIGZvciBzZXRfZGVidWcoKSAoa2V5d29yZHMpPw0KKwlpbmxpbmUgUHlH Q19JbnNlcnQgYW5kIFB5R0NfUmVtb3ZlIGNhbGxzPw0KKwl0dW5lIHBhcmFtZXRlcnMNCisN CisqLw0KKw0KKyNpbmNsdWRlICJQeXRob24uaCINCisNCisjaWZuZGVmIFdJVEhfQ1lDTEVf R0MNCisjZXJyb3IgIllvdSBtdXN0IGRlZmluZSBXSVRIX0NZQ0xFX0dDIHRvIGluY2x1ZGUg dGhpcyBtb2R1bGUiDQorI2VuZGlmDQorDQorLyogbWFnaWMgZ2NfcmVmcyB2YWx1ZSAqLw0K KyNkZWZpbmUgR0NfTU9WRUQgLTENCisNCisNCisvKioqIEdsb2JhbCBHQyBzdGF0ZSAqKiov DQorDQorLyogbGlua2VkIGxpc3RzIG9mIGNvbnRhaW5lciBvYmplY3RzICovDQorc3RhdGlj IFB5R0NJbmZvIGdlbmVyYXRpb24wID0geyZnZW5lcmF0aW9uMCwgJmdlbmVyYXRpb24wLCAw fTsNCitzdGF0aWMgUHlHQ0luZm8gZ2VuZXJhdGlvbjEgPSB7JmdlbmVyYXRpb24xLCAmZ2Vu ZXJhdGlvbjEsIDB9Ow0KK3N0YXRpYyBQeUdDSW5mbyBnZW5lcmF0aW9uMiA9IHsmZ2VuZXJh dGlvbjIsICZnZW5lcmF0aW9uMiwgMH07DQorc3RhdGljIGludCBnZW5lcmF0aW9uID0gMDsg LyogY3VycmVudCBnZW5lcmF0aW9uIGJlaW5nIGNvbGxlY3RlZCAqLw0KKw0KKy8qIGNvbGxl Y3Rpb24gZnJlcXVlbmNpZXMsIFhYWCB0dW5lIHRoZXNlICovDQorc3RhdGljIGludCB0aHJl c2hvbGQwID0gMTAwOyAvKiBuZXQgbmV3IGNvbnRhaW5lcnMgYmVmb3JlIGNvbGxlY3Rpb24g Ki8NCitzdGF0aWMgaW50IHRocmVzaG9sZDEgPSAxMDsgIC8qIGdlbmVyYXRpb24wIGNvbGxl Y3Rpb25zIGJlZm9yZSBjb2xsZWN0aW5nIDEgKi8NCitzdGF0aWMgaW50IHRocmVzaG9sZDIg PSAxMDsgIC8qIGdlbmVyYXRpb24xIGNvbGxlY3Rpb25zIGJlZm9yZSBjb2xsZWN0aW5nIDIg Ki8NCisNCisvKiBuZXQgbmV3IG9iamVjdHMgYWxsb2NhdGVkIHNpbmNlIGxhc3QgY29sbGVj dGlvbiAqLw0KK3N0YXRpYyBpbnQgYWxsb2NhdGVkID0gMDsNCisNCisvKiBzZXQgZm9yIGRl YnVnZ2luZyBpbmZvcm1hdGlvbiAqLw0KKyNkZWZpbmUgREVCVUdfU1RBVFMJCSgxPDwwKSAv KiBwcmludCBjb2xsZWN0aW9uIHN0YXRpc3RpY3MgKi8NCisjZGVmaW5lIERFQlVHX0NPTExF Q1RBQkxFCSgxPDwxKSAvKiBwcmludCBjb2xsZWN0YWJsZSBvYmplY3RzICovDQorI2RlZmlu ZSBERUJVR19VTkNPTExFQ1RBQkxFCSgxPDwyKSAvKiBwcmludCB1bmNvbGxlY3RhYmxlIG9i amVjdHMgKi8NCisjZGVmaW5lIERFQlVHX0lOU1RBTkNFUwkJKDE8PDMpIC8qIHByaW50IGlu c3RhbmNlcyAqLw0KKyNkZWZpbmUgREVCVUdfT0JKRUNUUwkJKDE8PDQpIC8qIHByaW50IG90 aGVyIG9iamVjdHMgKi8NCisjZGVmaW5lIERFQlVHX0xFQUsJCURFQlVHX0NPTExFQ1RBQkxF IHwgXA0KKwkJCQlERUJVR19VTkNPTExFQ1RBQkxFIHwgXA0KKwkJCQlERUJVR19JTlNUQU5D RVMgfCBcDQorCQkJCURFQlVHX09CSkVDVFMNCitzdGF0aWMgaW50IGRlYnVnID0gREVCVUdf TEVBSzsNCisNCisvKiBsaXN0IG9mIHVuY29sbGVjdGFibGUgb2JqZWN0cyAqLw0KK3N0YXRp YyBQeU9iamVjdCAqZ2FyYmFnZSA9IE5VTEw7DQorDQorDQorLyoqKiBsaXN0IGZ1bmN0aW9u cyAoc2hvdWxkIHByb2JhYmx5IGJlIG1hY3Jvcywgc3R1cGlkIGNvbXBpbGVycykgKioqLw0K Kw0KK3N0YXRpYyB2b2lkDQorTElTVF9JTklUKFB5R0NJbmZvICpsaXN0KQ0KK3sNCisJbGlz dC0+Z2NfcHJldiA9IGxpc3Q7DQorCWxpc3QtPmdjX25leHQgPSBsaXN0Ow0KK30NCisNCitz dGF0aWMgdm9pZA0KK0xJU1RfQVBQRU5EKFB5R0NJbmZvICpub2RlLCBQeUdDSW5mbyAqbGlz dCkNCit7DQorCW5vZGUtPmdjX25leHQgPSBsaXN0Ow0KKwlub2RlLT5nY19wcmV2ID0gbGlz dC0+Z2NfcHJldjsNCisJbm9kZS0+Z2NfcHJldi0+Z2NfbmV4dCA9IG5vZGU7DQorCWxpc3Qt PmdjX3ByZXYgPSBub2RlOw0KK30NCisNCitzdGF0aWMgdm9pZA0KK0xJU1RfUkVNT1ZFKFB5 R0NJbmZvICpub2RlKQ0KK3sNCisJbm9kZS0+Z2NfcHJldi0+Z2NfbmV4dCA9IG5vZGUtPmdj X25leHQ7DQorCW5vZGUtPmdjX25leHQtPmdjX3ByZXYgPSBub2RlLT5nY19wcmV2Ow0KK30N CisNCitzdGF0aWMgdm9pZCANCitMSVNUX01PVkUoUHlHQ0luZm8gKmZyb20sIFB5R0NJbmZv ICp0bykNCit7DQorCWlmIChmcm9tLT5nY19uZXh0ID09IGZyb20pIHsNCisJCS8qIGVtcHR5 IGZyb20gbGlzdCAqLw0KKwkJTElTVF9JTklUKHRvKTsNCisJfSBlbHNlIHsNCisJCXRvLT5n Y19uZXh0ID0gZnJvbS0+Z2NfbmV4dDsNCisJCXRvLT5nY19uZXh0LT5nY19wcmV2ID0gdG87 DQorCQl0by0+Z2NfcHJldiA9IGZyb20tPmdjX3ByZXY7DQorCQl0by0+Z2NfcHJldi0+Z2Nf bmV4dCA9IHRvOw0KKwl9DQorCUxJU1RfSU5JVChmcm9tKTsNCit9DQorDQorLyogYXBwZW5k IGEgbGlzdCBvbnRvIGFub3RoZXIgbGlzdCAqLw0KK3N0YXRpYyB2b2lkDQorTElTVF9MQVBQ RU5EKFB5R0NJbmZvICpmcm9tLCBQeUdDSW5mbyAqdG8pDQorew0KKwlQeUdDSW5mbyAqdGFp bDsNCisJaWYgKGZyb20tPmdjX25leHQgIT0gZnJvbSkgew0KKwkJdGFpbCA9IHRvLT5nY19w cmV2Ow0KKwkJdGFpbC0+Z2NfbmV4dCA9IGZyb20tPmdjX25leHQ7DQorCQl0YWlsLT5nY19u ZXh0LT5nY19wcmV2ID0gdGFpbDsNCisJCXRvLT5nY19wcmV2ID0gZnJvbS0+Z2NfcHJldjsN CisJCXRvLT5nY19wcmV2LT5nY19uZXh0ID0gdG87DQorCX0NCisJTElTVF9JTklUKGZyb20p Ow0KK30NCisNCitzdGF0aWMgbG9uZw0KK0xJU1RfU0laRShQeUdDSW5mbyAqbGlzdCkNCit7 DQorCVB5R0NJbmZvICpnYzsNCisJbG9uZyBuID0gMDsNCisJZm9yIChnYyA9IGxpc3QtPmdj X25leHQ7IGdjICE9IGxpc3Q7IGdjID0gZ2MtPmdjX25leHQpIHsNCisJCW4rKzsNCisJfQ0K KwlyZXR1cm4gbjsNCit9DQorDQorDQorI2lmZGVmIERFQlVHDQorc3RhdGljIHZvaWQNCits aXN0X3ByaW50KFB5R0NJbmZvICpsaXN0KSB7DQorCVB5R0NJbmZvICpvcCA9IGxpc3Q7DQor CWRvIHsNCisJCXByaW50ZigiJXggJXggJXggJWRcbiIsIChsb25nKW9wLCAobG9uZylvcC0+ Z2NfcHJldiwgDQorCQkJCShsb25nKW9wLT5nY19uZXh0LCAobG9uZylvcC0+Z2NfcmVmcyk7 DQorDQorCQlvcCA9IG9wLT5nY19uZXh0Ow0KKwl9IHdoaWxlIChvcCAhPSBsaXN0KTsNCit9 DQorI2VuZGlmDQorDQorLyoqKiBlbmQgb2YgbGlzdCBzdHVmZiAqKiovDQorDQorDQorLyog U2V0IGFsbCBnY19yZWZzID0gb2JfcmVmY250ICovDQorc3RhdGljIHZvaWQNCit1cGRhdGVf cmVmcyhQeUdDSW5mbyAqY29udGFpbmVycykNCit7DQorCVB5R0NJbmZvICpnYyA9IGNvbnRh aW5lcnMtPmdjX25leHQ7DQorCWZvciAoOyBnYyAhPSBjb250YWluZXJzOyBnYz1nYy0+Z2Nf bmV4dCkgew0KKwkJZ2MtPmdjX3JlZnMgPSBQWV9HQ09CSihnYyktPm9iX3JlZmNudDsNCisJ fQ0KK30NCisNCitzdGF0aWMgaW50DQordmlzaXRfZGVjcmVmKFB5T2JqZWN0ICpvcCwgdm9p ZCAqZGF0YSkNCit7DQorCWlmIChvcCAmJiBQWV9JU0dDKG9wKSkgew0KKwkJUFlfR0NJTkZP X1VOU0FGRShvcCktPmdjX3JlZnMtLTsNCisJfQ0KKwlyZXR1cm4gMTsNCit9DQorDQorLyog U3VidHJhY3QgaW50ZXJuYWwgcmVmZXJlbmNlcyBmcm9tIGdjX3JlZnMgKi8NCitzdGF0aWMg dm9pZA0KK3N1YnRyYWN0X3JlZnMoUHlHQ0luZm8gKmNvbnRhaW5lcnMpDQorew0KKwlyZWN1 cnNlcHJvYyByZWN1cnNlOw0KKwlQeUdDSW5mbyAqZ2MgPSBjb250YWluZXJzLT5nY19uZXh0 Ow0KKwlmb3IgKDsgZ2MgIT0gY29udGFpbmVyczsgZ2M9Z2MtPmdjX25leHQpIHsNCisJCXJl Y3Vyc2UgPSBQWV9HQ09CSihnYyktPm9iX3R5cGUtPnRwX3JlY3Vyc2U7DQorCQkodm9pZCkg cmVjdXJzZShQWV9HQ09CSihnYyksDQorCQkJICAgICAgICh2aXNpdHByb2MpdmlzaXRfZGVj cmVmLA0KKwkJCSAgICAgICBOVUxMKTsNCisJfQ0KK30NCisNCisvKiBBcHBlbmQgb2JqZWN0 cyB3aXRoIGdjX3JlZnMgPiAwIHRvIHJvb3RzIGxpc3QgKi8NCitzdGF0aWMgdm9pZA0KK21v dmVfcm9vdHMoUHlHQ0luZm8gKmNvbnRhaW5lcnMsIFB5R0NJbmZvICpyb290cykNCit7DQor CVB5R0NJbmZvICpuZXh0Ow0KKwlQeUdDSW5mbyAqZ2MgPSBjb250YWluZXJzLT5nY19uZXh0 Ow0KKwl3aGlsZSAoZ2MgIT0gY29udGFpbmVycykgew0KKwkJbmV4dCA9IGdjLT5nY19uZXh0 Ow0KKwkJaWYgKGdjLT5nY19yZWZzID4gMCkgew0KKwkJCUxJU1RfUkVNT1ZFKGdjKTsNCisJ CQlMSVNUX0FQUEVORChnYywgcm9vdHMpOw0KKwkJCWdjLT5nY19yZWZzID0gR0NfTU9WRUQ7 DQorCQl9DQorCQlnYyA9IG5leHQ7DQorCX0NCit9DQorDQorc3RhdGljIGludA0KK3Zpc2l0 X3JlYWNoYWJsZShQeU9iamVjdCAqb3AsIFB5R0NJbmZvICpyb290cykNCit7DQorCVB5R0NJ bmZvICpnYyA9IFBZX0dDSU5GTyhvcCk7DQorCWlmIChnYyAmJiBnYy0+Z2NfcmVmcyAhPSBH Q19NT1ZFRCkgew0KKwkJTElTVF9SRU1PVkUoZ2MpOw0KKwkJTElTVF9BUFBFTkQoZ2MsIHJv b3RzKTsNCisJCWdjLT5nY19yZWZzID0gR0NfTU9WRUQ7DQorCX0NCisJcmV0dXJuIDE7DQor fQ0KKw0KKy8qIE1vdmUgb2JqZWN0cyByZWZlcmVuY2VkIGZyb20gcmVhY2hhYmxlIHRvIHJl YWNoYWJsZSBzZXQuICovDQorc3RhdGljIHZvaWQNCittb3ZlX3Jvb3RfcmVhY2hhYmxlKFB5 R0NJbmZvICpyZWFjaGFibGUpDQorew0KKwlyZWN1cnNlcHJvYyByZWN1cnNlOw0KKwlQeUdD SW5mbyAqZ2MgPSByZWFjaGFibGUtPmdjX25leHQ7DQorCWZvciAoOyBnYyAhPSByZWFjaGFi bGU7IGdjPWdjLT5nY19uZXh0KSB7DQorCQkvKiBjYXJlZnVsLCByZWFjaGFibGUgbGlzdCBp cyBncm93aW5nIGhlcmUgKi8NCisJCVB5T2JqZWN0ICpvcCA9IFBZX0dDT0JKKGdjKTsNCisJ CXJlY3Vyc2UgPSBvcC0+b2JfdHlwZS0+dHBfcmVjdXJzZTsNCisJCSh2b2lkKSByZWN1cnNl KG9wLA0KKwkJCSAgICAgICAodmlzaXRwcm9jKXZpc2l0X3JlYWNoYWJsZSwNCisJCQkgICAg ICAgKHZvaWQgKilyZWFjaGFibGUpOw0KKwl9DQorfQ0KKw0KKy8qIG1vdmUgYWxsIG9iamVj dHMgd2l0aCBmaW5hbGl6ZXJzIChpbnN0YW5jZXMgd2l0aCBfX2RlbF9fKSAqLw0KK3N0YXRp YyB2b2lkDQorbW92ZV9maW5hbGl6ZXJzKFB5R0NJbmZvICp1bnJlYWNoYWJsZSwgUHlHQ0lu Zm8gKmZpbmFsaXplcnMpDQorew0KKwlQeUdDSW5mbyAqbmV4dDsNCisJUHlHQ0luZm8gKmdj ID0gdW5yZWFjaGFibGUtPmdjX25leHQ7DQorCXN0YXRpYyBQeU9iamVjdCAqZGVsc3RyOw0K KwlpZiAoZGVsc3RyID09IE5VTEwpIHsNCisJCWRlbHN0ciA9IFB5U3RyaW5nX0ludGVybkZy b21TdHJpbmcoIl9fZGVsX18iKTsNCisJfQ0KKwlmb3IgKDsgZ2MgIT0gdW5yZWFjaGFibGU7 IGdjPW5leHQpIHsNCisJCVB5T2JqZWN0ICpvcCA9IFBZX0dDT0JKKGdjKTsNCisJCW5leHQg PSBnYy0+Z2NfbmV4dDsNCisJCWlmIChQeUluc3RhbmNlX0NoZWNrKG9wKSAmJiBQeU9iamVj dF9IYXNBdHRyKG9wLCBkZWxzdHIpKSB7DQorCQkJTElTVF9SRU1PVkUoZ2MpOw0KKwkJCUxJ U1RfQVBQRU5EKGdjLCBmaW5hbGl6ZXJzKTsNCisJCX0NCisJfQ0KK30NCisNCisNCisvKiBj YWxsZWQgYnkgdHBfcmVjdXJzZSAqLw0KK3N0YXRpYyBpbnQNCit2aXNpdF9maW5hbGl6ZXJf cmVhY2hhYmxlKFB5T2JqZWN0ICpvcCwgUHlHQ0luZm8gKmZpbmFsaXplcnMpDQorew0KKwlQ eUdDSW5mbyAqZ2MgPSBQWV9HQ0lORk8ob3ApOw0KKwlpZiAoZ2MgJiYgZ2MtPmdjX3JlZnMg IT0gR0NfTU9WRUQpIHsNCisJCUxJU1RfUkVNT1ZFKGdjKTsNCisJCUxJU1RfQVBQRU5EKGdj LCBmaW5hbGl6ZXJzKTsNCisJCWdjLT5nY19yZWZzID0gR0NfTU9WRUQ7DQorCX0NCisJcmV0 dXJuIDE7DQorfQ0KKw0KKy8qIE1vdmUgb2JqZWN0cyByZWZlcmVuY2VkIGZyb20gcm9vdHMg dG8gcm9vdHMgKi8NCitzdGF0aWMgdm9pZA0KK21vdmVfZmluYWxpemVyX3JlYWNoYWJsZShQ eUdDSW5mbyAqZmluYWxpemVycykNCit7DQorCXJlY3Vyc2Vwcm9jIHJlY3Vyc2U7DQorCVB5 R0NJbmZvICpnYyA9IGZpbmFsaXplcnMtPmdjX25leHQ7DQorCWZvciAoOyBnYyAhPSBmaW5h bGl6ZXJzOyBnYz1nYy0+Z2NfbmV4dCkgew0KKwkJLyogY2FyZWZ1bCwgZmluYWxpemVycyBs aXN0IGlzIGdyb3dpbmcgaGVyZSAqLw0KKwkJcmVjdXJzZSA9IFBZX0dDT0JKKGdjKS0+b2Jf dHlwZS0+dHBfcmVjdXJzZTsNCisJCSh2b2lkKSByZWN1cnNlKFBZX0dDT0JKKGdjKSwgDQor CQkJICAgICAgICh2aXNpdHByb2MpdmlzaXRfZmluYWxpemVyX3JlYWNoYWJsZSwNCisJCQkg ICAgICAgKHZvaWQgKilmaW5hbGl6ZXJzKTsNCisJfQ0KK30NCisNCitzdGF0aWMgdm9pZA0K K2RlYnVnX2luc3RhbmNlKFB5T2JqZWN0ICpvdXRwdXQsIGNoYXIgKm1zZywgUHlJbnN0YW5j ZU9iamVjdCAqaW5zdCkNCit7DQorCWNoYXIgYnVmWzIwMF07DQorCWNoYXIgKmNuYW1lOw0K KwkvKiBiZSBjYXJlZnVsIG5vdCB0byBjcmVhdGUgbmV3IGRpY3Rpb25hcmllcyAqLw0KKwlQ eU9iamVjdCAqY2xhc3NuYW1lID0gaW5zdC0+aW5fY2xhc3MtPmNsX25hbWU7DQorCWlmIChj bGFzc25hbWUgIT0gTlVMTCAmJiBQeVN0cmluZ19DaGVjayhjbGFzc25hbWUpKQ0KKwkJY25h bWUgPSBQeVN0cmluZ19Bc1N0cmluZyhjbGFzc25hbWUpOw0KKwllbHNlDQorCQljbmFtZSA9 ICI/IjsNCisJc3ByaW50ZihidWYsICJnYzogJXM8JS4xMDBzIGluc3RhbmNlIGF0ICVseD5c biIsIA0KKwkJCW1zZywgY25hbWUsIChsb25nKWluc3QpOw0KKwlQeUZpbGVfV3JpdGVTdHJp bmcoYnVmLCBvdXRwdXQpOw0KK30NCisNCitzdGF0aWMgdm9pZA0KK2RlYnVnX2N5Y2xlKFB5 T2JqZWN0ICpvdXRwdXQsIGNoYXIgKm1zZywgUHlPYmplY3QgKm9wKQ0KK3sNCisJaWYgKChk ZWJ1ZyAmIERFQlVHX0lOU1RBTkNFUykgJiYgUHlJbnN0YW5jZV9DaGVjayhvcCkpIHsNCisJ CWRlYnVnX2luc3RhbmNlKG91dHB1dCwgbXNnLCAoUHlJbnN0YW5jZU9iamVjdCAqKW9wKTsN CisJfSBlbHNlIGlmIChkZWJ1ZyAmIERFQlVHX09CSkVDVFMpIHsNCisJCWNoYXIgYnVmWzIw MF07DQorCQlzcHJpbnRmKGJ1ZiwgImdjOiAlczxPYmplY3QgMHgleD5cbiIsIG1zZywgKGxv bmcpb3ApOw0KKwkJUHlGaWxlX1dyaXRlU3RyaW5nKGJ1Ziwgb3V0cHV0KTsNCisJfQ0KK30N CisNCisvKiBIYW5kbGUgdW5jb2xsZWN0YWJsZSBnYXJiYWdlIChjeWNsZXMgd2l0aCBmaW5h bGl6ZXJzKS4gKi8NCitzdGF0aWMgdm9pZA0KK2hhbmRsZV9maW5hbGl6ZXJzKFB5R0NJbmZv ICpmaW5hbGl6ZXJzLCBQeUdDSW5mbyAqb2xkKQ0KK3sNCisJUHlHQ0luZm8gKmdjOw0KKwlp ZiAoZ2FyYmFnZSA9PSBOVUxMKSB7DQorCQlnYXJiYWdlID0gUHlMaXN0X05ldygwKTsNCisJ fQ0KKwlmb3IgKGdjID0gZmluYWxpemVycy0+Z2NfbmV4dDsgZ2MgIT0gZmluYWxpemVyczsN CisJCQlnYyA9IGZpbmFsaXplcnMtPmdjX25leHQpIHsNCisJCVB5T2JqZWN0ICpvcCA9IFBZ X0dDT0JKKGdjKTsNCisJCS8qIEFkZCBhbGwgaW5zdGFuY2VzIHRvIGEgUHl0aG9uIGFjY2Vz c2libGUgbGlzdCBvZiBnYXJiYWdlICovDQorCQlpZiAoUHlJbnN0YW5jZV9DaGVjayhvcCkp IHsNCisJCQlQeUxpc3RfQXBwZW5kKGdhcmJhZ2UsIG9wKTsNCisJCX0NCisJCS8qIFdlIGFz c3VtZSB0aGF0IGFsbCBvYmplY3RzIGluIGZpbmFsaXplcnMgYXJlIHJlYWNoYWJsZSBmcm9t DQorCQkgKiBpbnN0YW5jZXMuICBPbmNlIHdlIGFkZCB0aGUgaW5zdGFuY2VzIHRvIHRoZSBn YXJiYWdlIGxpc3QNCisJCSAqIGV2ZXJ5dGhpbmcgaXMgcmVhY2hhYmxlIGZyb20gUHl0aG9u IGFnYWluLiAqLw0KKwkJTElTVF9SRU1PVkUoZ2MpOw0KKwkJTElTVF9BUFBFTkQoZ2MsIG9s ZCk7DQorCX0NCit9DQorDQorLyogQnJlYWsgcmVmZXJlbmNlIGN5Y2xlcyBieSBjbGVhcmlu ZyB0aGUgY29udGFpbmVycyBpbnZvbHZlZC4gIFRoaXMgaXMNCisgKiB0cmlja3kgYnVzaW5l c3MgYXMgdGhlIGxpc3RzIGNhbiBiZSBjaGFuZ2luZyBhbmQgd2UgZG9uJ3Qga25vdyB3aGlj aA0KKyAqIG9iamVjdHMgbWF5IGJlIGZyZWVkLiAgSXQgaXMgcG9zc2libGUgSSBzY3Jld2Vk IHNvbWV0aGluZyB1cCBoZXJlLiAqLw0KK3N0YXRpYyB2b2lkDQorZGVsZXRlX2dhcmJhZ2Uo UHlHQ0luZm8gKnVucmVhY2hhYmxlLCBQeUdDSW5mbyAqb2xkKQ0KK3sNCisJaW5xdWlyeSBj bGVhcjsNCisNCisJd2hpbGUgKHVucmVhY2hhYmxlLT5nY19uZXh0ICE9IHVucmVhY2hhYmxl KSB7DQorCQlQeUdDSW5mbyAqZ2MgPSB1bnJlYWNoYWJsZS0+Z2NfbmV4dDsNCisJCVB5T2Jq ZWN0ICpvcCA9IFBZX0dDT0JKKGdjKTsNCisJCWlmICgoY2xlYXIgPSBvcC0+b2JfdHlwZS0+ dHBfY2xlYXIpICE9IE5VTEwpIHsNCisJCQlQeV9JTkNSRUYob3ApOw0KKwkJCWNsZWFyKChQ eU9iamVjdCAqKW9wKTsNCisJCQlQeV9ERUNSRUYob3ApOw0KKwkJfQ0KKwkJLyogb25seSB0 cnkgdG8gY2FsbCB0cF9jbGVhciBvbmNlIGZvciBlYWNoIG9iamVjdCAqLw0KKwkJaWYgKHVu cmVhY2hhYmxlLT5nY19uZXh0ID09IGdjKSB7DQorCQkJLyogc3RpbGwgYWxpdmUsIG1vdmUg aXQsIGl0IG1heSBkaWUgbGF0ZXIgKi8NCisJCQlMSVNUX1JFTU9WRShnYyk7DQorCQkJTElT VF9BUFBFTkQoZ2MsIG9sZCk7DQorCQl9DQorCX0NCit9DQorDQorLyogVGhpcyBpcyB0aGUg bWFpbiBmdW5jdGlvbi4gIFJlYWQgdGhpcyB0byB1bmRlcnN0YW5kIGhvdyB0aGUNCisgKiBj b2xsZWN0aW9uIHByb2Nlc3Mgd29ya3MuICovDQorc3RhdGljIGxvbmcNCitjb2xsZWN0KFB5 R0NJbmZvICp5b3VuZywgUHlHQ0luZm8gKm9sZCkNCit7DQorCWxvbmcgbiA9IDA7DQorCWxv bmcgbSA9IDA7DQorCVB5R0NJbmZvIHJlYWNoYWJsZTsNCisJUHlHQ0luZm8gdW5yZWFjaGFi bGU7DQorCVB5R0NJbmZvIGZpbmFsaXplcnM7DQorCVB5R0NJbmZvICpnYzsNCisJUHlPYmpl Y3QgKm91dHB1dCA9IE5VTEw7DQorDQorCWlmIChkZWJ1Zykgew0KKwkJb3V0cHV0ID0gUHlT eXNfR2V0T2JqZWN0KCJzdGRlcnIiKTsNCisJfQ0KKwlpZiAoZGVidWcgJiBERUJVR19TVEFU Uykgew0KKwkJY2hhciBidWZbMTAwXTsNCisJCXNwcmludGYoYnVmLCAiZ2M6IGNvbGxlY3Rp bmcgZ2VuZXJhdGlvbiAlZC4uLlxuIiwgZ2VuZXJhdGlvbik7DQorCQlQeUZpbGVfV3JpdGVT dHJpbmcoYnVmLG91dHB1dCk7DQorCQlzcHJpbnRmKGJ1ZiwgImdjOiBvYmplY3RzIGluIGVh Y2ggZ2VuZXJhdGlvbjogJWQgJWQgJWRcbiIsDQorCQkJTElTVF9TSVpFKCZnZW5lcmF0aW9u MCksDQorCQkJTElTVF9TSVpFKCZnZW5lcmF0aW9uMSksDQorCQkJTElTVF9TSVpFKCZnZW5l cmF0aW9uMikpOw0KKwkJUHlGaWxlX1dyaXRlU3RyaW5nKGJ1ZixvdXRwdXQpOw0KKwl9DQor DQorCS8qIFVzaW5nIG9iX3JlZmNudCBhbmQgZ2NfcmVmcywgY2FsY3VsYXRlIHdoaWNoIG9i amVjdHMgaW4gdGhlDQorCSAqIGNvbnRhaW5lciBzZXQgYXJlIHJlYWNoYWJsZSBmcm9tIG91 dHNpZGUgdGhlIHNldCAoaWUuIGhhdmUgYQ0KKwkgKiByZWZjb3VudCBncmVhdGVyIHRoYW4g MCB3aGVuIGFsbCB0aGUgcmVmZXJlbmNlcyB3aXRoaW4gdGhlDQorCSAqIHNldCBhcmUgdGFr ZW4gaW50byBhY2NvdW50ICovDQorCXVwZGF0ZV9yZWZzKHlvdW5nKTsNCisJc3VidHJhY3Rf cmVmcyh5b3VuZyk7DQorDQorCS8qIE1vdmUgZXZlcnl0aGluZyByZWFjaGFibGUgZnJvbSBv dXRzaWRlIHRoZSBzZXQgaW50byB0aGUNCisJICogcmVhY2hhYmxlIHNldCAoaWUuIGdjX3Jl ZnMgPiAwKS4gIE5leHQsIG1vdmUgZXZlcnl0aGluZw0KKwkgKiByZWFjaGFibGUgZnJvbSBv YmplY3RzIGluIHRoZSByZWFjaGFibGUgc2V0LiAqLw0KKwlMSVNUX0lOSVQoJnJlYWNoYWJs ZSk7DQorCW1vdmVfcm9vdHMoeW91bmcsICZyZWFjaGFibGUpOw0KKwltb3ZlX3Jvb3RfcmVh Y2hhYmxlKCZyZWFjaGFibGUpOw0KKw0KKwkvKiBtb3ZlIHVucmVhY2hhYmxlIG9iamVjdHMg dG8gYSB0ZW1wb3JhcnkgbGlzdCwgbmV3IG9iamVjdHMgY2FuIGJlDQorCSAqIGFsbG9jYXRl ZCBhZnRlciB0aGlzIHBvaW50ICovDQorCUxJU1RfSU5JVCgmdW5yZWFjaGFibGUpOw0KKwlM SVNUX01PVkUoeW91bmcsICZ1bnJlYWNoYWJsZSk7DQorCS8vTElTVF9JTklUKHlvdW5nKTsN CisNCisJLyogbW92ZSByZWFjaGFibGUgb2JqZWN0cyB0byBuZXh0IGdlbmVyYXRpb24gKi8N CisJTElTVF9MQVBQRU5EKCZyZWFjaGFibGUsIG9sZCk7DQorDQorCS8qIE1vdmUgb2JqZWN0 cyByZWFjaGFibGUgZnJvbSBmaW5hbGl6ZXJzLCB3ZSBjYW4ndCBzYWZlbHkgZGVsZXRlDQor CSAqIHRoZW0uICBQeXRob24gcHJvZ3JhbW1lcnMgc2hvdWxkIHRha2UgY2FyZSBub3QgdG8g Y3JlYXRlIHN1Y2gNCisJICogdGhpbmdzLiAgRm9yIFB5dGhvbiBmaW5hbGl6ZXJzIG1lYW5z IGluc3RhbmNlIG9iamVjdHMgd2l0aA0KKwkgKiBfX2RlbF9fIG1ldGhvZHMuICovDQorCUxJ U1RfSU5JVCgmZmluYWxpemVycyk7DQorCW1vdmVfZmluYWxpemVycygmdW5yZWFjaGFibGUs ICZmaW5hbGl6ZXJzKTsNCisJbW92ZV9maW5hbGl6ZXJfcmVhY2hhYmxlKCZmaW5hbGl6ZXJz KTsNCisNCisJLyogQ29sbGVjdCBzdGF0aXN0aWNzIG9uIGNvbGxlY3RhYmxlIG9iamVjdHMg Zm91bmQgYW5kIHByaW50DQorCSAqIGRlYnVnZ2luZyBpbmZvcm1hdGlvbi4gKi8NCisJZm9y IChnYyA9IHVucmVhY2hhYmxlLmdjX25leHQ7IGdjICE9ICZ1bnJlYWNoYWJsZTsNCisJCQln YyA9IGdjLT5nY19uZXh0KSB7DQorCQltKys7DQorCQlpZiAob3V0cHV0ICE9IE5VTEwgJiYg KGRlYnVnICYgREVCVUdfQ09MTEVDVEFCTEUpKSB7DQorCQkJZGVidWdfY3ljbGUob3V0cHV0 LCAiY29sbGVjdGFibGUgIiwgUFlfR0NPQkooZ2MpKTsNCisJCX0NCisJfQ0KKwkvKiBjYWxs IHRwX2NsZWFyIG9uIG9iamVjdHMgaW4gdGhlIGNvbGxlY3RhYmxlIHNldC4gIFRoaXMgd2ls bCBjYXVzZQ0KKwkgKiB0aGUgcmVmZXJlbmNlIGN5Y2xlcyB0byBiZSBicm9rZW4uIEl0IG1h eSBhbHNvIGNhdXNlIHNvbWUgb2JqZWN0cyBpbg0KKwkgKiBmaW5hbGl6ZXJzIHRvIGJlIGZy ZWVkICovDQorCWRlbGV0ZV9nYXJiYWdlKCZ1bnJlYWNoYWJsZSwgb2xkKTsNCisNCisJLyog Q29sbGVjdCBzdGF0aXN0aWNzIG9uIHVuY29sbGVjdGFibGUgb2JqZWN0cyBmb3VuZCBhbmQg cHJpbnQNCisJICogZGVidWdnaW5nIGluZm9ybWF0aW9uLiAqLw0KKwlmb3IgKGdjID0gZmlu YWxpemVycy5nY19uZXh0OyBnYyAhPSAmZmluYWxpemVyczsNCisJCQlnYyA9IGdjLT5nY19u ZXh0KSB7DQorCQluKys7DQorCQlpZiAob3V0cHV0ICE9IE5VTEwgJiYgKGRlYnVnICYgREVC VUdfVU5DT0xMRUNUQUJMRSkpIHsNCisJCQlkZWJ1Z19jeWNsZShvdXRwdXQsICJ1bmNvbGxl Y3RhYmxlICIsIFBZX0dDT0JKKGdjKSk7DQorCQl9DQorCX0NCisJaWYgKG91dHB1dCAhPSBO VUxMICYmIChkZWJ1ZyAmIERFQlVHX1NUQVRTKSkgew0KKwkJaWYgKG0gPT0gMCAmJiBuID09 IDApIHsNCisJCQlQeUZpbGVfV3JpdGVTdHJpbmcoImdjOiBkb25lLlxuIiwgb3V0cHV0KTsN CisJCX0gZWxzZSB7DQorCQkJY2hhciBidWZbMjAwXTsNCisJCQlzcHJpbnRmKGJ1ZiwNCisJ CQkJImdjOiBkb25lLCAlZCB1bnJlYWNoYWJsZSwgJWQgdW5jb2xsZWN0YWJsZS5cbiIsDQor CQkJCW4rbSwgbik7DQorCQkJUHlGaWxlX1dyaXRlU3RyaW5nKGJ1Ziwgb3V0cHV0KTsNCisJ CX0NCisJfQ0KKw0KKwkvKiBBcHBlbmQgaW5zdGFuY2VzIGluIHRoZSB1bmNvbGxlY3RhYmxl IHNldCB0byBhIFB5dGhvbg0KKwkgKiByZWFjaGFibGUgbGlzdCBvZiBnYXJiYWdlLiAgVGhl IHByb2dyYW1tZXIgaGFzIHRvIGRlYWwgd2l0aA0KKwkgKiB0aGlzIGlmIHRoZXkgaW5zaXN0 IG9uIGNyZWF0aW5nIHRoaXMgdHlwZSBvZiBzdHJ1Y3R1cmUuICovDQorCWhhbmRsZV9maW5h bGl6ZXJzKCZmaW5hbGl6ZXJzLCBvbGQpOw0KKw0KKwlhbGxvY2F0ZWQgPSAwOw0KKwlQeUVy cl9DbGVhcigpOyAvKiBpbiBjYXNlIHdyaXRpbmcgdG8gc3lzLnN0ZGVyciBmYWlsZWQgKi8N CisJcmV0dXJuIG4rbTsNCit9DQorDQorc3RhdGljIGxvbmcNCitjb2xsZWN0X2dlbmVyYXRp b25zKHZvaWQpDQorew0KKwlzdGF0aWMgbG9uZyBjb2xsZWN0aW9uczAgPSAwOw0KKwlzdGF0 aWMgbG9uZyBjb2xsZWN0aW9uczEgPSAwOw0KKwlsb25nIG47DQorDQorDQorCWlmIChjb2xs ZWN0aW9uczEgPiB0aHJlc2hvbGQyKSB7DQorCQlnZW5lcmF0aW9uID0gMjsNCisJCUxJU1Rf TEFQUEVORCgmZ2VuZXJhdGlvbjAsICZnZW5lcmF0aW9uMik7DQorCQlMSVNUX0xBUFBFTkQo JmdlbmVyYXRpb24xLCAmZ2VuZXJhdGlvbjIpOw0KKwkJaWYgKGdlbmVyYXRpb24yLmdjX25l eHQgIT0gJmdlbmVyYXRpb24yKSB7DQorCQkJbiA9IGNvbGxlY3QoJmdlbmVyYXRpb24yLCAm Z2VuZXJhdGlvbjIpOw0KKwkJfQ0KKwkJY29sbGVjdGlvbnMxID0gMDsNCisJfSBlbHNlIGlm IChjb2xsZWN0aW9uczAgPiB0aHJlc2hvbGQxKSB7DQorCQlnZW5lcmF0aW9uID0gMTsNCisJ CWNvbGxlY3Rpb25zMSsrOw0KKwkJTElTVF9MQVBQRU5EKCZnZW5lcmF0aW9uMCwgJmdlbmVy YXRpb24xKTsNCisJCWlmIChnZW5lcmF0aW9uMS5nY19uZXh0ICE9ICZnZW5lcmF0aW9uMSkg ew0KKwkJCW4gPSBjb2xsZWN0KCZnZW5lcmF0aW9uMSwgJmdlbmVyYXRpb24yKTsNCisJCX0N CisJCWNvbGxlY3Rpb25zMCA9IDA7DQorCX0gZWxzZSB7DQorCQlnZW5lcmF0aW9uID0gMDsN CisJCWNvbGxlY3Rpb25zMCsrOw0KKwkJaWYgKGdlbmVyYXRpb24wLmdjX25leHQgIT0gJmdl bmVyYXRpb24wKSB7DQorCQkJbiA9IGNvbGxlY3QoJmdlbmVyYXRpb24wLCAmZ2VuZXJhdGlv bjEpOw0KKwkJfQ0KKwl9DQorCXJldHVybiBuOw0KK30NCisNCit2b2lkDQorUHlHQ19JbnNl cnQoUHlPYmplY3QgKm9wKQ0KK3sNCisJLyogY29sbGVjdGlvbiBsb2NrIHNpbmNlIGNvbGxl Y3RpbmcgbWF5IGNhdXNlIGFsbG9jYXRpb25zICovDQorCXN0YXRpYyBpbnQgY29sbGVjdGlu ZyA9IDA7DQorDQorI2lmZGVmIERFQlVHDQorCS8qZnByaW50ZihzdGRlcnIsICJJbnNlcnQg MHgleFxuIiwgb3ApOyovDQorI2VuZGlmDQorCWlmICh0aHJlc2hvbGQwICYmIGFsbG9jYXRl ZCA+IHRocmVzaG9sZDAgJiYgIWNvbGxlY3RpbmcpIHsNCisJCWNvbGxlY3RpbmcrKzsNCisJ CWNvbGxlY3RfZ2VuZXJhdGlvbnMoKTsNCisJCWNvbGxlY3RpbmctLTsNCisJfQ0KKwlhbGxv Y2F0ZWQrKzsNCisJTElTVF9BUFBFTkQoUFlfR0NJTkZPKG9wKSwgJmdlbmVyYXRpb24wKTsN Cit9DQorDQordm9pZA0KK1B5R0NfUmVtb3ZlKFB5T2JqZWN0ICpvcCkNCit7DQorI2lmZGVm IERFQlVHDQorCS8qZnByaW50ZihzdGRlcnIsICJSZW1vdmUgMHgleFxuIiwgb3ApOyovDQor I2VuZGlmDQorCWlmIChhbGxvY2F0ZWQgPiAwKSB7DQorCQlhbGxvY2F0ZWQtLTsNCisJfQ0K KwlMSVNUX1JFTU9WRShQWV9HQ0lORk8ob3ApKTsNCit9DQorDQorDQorc3RhdGljIGNoYXIg Y29sbGVjdF9fZG9jX19bXSA9DQorImNvbGxlY3QoKSAtPiBuXG4iDQorIlxuIg0KKyJSdW4g YSBmdWxsIGNvbGxlY3Rpb24uICBUaGUgbnVtYmVyIG9mIHVucmVhY2hhYmxlIG9iamVjdHMg aXMgcmV0dXJuZWQuXG4iDQorOw0KKw0KK3N0YXRpYyBQeU9iamVjdCAqDQorUHlfY29sbGVj dChzZWxmLCBhcmdzKQ0KKwlQeU9iamVjdCAqc2VsZjsNCisJUHlPYmplY3QgKmFyZ3M7DQor ew0KKwlsb25nIG47DQorDQorCWlmKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICIiKSkJLyog Y2hlY2sgbm8gYXJncyAqLw0KKwkJcmV0dXJuIE5VTEw7DQorDQorCWdlbmVyYXRpb24gPSAy Ow0KKwlMSVNUX0xBUFBFTkQoJmdlbmVyYXRpb24wLCAmZ2VuZXJhdGlvbjIpOw0KKwlMSVNU X0xBUFBFTkQoJmdlbmVyYXRpb24xLCAmZ2VuZXJhdGlvbjIpOw0KKwluID0gY29sbGVjdCgm Z2VuZXJhdGlvbjIsICZnZW5lcmF0aW9uMik7DQorDQorCXJldHVybiBQeV9CdWlsZFZhbHVl KCJpIiwgbik7DQorfQ0KKw0KK3N0YXRpYyBjaGFyIHNldF9kZWJ1Z19fZG9jX19bXSA9IA0K KyJzZXRfZGVidWcoZmxhZ3MpIC0+IE5vbmVcbiINCisiXG4iDQorIlNldCB0aGUgZ2FyYmFn ZSBjb2xsZWN0aW9uIGRlYnVnZ2luZyBmbGFncy4gRGVidWdnaW5nIGluZm9ybWF0aW9uIGlz XG4iDQorIndyaXR0ZW4gdG8gc3lzLnN0ZGVyci5cbiINCisiXG4iDQorImZsYWdzIGlzIGFu IGludGVnZXIgYW5kIGNhbiBoYXZlIHRoZSBmb2xsb3dpbmcgYml0cyB0dXJuZWQgb246XG4i DQorIlxuIg0KKyIgIERFQlVHX1NUQVRTIC0gUHJpbnQgc3RhdGlzdGljcyBkdXJpbmcgY29s bGVjdGlvbi5cbiINCisiICBERUJVR19DT0xMRUNUQUJMRSAtIFByaW50IGNvbGxlY3RhYmxl IG9iamVjdHMgZm91bmQuXG4iDQorIiAgREVCVUdfVU5DT0xMRUNUQUJMRSAtIFByaW50IHVu cmVhY2hhYmxlIGJ1dCB1bmNvbGxlY3RhYmxlIG9iamVjdHMgZm91bmQuXG4iDQorIiAgREVC VUdfSU5TVEFOQ0VTIC0gUHJpbnQgaW5zdGFuY2Ugb2JqZWN0cy5cbiINCisiICBERUJVR19P QkpFQ1RTIC0gUHJpbnQgb2JqZWN0cyBvdGhlciB0aGFuIGluc3RhbmNlcy5cbiINCisiICBE RUJVR19MRUFLIC0gRGVidWcgbGVha2luZyBwcm9ncmFtcyAoZXZlcnl0aGluZyBidXQgU1RB VFMpLlxuIg0KKzsNCisNCitzdGF0aWMgUHlPYmplY3QgKg0KK1B5X3NldF9kZWJ1ZyhzZWxm LCBhcmdzKQ0KKwlQeU9iamVjdCAqc2VsZjsNCisJUHlPYmplY3QgKmFyZ3M7DQorew0KKwlp ZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgImwiLCAmZGVidWcpKQ0KKwkJcmV0dXJuIE5V TEw7DQorDQorCVB5X0lOQ1JFRihQeV9Ob25lKTsNCisJcmV0dXJuIFB5X05vbmU7DQorfQ0K Kw0KK3N0YXRpYyBjaGFyIGdldF9kZWJ1Z19fZG9jX19bXSA9IA0KKyJnZXRfZGVidWcoKSAt PiBmbGFnc1xuIg0KKyJcbiINCisiR2V0IHRoZSBnYXJiYWdlIGNvbGxlY3Rpb24gZGVidWdn aW5nIGZsYWdzLlxuIg0KKzsNCisNCitzdGF0aWMgUHlPYmplY3QgKg0KK1B5X2dldF9kZWJ1 ZyhzZWxmLCBhcmdzKQ0KKwlQeU9iamVjdCAqc2VsZjsNCisJUHlPYmplY3QgKmFyZ3M7DQor ew0KKwlpZighUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiIikpCS8qIG5vIGFyZ3MgKi8NCisJ CXJldHVybiBOVUxMOw0KKw0KKwlyZXR1cm4gUHlfQnVpbGRWYWx1ZSgiaSIsIGRlYnVnKTsN Cit9DQorDQorc3RhdGljIGNoYXIgc2V0X3RocmVzaF9fZG9jX19bXSA9DQorInNldF90aHJl c2hvbGQodGhyZXNob2xkMCwgW3RocmVob2xkMSwgdGhyZXNob2xkMl0pIC0+IE5vbmVcbiIN CisiXG4iDQorIlNldHMgdGhlIGNvbGxlY3Rpb24gdGhyZXNob2xkcy4gIFNldHRpbmcgdGhy ZXNob2xkMCB0byB6ZXJvIGRpc2FibGVzXG4iDQorImNvbGxlY3Rpb24uXG4iDQorOw0KKw0K K3N0YXRpYyBQeU9iamVjdCAqDQorUHlfc2V0X3RocmVzaChzZWxmLCBhcmdzKQ0KKwlQeU9i amVjdCAqc2VsZjsNCisJUHlPYmplY3QgKmFyZ3M7DQorew0KKwlpZiAoIVB5QXJnX1BhcnNl VHVwbGUoYXJncywgIml8aWkiLCAmdGhyZXNob2xkMCwgDQorCQkJCSZ0aHJlc2hvbGQxLCAm dGhyZXNob2xkMikpDQorCQlyZXR1cm4gTlVMTDsNCisNCisJUHlfSU5DUkVGKFB5X05vbmUp Ow0KKwlyZXR1cm4gUHlfTm9uZTsNCit9DQorDQorc3RhdGljIGNoYXIgZ2V0X3RocmVzaF9f ZG9jX19bXSA9DQorImdldF90cmVzaG9sZCgpIC0+ICh0aHJlc2hvbGQwLCB0aHJlc2hvbGQx LCB0aHJlc2hvbGQyKVxuIg0KKyJcbiINCisiUmV0dXJuIHRoZSBjdXJyZW50IGNvbGxlY3Rp b24gdGhyZXNob2xkc1xuIg0KKzsNCisNCitzdGF0aWMgUHlPYmplY3QgKg0KK1B5X2dldF90 aHJlc2goc2VsZiwgYXJncykNCisJUHlPYmplY3QgKnNlbGY7DQorCVB5T2JqZWN0ICphcmdz Ow0KK3sNCisJaWYoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIiIpKQkvKiBubyBhcmdzICov DQorCQlyZXR1cm4gTlVMTDsNCisNCisJcmV0dXJuIFB5X0J1aWxkVmFsdWUoIihpaWkpIiwg dGhyZXNob2xkMCwgdGhyZXNob2xkMSwgdGhyZXNob2xkMik7DQorfQ0KKw0KKw0KK3N0YXRp YyBjaGFyIGdjX19kb2NfXyBbXSA9DQorIlRoaXMgbW9kdWxlIHByb3ZpZGVzIGFjY2VzcyB0 byB0aGUgZ2FyYmFnZSBjb2xsZWN0b3IgZm9yIHJlZmVyZW5jZSBjeWNsZXMuXG4iDQorIlxu Ig0KKyJjb2xsZWN0KCkgLS0gRG8gYSBmdWxsIGNvbGxlY3Rpb24gcmlnaHQgbm93LlxuIg0K KyJzZXRfZGVidWcoKSAtLSBTZXQgZGVidWdnaW5nIGZsYWdzLlxuIg0KKyJnZXRfZGVidWco KSAtLSBHZXQgZGVidWdnaW5nIGZsYWdzLlxuIg0KKyJzZXRfdGhyZXNob2xkKCkgLS0gU2V0 IHRoZSBjb2xsZWN0aW9uIHRocmVzaG9sZHMuXG4iDQorImdldF90aHJlc2hvbGQoKSAtLSBS ZXR1cm4gdGhlIGN1cnJlbnQgdGhlIGNvbGxlY3Rpb24gdGhyZXNob2xkcy5cbiINCis7DQor DQorc3RhdGljIFB5TWV0aG9kRGVmIEdjTWV0aG9kc1tdID0gew0KKwl7InNldF9kZWJ1ZyIs CQlQeV9zZXRfZGVidWcsICBNRVRIX1ZBUkFSR1MsIHNldF9kZWJ1Z19fZG9jX199LA0KKwl7 ImdldF9kZWJ1ZyIsCQlQeV9nZXRfZGVidWcsICBNRVRIX1ZBUkFSR1MsIGdldF9kZWJ1Z19f ZG9jX199LA0KKwl7InNldF90aHJlc2hvbGQiLAlQeV9zZXRfdGhyZXNoLCBNRVRIX1ZBUkFS R1MsIHNldF90aHJlc2hfX2RvY19ffSwNCisJeyJnZXRfdGhyZXNob2xkIiwJUHlfZ2V0X3Ro cmVzaCwgTUVUSF9WQVJBUkdTLCBnZXRfdGhyZXNoX19kb2NfX30sDQorCXsiY29sbGVjdCIs CQlQeV9jb2xsZWN0LCAgICBNRVRIX1ZBUkFSR1MsIGNvbGxlY3RfX2RvY19ffSwNCisJe05V TEwsCU5VTEx9CQkvKiBTZW50aW5lbCAqLw0KK307DQorDQordm9pZA0KK2luaXRnYyh2b2lk KQ0KK3sNCisJUHlPYmplY3QgKm07DQorCVB5T2JqZWN0ICpkOw0KKw0KKwltID0gUHlfSW5p dE1vZHVsZTQoImdjIiwNCisJCQkgICAgICBHY01ldGhvZHMsDQorCQkJICAgICAgZ2NfX2Rv Y19fLA0KKwkJCSAgICAgIE5VTEwsDQorCQkJICAgICAgUFlUSE9OX0FQSV9WRVJTSU9OKTsN CisJZCA9IFB5TW9kdWxlX0dldERpY3QobSk7DQorCWlmIChnYXJiYWdlID09IE5VTEwpIHsN CisJCWdhcmJhZ2UgPSBQeUxpc3RfTmV3KDApOw0KKwl9DQorCVB5RGljdF9TZXRJdGVtU3Ry aW5nKGQsICJnYXJiYWdlIiwgZ2FyYmFnZSk7DQorCVB5RGljdF9TZXRJdGVtU3RyaW5nKGQs ICJERUJVR19TVEFUUyIsDQorCQkJUHlJbnRfRnJvbUxvbmcoREVCVUdfU1RBVFMpKTsNCisJ UHlEaWN0X1NldEl0ZW1TdHJpbmcoZCwgIkRFQlVHX0NPTExFQ1RBQkxFIiwNCisJCQlQeUlu dF9Gcm9tTG9uZyhERUJVR19DT0xMRUNUQUJMRSkpOw0KKwlQeURpY3RfU2V0SXRlbVN0cmlu ZyhkLCAiREVCVUdfVU5DT0xMRUNUQUJMRSIsDQorCQkJUHlJbnRfRnJvbUxvbmcoREVCVUdf VU5DT0xMRUNUQUJMRSkpOw0KKwlQeURpY3RfU2V0SXRlbVN0cmluZyhkLCAiREVCVUdfSU5T VEFOQ0VTIiwNCisJCQlQeUludF9Gcm9tTG9uZyhERUJVR19JTlNUQU5DRVMpKTsNCisJUHlE aWN0X1NldEl0ZW1TdHJpbmcoZCwgIkRFQlVHX09CSkVDVFMiLA0KKwkJCVB5SW50X0Zyb21M b25nKERFQlVHX09CSkVDVFMpKTsNCisJUHlEaWN0X1NldEl0ZW1TdHJpbmcoZCwgIkRFQlVH X0xFQUsiLA0KKwkJCVB5SW50X0Zyb21Mb25nKERFQlVHX0xFQUspKTsNCit9DQorDQotLS0g UHl0aG9uLWN2cy9PYmplY3RzL2NsYXNzb2JqZWN0LmMJVHVlIEZlYiAyOSAxNDo1NToxNSAy MDAwDQorKysgUHl0aG9uLWdjL09iamVjdHMvY2xhc3NvYmplY3QuYwlNb24gQXByIDI0IDIx OjE5OjE4IDIwMDANCkBAIC0xMTAsNyArMTEwLDcgQEANCiAJCX0NCiAJCVB5X0lOQ1JFRihi YXNlcyk7DQogCX0NCi0Jb3AgPSBQeU9iamVjdF9ORVcoUHlDbGFzc09iamVjdCwgJlB5Q2xh c3NfVHlwZSk7DQorCW9wID0gUHlPYmplY3RfTmV3KFB5Q2xhc3NPYmplY3QsICZQeUNsYXNz X1R5cGUpOw0KIAlpZiAob3AgPT0gTlVMTCkgew0KIAkJUHlfREVDUkVGKGJhc2VzKTsNCiAJ CXJldHVybiBOVUxMOw0KQEAgLTEzMSw2ICsxMzEsOSBAQA0KIAlQeV9YSU5DUkVGKG9wLT5j bF9nZXRhdHRyKTsNCiAJUHlfWElOQ1JFRihvcC0+Y2xfc2V0YXR0cik7DQogCVB5X1hJTkNS RUYob3AtPmNsX2RlbGF0dHIpOw0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDDQorCVB5R0NfSW5z ZXJ0KChQeU9iamVjdCAqKW9wKTsNCisjZW5kaWYNCiAJcmV0dXJuIChQeU9iamVjdCAqKSBv cDsNCiB9DQogDQpAQCAtMTQwLDEzICsxNDMsMTYgQEANCiBjbGFzc19kZWFsbG9jKG9wKQ0K IAlQeUNsYXNzT2JqZWN0ICpvcDsNCiB7DQorI2lmZGVmIFdJVEhfQ1lDTEVfR0MNCisJUHlH Q19SZW1vdmUoKFB5T2JqZWN0ICopb3ApOw0KKyNlbmRpZg0KIAlQeV9ERUNSRUYob3AtPmNs X2Jhc2VzKTsNCiAJUHlfREVDUkVGKG9wLT5jbF9kaWN0KTsNCiAJUHlfWERFQ1JFRihvcC0+ Y2xfbmFtZSk7DQogCVB5X1hERUNSRUYob3AtPmNsX2dldGF0dHIpOw0KIAlQeV9YREVDUkVG KG9wLT5jbF9zZXRhdHRyKTsNCiAJUHlfWERFQ1JFRihvcC0+Y2xfZGVsYXR0cik7DQotCWZy ZWUoKEFOWSAqKW9wKTsNCisJUHlPYmplY3RfRGVsKChQeU9iamVjdCAqKW9wKTsNCiB9DQog DQogc3RhdGljIFB5T2JqZWN0ICoNCkBAIC0zODYsNiArMzkyLDIxIEBADQogCXJldHVybiBy ZXM7DQogfQ0KIA0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDDQorc3RhdGljIGludA0KK2NsYXNz X3JlY3Vyc2UoUHlDbGFzc09iamVjdCAqbywgdmlzaXRwcm9jIHZpc2l0LCB2b2lkICpjbG9z dXJlKQ0KK3sNCisJaWYgKG8tPmNsX2Jhc2VzKSB2aXNpdChvLT5jbF9iYXNlcywgY2xvc3Vy ZSk7DQorCWlmIChvLT5jbF9kaWN0KSB2aXNpdChvLT5jbF9kaWN0LCBjbG9zdXJlKTsNCisJ aWYgKG8tPmNsX25hbWUpIHZpc2l0KG8tPmNsX25hbWUsIGNsb3N1cmUpOw0KKwlpZiAoby0+ Y2xfZ2V0YXR0cikgdmlzaXQoby0+Y2xfZ2V0YXR0ciwgY2xvc3VyZSk7DQorCWlmIChvLT5j bF9zZXRhdHRyKSB2aXNpdChvLT5jbF9zZXRhdHRyLCBjbG9zdXJlKTsNCisJaWYgKG8tPmNs X2RlbGF0dHIpIHZpc2l0KG8tPmNsX2RlbGF0dHIsIGNsb3N1cmUpOw0KKwlyZXR1cm4gMTsN Cit9DQorI2VuZGlmIC8qIFdJVEhfQ1lDTEVfR0MgKi8NCisNCisNCiBQeVR5cGVPYmplY3Qg UHlDbGFzc19UeXBlID0gew0KIAlQeU9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlKQ0K IAkwLA0KQEAgLTQwNiw2ICs0MjcsMTIgQEANCiAJKHJlcHJmdW5jKWNsYXNzX3N0ciwgLyp0 cF9zdHIqLw0KIAkoZ2V0YXR0cm9mdW5jKWNsYXNzX2dldGF0dHIsIC8qdHBfZ2V0YXR0cm8q Lw0KIAkoc2V0YXR0cm9mdW5jKWNsYXNzX3NldGF0dHIsIC8qdHBfc2V0YXR0cm8qLw0KKyNp ZmRlZiBXSVRIX0NZQ0xFX0dDDQorCTAsCQkvKiB0cF9hc19idWZmZXIgKi8NCisJUHlfVFBG TEFHU19ERUZBVUxUIHwgUHlfVFBGTEFHU19IQVZFX0dDSU5GTywgLyp0cF9mbGFncyovDQor CTAsCQkvKiB0cF9kb2MgKi8NCisJKHJlY3Vyc2Vwcm9jKWNsYXNzX3JlY3Vyc2UsCS8qIHRw X3JlY3Vyc2UgKi8NCisjZW5kaWYNCiB9Ow0KIA0KIGludA0KQEAgLTQ0NCwxMiArNDcxLDE1 IEBADQogCQlQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsNCiAJCXJldHVybiBOVUxMOw0KIAl9 DQotCWluc3QgPSBQeU9iamVjdF9ORVcoUHlJbnN0YW5jZU9iamVjdCwgJlB5SW5zdGFuY2Vf VHlwZSk7DQorCWluc3QgPSBQeU9iamVjdF9OZXcoUHlJbnN0YW5jZU9iamVjdCwgJlB5SW5z dGFuY2VfVHlwZSk7DQogCWlmIChpbnN0ID09IE5VTEwpDQogCQlyZXR1cm4gTlVMTDsNCiAJ UHlfSU5DUkVGKGNsYXNzKTsNCiAJaW5zdC0+aW5fY2xhc3MgPSAoUHlDbGFzc09iamVjdCAq KWNsYXNzOw0KIAlpbnN0LT5pbl9kaWN0ID0gUHlEaWN0X05ldygpOw0KKyNpZmRlZiBXSVRI X0NZQ0xFX0dDDQorCVB5R0NfSW5zZXJ0KChQeU9iamVjdCAqKWluc3QpOw0KKyNlbmRpZg0K IAlpZiAoaW5zdC0+aW5fZGljdCA9PSBOVUxMKSB7DQogCQlQeV9ERUNSRUYoaW5zdCk7DQog CQlyZXR1cm4gTlVMTDsNCkBAIC00OTgsMTEgKzUyOCwxNCBAQA0KIAlQeU9iamVjdCAqZXJy b3JfdHlwZSwgKmVycm9yX3ZhbHVlLCAqZXJyb3JfdHJhY2ViYWNrOw0KIAlQeU9iamVjdCAq ZGVsOw0KIAlzdGF0aWMgUHlPYmplY3QgKmRlbHN0cjsNCisJZXh0ZXJuIGxvbmcgX1B5X1Jl ZlRvdGFsOw0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDDQorCVB5R0NfUmVtb3ZlKChQeU9iamVj dCAqKWluc3QpOw0KKyNlbmRpZg0KIAkvKiBDYWxsIHRoZSBfX2RlbF9fIG1ldGhvZCBpZiBp dCBleGlzdHMuICBGaXJzdCB0ZW1wb3JhcmlseQ0KIAkgICByZXZpdmUgdGhlIG9iamVjdCBh bmQgc2F2ZSB0aGUgY3VycmVudCBleGNlcHRpb24sIGlmIGFueS4gKi8NCiAjaWZkZWYgUHlf VFJBQ0VfUkVGUw0KIAkvKiBtdWNoIHRvbyBjb21wbGljYXRlZCBpZiBQeV9UUkFDRV9SRUZT IGRlZmluZWQgKi8NCi0JZXh0ZXJuIGxvbmcgX1B5X1JlZlRvdGFsOw0KIAlpbnN0LT5vYl90 eXBlID0gJlB5SW5zdGFuY2VfVHlwZTsNCiAJX1B5X05ld1JlZmVyZW5jZSgoUHlPYmplY3Qg KilpbnN0KTsNCiAJX1B5X1JlZlRvdGFsLS07CQkvKiBjb21wZW5zYXRlIGZvciBpbmNyZW1l bnQgaW4gTkVXUkVGICovDQpAQCAtNTUwLDYgKzU4Myw5IEBADQogI2lmZGVmIENPVU5UX0FM TE9DUw0KIAkJaW5zdC0+b2JfdHlwZS0+dHBfZnJlZS0tOw0KICNlbmRpZg0KKyNpZmRlZiBX SVRIX0NZQ0xFX0dDDQorCQlQeUdDX0luc2VydCgoUHlPYmplY3QgKilpbnN0KTsNCisjZW5k aWYNCiAJCXJldHVybjsgLyogX19kZWxfXyBhZGRlZCBhIHJlZmVyZW5jZTsgZG9uJ3QgZGVs ZXRlIG5vdyAqLw0KIAl9DQogI2lmZGVmIFB5X1RSQUNFX1JFRlMNCkBAIC01NTcsMTEgKzU5 MywxMCBAQA0KIAlpbnN0LT5vYl90eXBlLT50cF9mcmVlLS07CS8qIGNvbXBlbnNhdGUgZm9y IGluY3JlbWVudCBpbiBVTlJFRiAqLw0KICNlbmRpZg0KIAlfUHlfRm9yZ2V0UmVmZXJlbmNl KChQeU9iamVjdCAqKWluc3QpOw0KLQlpbnN0LT5vYl90eXBlID0gTlVMTDsNCiAjZW5kaWYg LyogUHlfVFJBQ0VfUkVGUyAqLw0KIAlQeV9ERUNSRUYoaW5zdC0+aW5fY2xhc3MpOw0KIAlQ eV9YREVDUkVGKGluc3QtPmluX2RpY3QpOw0KLQlmcmVlKChBTlkgKilpbnN0KTsNCisJUHlP YmplY3RfRGVsKChQeU9iamVjdCAqKWluc3QpOw0KIH0NCiANCiBzdGF0aWMgUHlPYmplY3Qg Kg0KQEAgLTg0MCw2ICs4NzUsMTYgQEANCiAJcmV0dXJuIG91dGNvbWU7DQogfQ0KIA0KKyNp ZmRlZiBXSVRIX0NZQ0xFX0dDDQorc3RhdGljIGludA0KK2luc3RhbmNlX3JlY3Vyc2UoUHlJ bnN0YW5jZU9iamVjdCAqbywgdmlzaXRwcm9jIHZpc2l0LCB2b2lkICpjbG9zdXJlKQ0KK3sN CisJaWYgKG8tPmluX2NsYXNzKSB2aXNpdCgoUHlPYmplY3QgKikoby0+aW5fY2xhc3MpLCBj bG9zdXJlKTsNCisJaWYgKG8tPmluX2RpY3QpIHZpc2l0KG8tPmluX2RpY3QsIGNsb3N1cmUp Ow0KKwlyZXR1cm4gMTsNCit9DQorI2VuZGlmIC8qIFdJVEhfQ1lDTEVfR0MgKi8NCisNCiBz dGF0aWMgUHlPYmplY3QgKmdldGl0ZW1zdHIsICpzZXRpdGVtc3RyLCAqZGVsaXRlbXN0ciwg KmxlbnN0cjsNCiANCiBzdGF0aWMgaW50DQpAQCAtMTQ2Myw3ICsxNTA4LDExIEBADQogCShn ZXRhdHRyb2Z1bmMpaW5zdGFuY2VfZ2V0YXR0ciwgLyp0cF9nZXRhdHRybyovDQogCShzZXRh dHRyb2Z1bmMpaW5zdGFuY2Vfc2V0YXR0ciwgLyp0cF9zZXRhdHRybyovDQogICAgICAgICAw LCAvKiB0cF9hc19idWZmZXIgKi8NCi0JUHlfVFBGTEFHU19ERUZBVUxULCAvKnRwX2ZsYWdz ICovDQorCVB5X1RQRkxBR1NfREVGQVVMVCB8IFB5X1RQRkxBR1NfSEFWRV9HQ0lORk8sIC8q dHBfZmxhZ3MqLw0KKwkwLAkJLyogdHBfZG9jICovDQorI2lmZGVmIFdJVEhfQ1lDTEVfR0MN CisJKHJlY3Vyc2Vwcm9jKWluc3RhbmNlX3JlY3Vyc2UsCS8qIHRwX3JlY3Vyc2UgKi8NCisj ZW5kaWYNCiB9Ow0KIA0KIA0KQEAgLTE0OTMsNyArMTU0Miw3IEBADQogCQlfUHlfTmV3UmVm ZXJlbmNlKChQeU9iamVjdCAqKWltKTsNCiAJfQ0KIAllbHNlIHsNCi0JCWltID0gUHlPYmpl Y3RfTkVXKFB5TWV0aG9kT2JqZWN0LCAmUHlNZXRob2RfVHlwZSk7DQorCQlpbSA9IFB5T2Jq ZWN0X05ldyhQeU1ldGhvZE9iamVjdCwgJlB5TWV0aG9kX1R5cGUpOw0KIAkJaWYgKGltID09 IE5VTEwpDQogCQkJcmV0dXJuIE5VTEw7DQogCX0NCi0tLSBQeXRob24tY3ZzL09iamVjdHMv ZGljdG9iamVjdC5jCVRodSBNYXIgMzAgMjI6MDI6NTIgMjAwMA0KKysrIFB5dGhvbi1nYy9P YmplY3RzL2RpY3RvYmplY3QuYwlTYXQgQXByICA4IDAyOjA5OjU5IDIwMDANCkBAIC0xMjEs NyArMTIxLDcgQEANCiAJCWlmIChkdW1teSA9PSBOVUxMKQ0KIAkJCXJldHVybiBOVUxMOw0K IAl9DQotCW1wID0gUHlPYmplY3RfTkVXKGRpY3RvYmplY3QsICZQeURpY3RfVHlwZSk7DQor CW1wID0gUHlPYmplY3RfTmV3KGRpY3RvYmplY3QsICZQeURpY3RfVHlwZSk7DQogCWlmICht cCA9PSBOVUxMKQ0KIAkJcmV0dXJuIE5VTEw7DQogCW1wLT5tYV9zaXplID0gMDsNCkBAIC0x MjksNiArMTI5LDkgQEANCiAJbXAtPm1hX3RhYmxlID0gTlVMTDsNCiAJbXAtPm1hX2ZpbGwg PSAwOw0KIAltcC0+bWFfdXNlZCA9IDA7DQorI2lmZGVmIFdJVEhfQ1lDTEVfR0MNCisJUHlH Q19JbnNlcnQoKFB5T2JqZWN0ICopbXApOw0KKyNlbmRpZg0KIAlyZXR1cm4gKFB5T2JqZWN0 ICopbXA7DQogfQ0KIA0KQEAgLTQ4MCw2ICs0ODMsOSBAQA0KIAlyZWdpc3RlciBpbnQgaTsN CiAJcmVnaXN0ZXIgZGljdGVudHJ5ICplcDsNCiAJUHlfVFJBU0hDQU5fU0FGRV9CRUdJTiht cCkNCisjaWZkZWYgV0lUSF9DWUNMRV9HQw0KKwlQeUdDX1JlbW92ZSgoUHlPYmplY3QgKilt cCk7DQorI2VuZGlmDQogCWZvciAoaSA9IDAsIGVwID0gbXAtPm1hX3RhYmxlOyBpIDwgbXAt Pm1hX3NpemU7IGkrKywgZXArKykgew0KIAkJaWYgKGVwLT5tZV9rZXkgIT0gTlVMTCkgew0K IAkJCVB5X0RFQ1JFRihlcC0+bWVfa2V5KTsNCkBAIC00ODksNyArNDk1LDcgQEANCiAJCX0N CiAJfQ0KIAlQeU1lbV9YREVMKG1wLT5tYV90YWJsZSk7DQotCVB5TWVtX0RFTChtcCk7DQor CVB5T2JqZWN0X0RlbCgoUHlPYmplY3QgKiltcCk7DQogCVB5X1RSQVNIQ0FOX1NBRkVfRU5E KG1wKQ0KIH0NCiANCkBAIC0xMDM2LDYgKzEwNDIsMzMgQEANCiAJcmV0dXJuIFB5X05vbmU7 DQogfQ0KIA0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDDQorc3RhdGljIGludA0KK2RpY3RfcmVj dXJzZShQeU9iamVjdCAqb3AsIHZpc2l0cHJvYyB2aXNpdCwgdm9pZCAqY2xvc3VyZSkNCit7 DQorCWludCBpID0gMDsNCisJUHlPYmplY3QgKnBrOw0KKwlQeU9iamVjdCAqcHY7DQorDQor CXdoaWxlIChQeURpY3RfTmV4dChvcCwgJmksICZwaywgJnB2KSkgew0KKwkJaWYgKCF2aXNp dChwaywgY2xvc3VyZSkpIHsNCisJCQlyZXR1cm4gMDsNCisJCX0NCisJCWlmICghdmlzaXQo cHYsIGNsb3N1cmUpKSB7DQorCQkJcmV0dXJuIDA7DQorCQl9DQorCX0NCisJcmV0dXJuIDE7 DQorfQ0KKw0KK3N0YXRpYyBpbnQNCitkaWN0X2djX2NsZWFyKFB5T2JqZWN0ICpvcCkNCit7 DQorCVB5RGljdF9DbGVhcihvcCk7DQorCXJldHVybiAwOw0KK30NCisjZW5kaWYgLyogV0lU SF9DWUNMRV9HQyAqLw0KKw0KIHN0YXRpYyBQeU1ldGhvZERlZiBtYXBwX21ldGhvZHNbXSA9 IHsNCiAJeyJoYXNfa2V5IiwJKFB5Q0Z1bmN0aW9uKWRpY3RfaGFzX2tleSwgICAgICBNRVRI X1ZBUkFSR1N9LA0KIAl7ImtleXMiLAkoUHlDRnVuY3Rpb24pZGljdF9rZXlzfSwNCkBAIC0x MDcxLDYgKzExMDQsMTggQEANCiAJMCwJCQkvKnRwX2FzX251bWJlciovDQogCTAsCQkJLyp0 cF9hc19zZXF1ZW5jZSovDQogCSZkaWN0X2FzX21hcHBpbmcsCS8qdHBfYXNfbWFwcGluZyov DQorI2lmZGVmIFdJVEhfQ1lDTEVfR0MNCisJMCwJCS8qIHRwX2hhc2ggKi8NCisJMCwJCS8q IHRwX2NhbGwgKi8NCisJMCwJCS8qIHRwX3N0ciAqLw0KKwkwLAkJLyogdHBfZ2V0YXR0cm8g Ki8NCisJMCwJCS8qIHRwX3NldGF0dHJvICovDQorCTAsCQkvKiB0cF9hc19idWZmZXIgKi8N CisJUHlfVFBGTEFHU19ERUZBVUxUIHwgUHlfVFBGTEFHU19IQVZFX0dDSU5GTywgLyp0cF9m bGFncyovDQorCTAsCQkvKiB0cF9kb2MgKi8NCisJKHJlY3Vyc2Vwcm9jKWRpY3RfcmVjdXJz ZSwJLyogdHBfcmVjdXJzZSAqLw0KKwkoaW5xdWlyeSlkaWN0X2djX2NsZWFyLAkJLyogdHBf Y2xlYXIgKi8NCisjZW5kaWYNCiB9Ow0KIA0KIC8qIEZvciBiYWNrd2FyZCBjb21wYXRpYmls aXR5IHdpdGggb2xkIGRpY3Rpb25hcnkgaW50ZXJmYWNlICovDQotLS0gUHl0aG9uLWN2cy9P YmplY3RzL2Z1bmNvYmplY3QuYwlUaHUgTWF5IDIxIDE4OjU1OjM0IDE5OTgNCisrKyBQeXRo b24tZ2MvT2JqZWN0cy9mdW5jb2JqZWN0LmMJU2F0IEFwciAgOCAwMjowOTo1MCAyMDAwDQpA QCAtNDAsNyArNDAsNyBAQA0KIAlQeU9iamVjdCAqY29kZTsNCiAJUHlPYmplY3QgKmdsb2Jh bHM7DQogew0KLQlQeUZ1bmN0aW9uT2JqZWN0ICpvcCA9IFB5T2JqZWN0X05FVyhQeUZ1bmN0 aW9uT2JqZWN0LA0KKwlQeUZ1bmN0aW9uT2JqZWN0ICpvcCA9IFB5T2JqZWN0X05ldyhQeUZ1 bmN0aW9uT2JqZWN0LA0KIAkJCQkJICAgICZQeUZ1bmN0aW9uX1R5cGUpOw0KIAlpZiAob3Ag IT0gTlVMTCkgew0KIAkJUHlPYmplY3QgKmRvYzsNCkBAIC02Myw2ICs2Myw5IEBADQogCQlQ eV9JTkNSRUYoZG9jKTsNCiAJCW9wLT5mdW5jX2RvYyA9IGRvYzsNCiAJfQ0KKyNpZmRlZiBX SVRIX0NZQ0xFX0dDDQorCVB5R0NfSW5zZXJ0KChQeU9iamVjdCAqKW9wKTsNCisjZW5kaWYN CiAJcmV0dXJuIChQeU9iamVjdCAqKW9wOw0KIH0NCiANCkBAIC0xODYsMTIgKzE4OSwxNSBA QA0KIGZ1bmNfZGVhbGxvYyhvcCkNCiAJUHlGdW5jdGlvbk9iamVjdCAqb3A7DQogew0KKyNp ZmRlZiBXSVRIX0NZQ0xFX0dDDQorCVB5R0NfUmVtb3ZlKChQeU9iamVjdCAqKW9wKTsNCisj ZW5kaWYNCiAJUHlfREVDUkVGKG9wLT5mdW5jX2NvZGUpOw0KIAlQeV9ERUNSRUYob3AtPmZ1 bmNfZ2xvYmFscyk7DQogCVB5X0RFQ1JFRihvcC0+ZnVuY19uYW1lKTsNCiAJUHlfWERFQ1JF RihvcC0+ZnVuY19kZWZhdWx0cyk7DQogCVB5X1hERUNSRUYob3AtPmZ1bmNfZG9jKTsNCi0J UHlNZW1fREVMKG9wKTsNCisJUHlPYmplY3RfRGVsKChQeU9iamVjdCAqKW9wKTsNCiB9DQog DQogc3RhdGljIFB5T2JqZWN0Kg0KQEAgLTIzOSw2ICsyNDUsMTkgQEANCiAJcmV0dXJuIGg7 DQogfQ0KIA0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDDQorc3RhdGljIGludA0KK2Z1bmNfcmVj dXJzZShQeUZ1bmN0aW9uT2JqZWN0ICpmLCB2aXNpdHByb2MgdmlzaXQsIHZvaWQgKmNsb3N1 cmUpDQorew0KKwlpZiAoZi0+ZnVuY19jb2RlKSB2aXNpdChmLT5mdW5jX2NvZGUsIGNsb3N1 cmUpOw0KKwlpZiAoZi0+ZnVuY19nbG9iYWxzKSB2aXNpdChmLT5mdW5jX2dsb2JhbHMsIGNs b3N1cmUpOw0KKwlpZiAoZi0+ZnVuY19kZWZhdWx0cykgdmlzaXQoZi0+ZnVuY19kZWZhdWx0 cywgY2xvc3VyZSk7DQorCWlmIChmLT5mdW5jX2RvYykgdmlzaXQoZi0+ZnVuY19kb2MsIGNs b3N1cmUpOw0KKwlpZiAoZi0+ZnVuY19uYW1lKSB2aXNpdChmLT5mdW5jX25hbWUsIGNsb3N1 cmUpOw0KKwlyZXR1cm4gMTsNCit9DQorI2VuZGlmIC8qIFdJVEhfQ1lDTEVfR0MgKi8NCisN CiBQeVR5cGVPYmplY3QgUHlGdW5jdGlvbl9UeXBlID0gew0KIAlQeU9iamVjdF9IRUFEX0lO SVQoJlB5VHlwZV9UeXBlKQ0KIAkwLA0KQEAgLTI1NSw0ICsyNzQsMTQgQEANCiAJMCwJCS8q dHBfYXNfc2VxdWVuY2UqLw0KIAkwLAkJLyp0cF9hc19tYXBwaW5nKi8NCiAJKGhhc2hmdW5j KWZ1bmNfaGFzaCwgLyp0cF9oYXNoKi8NCisjaWZkZWYgV0lUSF9DWUNMRV9HQw0KKwkwLAkJ Lyp0cF9jYWxsKi8NCisJMCwJCS8qdHBfc3RyKi8NCisJMCwJCS8qdHBfZ2V0YXR0cm8qLw0K KwkwLAkJLyp0cF9zZXRhdHRybyovDQorCTAsCQkvKiB0cF9hc19idWZmZXIgKi8NCisJUHlf VFBGTEFHU19ERUZBVUxUIHwgUHlfVFBGTEFHU19IQVZFX0dDSU5GTywgLyp0cF9mbGFncyov DQorCTAsCQkvKiB0cF9kb2MgKi8NCisJKHJlY3Vyc2Vwcm9jKWZ1bmNfcmVjdXJzZSwJLyog dHBfcmVjdXJzZSAqLw0KKyNlbmRpZg0KIH07DQotLS0gUHl0aG9uLWN2cy9PYmplY3RzL2xp c3RvYmplY3QuYwlGcmkgTWFyIDI0IDIyOjMyOjMwIDIwMDANCisrKyBQeXRob24tZ2MvT2Jq ZWN0cy9saXN0b2JqZWN0LmMJU2F0IEFwciAgOCAwMjowMjozNiAyMDAwDQpAQCAtNjEsMzQg KzYxLDM4IEBADQogCWludCBpOw0KIAlQeUxpc3RPYmplY3QgKm9wOw0KIAlzaXplX3QgbmJ5 dGVzOw0KKwlQeU9iamVjdCAqKml0ZW07DQorDQogCWlmIChzaXplIDwgMCkgew0KIAkJUHlF cnJfQmFkSW50ZXJuYWxDYWxsKCk7DQogCQlyZXR1cm4gTlVMTDsNCiAJfQ0KLQluYnl0ZXMg PSBzaXplICogc2l6ZW9mKFB5T2JqZWN0ICopOw0KLQkvKiBDaGVjayBmb3Igb3ZlcmZsb3cg Ki8NCi0JaWYgKG5ieXRlcyAvIHNpemVvZihQeU9iamVjdCAqKSAhPSAoc2l6ZV90KXNpemUp IHsNCi0JCXJldHVybiBQeUVycl9Ob01lbW9yeSgpOw0KLQl9DQotCW9wID0gKFB5TGlzdE9i amVjdCAqKSBtYWxsb2Moc2l6ZW9mKFB5TGlzdE9iamVjdCkpOw0KLQlpZiAob3AgPT0gTlVM TCkgew0KLQkJcmV0dXJuIFB5RXJyX05vTWVtb3J5KCk7DQotCX0NCi0JaWYgKHNpemUgPD0g MCkgew0KLQkJb3AtPm9iX2l0ZW0gPSBOVUxMOw0KLQl9DQorCWlmIChzaXplID09IDApDQor CQlpdGVtID0gTlVMTDsNCiAJZWxzZSB7DQotCQlvcC0+b2JfaXRlbSA9IChQeU9iamVjdCAq KikgbWFsbG9jKG5ieXRlcyk7DQotCQlpZiAob3AtPm9iX2l0ZW0gPT0gTlVMTCkgew0KLQkJ CWZyZWUoKEFOWSAqKW9wKTsNCisJCW5ieXRlcyA9IHNpemUgKiBzaXplb2YoUHlPYmplY3Qg Kik7DQorCQkvKiBDaGVjayBmb3Igb3ZlcmZsb3cgKi8NCisJCWlmIChuYnl0ZXMgLyBzaXpl b2YoUHlPYmplY3QgKikgIT0gKHNpemVfdClzaXplKSB7DQogCQkJcmV0dXJuIFB5RXJyX05v TWVtb3J5KCk7DQogCQl9DQorCQlpdGVtID0gKFB5T2JqZWN0ICoqKSBtYWxsb2MobmJ5dGVz KTsNCisJCWlmIChpdGVtID09IE5VTEwpDQorCQkJcmV0dXJuIFB5RXJyX05vTWVtb3J5KCk7 DQorCX0NCisJb3AgPSBQeU9iamVjdF9OZXcoUHlMaXN0T2JqZWN0LCAmUHlMaXN0X1R5cGUp Ow0KKwlpZiAob3AgPT0gTlVMTCkgew0KKwkJaWYgKGl0ZW0gIT0gTlVMTCkNCisJCQlmcmVl KChBTlkgKilpdGVtKTsNCisJCXJldHVybiBQeUVycl9Ob01lbW9yeSgpOw0KIAl9DQotCW9w LT5vYl90eXBlID0gJlB5TGlzdF9UeXBlOw0KIAlvcC0+b2Jfc2l6ZSA9IHNpemU7DQorCW9w LT5vYl9pdGVtID0gaXRlbTsNCiAJZm9yIChpID0gMDsgaSA8IHNpemU7IGkrKykNCiAJCW9w LT5vYl9pdGVtW2ldID0gTlVMTDsNCiAJX1B5X05ld1JlZmVyZW5jZSgoUHlPYmplY3QgKilv cCk7DQorI2lmZGVmIFdJVEhfQ1lDTEVfR0MNCisJUHlHQ19JbnNlcnQoKFB5T2JqZWN0ICop b3ApOw0KKyNlbmRpZg0KIAlyZXR1cm4gKFB5T2JqZWN0ICopIG9wOw0KIH0NCiANCkBAIC0y MTYsNiArMjIwLDkgQEANCiB7DQogCWludCBpOw0KIAlQeV9UUkFTSENBTl9TQUZFX0JFR0lO KG9wKQ0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDDQorCVB5R0NfUmVtb3ZlKChQeU9iamVjdCAq KW9wKTsNCisjZW5kaWYNCiAJaWYgKG9wLT5vYl9pdGVtICE9IE5VTEwpIHsNCiAJCS8qIERv IGl0IGJhY2t3YXJkcywgZm9yIENocmlzdGlhbiBUaXNtZXIuDQogCQkgICBUaGVyZSdzIGEg c2ltcGxlIHRlc3QgY2FzZSB3aGVyZSBzb21laG93IHRoaXMgcmVkdWNlcw0KQEAgLTIyNyw3 ICsyMzQsNyBAQA0KIAkJfQ0KIAkJZnJlZSgoQU5ZICopb3AtPm9iX2l0ZW0pOw0KIAl9DQot CWZyZWUoKEFOWSAqKW9wKTsNCisJUHlPYmplY3RfRGVsKChQeU9iamVjdCAqKW9wKTsNCiAJ UHlfVFJBU0hDQU5fU0FGRV9FTkQob3ApDQogfQ0KIA0KQEAgLTEzOTksNiArMTQwNiwyOSBA QA0KIAlyZXR1cm4gTlVMTDsNCiB9DQogDQorI2lmZGVmIFdJVEhfQ1lDTEVfR0MNCitzdGF0 aWMgaW50DQorbGlzdF9yZWN1cnNlKFB5TGlzdE9iamVjdCAqbywgdmlzaXRwcm9jIHZpc2l0 LCB2b2lkICpjbG9zdXJlKQ0KK3sNCisJaW50IGk7DQorCVB5T2JqZWN0ICp4Ow0KKw0KKwlm b3IgKGkgPSBvLT5vYl9zaXplOyAtLWkgPj0gMDsgKSB7DQorCQl4ID0gby0+b2JfaXRlbVtp XTsNCisJCWlmICh4ICE9IE5VTEwgJiYgIXZpc2l0KHgsIGNsb3N1cmUpKQ0KKwkJCXJldHVy biAwOw0KKwl9DQorCXJldHVybiAxOw0KK30NCisNCitzdGF0aWMgaW50DQorbGlzdF9jbGVh cihQeUxpc3RPYmplY3QgKmxwKQ0KK3sNCisJKHZvaWQpIFB5TGlzdF9TZXRTbGljZSgoUHlP YmplY3QgKilscCwgMCwgbHAtPm9iX3NpemUsIDApOw0KKwlyZXR1cm4gMDsNCit9DQorI2Vu ZGlmIC8qIFdJVEhfQ1lDTEVfR0MgKi8NCisNCiBzdGF0aWMgY2hhciBhcHBlbmRfZG9jW10g PQ0KICJMLmFwcGVuZChvYmplY3QpIC0tIGFwcGVuZCBvYmplY3QgdG8gZW5kIjsNCiBzdGF0 aWMgY2hhciBleHRlbmRfZG9jW10gPQ0KQEAgLTE0NjQsNiArMTQ5NCwxOCBAQA0KIAkwLAkJ Lyp0cF9hc19udW1iZXIqLw0KIAkmbGlzdF9hc19zZXF1ZW5jZSwJLyp0cF9hc19zZXF1ZW5j ZSovDQogCTAsCQkvKnRwX2FzX21hcHBpbmcqLw0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDDQor CTAsCQkvKiB0cF9oYXNoICovDQorCTAsCQkvKiB0cF9jYWxsICovDQorCTAsCQkvKiB0cF9z dHIgKi8NCisJMCwJCS8qIHRwX2dldGF0dHJvICovDQorCTAsCQkvKiB0cF9zZXRhdHRybyAq Lw0KKwkwLAkJLyogdHBfYXNfYnVmZmVyICovDQorCVB5X1RQRkxBR1NfREVGQVVMVCB8IFB5 X1RQRkxBR1NfSEFWRV9HQ0lORk8sCS8qIHRwX2ZsYWdzICovDQorCTAsCQkvKiB0cF9kb2Mg Ki8NCisJKHJlY3Vyc2Vwcm9jKWxpc3RfcmVjdXJzZSwJLyogdHBfcmVjdXJzZSAqLw0KKwko aW5xdWlyeSlsaXN0X2NsZWFyLAkvKiB0cF9jbGVhciAqLw0KKyNlbmRpZg0KIH07DQogDQog DQpAQCAtMTUzMiw1ICsxNTc0LDE2IEBADQogCTAsCQkvKnRwX2FzX251bWJlciovDQogCSZp bW11dGFibGVfbGlzdF9hc19zZXF1ZW5jZSwJLyp0cF9hc19zZXF1ZW5jZSovDQogCTAsCQkv KnRwX2FzX21hcHBpbmcqLw0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDDQorCTAsCQkvKiB0cF9o YXNoICovDQorCTAsCQkvKiB0cF9jYWxsICovDQorCTAsCQkvKiB0cF9zdHIgKi8NCisJMCwJ CS8qIHRwX2dldGF0dHJvICovDQorCTAsCQkvKiB0cF9zZXRhdHRybyAqLw0KKwkwLAkJLyog dHBfYXNfYnVmZmVyICovDQorCVB5X1RQRkxBR1NfREVGQVVMVCwJLyogdHBfZmxhZ3MgKi8N CisJMCwJCS8qIHRwX2RvYyAqLw0KKwkocmVjdXJzZXByb2MpbGlzdF9yZWN1cnNlLAkvKiB0 cF9yZWN1cnNlICovDQorI2VuZGlmDQogfTsNCiANCi0tLSBQeXRob24tY3ZzL09iamVjdHMv b2JqZWN0LmMJVHVlIE1hciAyOCAwODoxMTowOSAyMDAwDQorKysgUHl0aG9uLWdjL09iamVj dHMvb2JqZWN0LmMJU2F0IEFwciAgOCAwMjoxMDowNiAyMDAwDQpAQCAtMTA3LDIwICsxMDcs MTIgQEANCiB9DQogI2VuZGlmDQogDQotI2lmbmRlZiBNU19DT1JFRExMDQotUHlPYmplY3Qg Kg0KLV9QeU9iamVjdF9OZXcodHApDQotCVB5VHlwZU9iamVjdCAqdHA7DQotI2Vsc2UNCisN CiBQeU9iamVjdCAqDQotX1B5T2JqZWN0X05ldyh0cCxvcCkNCitfUHlPYmplY3RfRnJvbVR5 cGUodHAsb3ApDQogCVB5VHlwZU9iamVjdCAqdHA7DQogCVB5T2JqZWN0ICpvcDsNCi0jZW5k aWYNCiB7DQotI2lmbmRlZiBNU19DT1JFRExMDQotCVB5T2JqZWN0ICpvcCA9IChQeU9iamVj dCAqKSBtYWxsb2ModHAtPnRwX2Jhc2ljc2l6ZSk7DQotI2VuZGlmDQogCWlmIChvcCA9PSBO VUxMKQ0KIAkJcmV0dXJuIFB5RXJyX05vTWVtb3J5KCk7DQogCW9wLT5vYl90eXBlID0gdHA7 DQpAQCAtMTI4LDI5ICsxMjAsNzggQEANCiAJcmV0dXJuIG9wOw0KIH0NCiANCi0jaWZuZGVm IE1TX0NPUkVETEwNCi1QeVZhck9iamVjdCAqDQotX1B5T2JqZWN0X05ld1Zhcih0cCwgc2l6 ZSkNCi0JUHlUeXBlT2JqZWN0ICp0cDsNCi0JaW50IHNpemU7DQotI2Vsc2UNCiBQeVZhck9i amVjdCAqDQotX1B5T2JqZWN0X05ld1Zhcih0cCwgc2l6ZSwgb3ApDQorX1B5T2JqZWN0X1Zh ckZyb21UeXBlKHRwLCBzaXplLCBvcCkNCiAJUHlUeXBlT2JqZWN0ICp0cDsNCiAJaW50IHNp emU7DQogCVB5VmFyT2JqZWN0ICpvcDsNCi0jZW5kaWYNCiB7DQotI2lmbmRlZiBNU19DT1JF RExMDQotCVB5VmFyT2JqZWN0ICpvcCA9IChQeVZhck9iamVjdCAqKQ0KLQkJbWFsbG9jKHRw LT50cF9iYXNpY3NpemUgKyBzaXplICogdHAtPnRwX2l0ZW1zaXplKTsNCi0jZW5kaWYNCiAJ aWYgKG9wID09IE5VTEwpDQogCQlyZXR1cm4gKFB5VmFyT2JqZWN0ICopUHlFcnJfTm9NZW1v cnkoKTsNCiAJb3AtPm9iX3R5cGUgPSB0cDsNCiAJb3AtPm9iX3NpemUgPSBzaXplOw0KIAlf UHlfTmV3UmVmZXJlbmNlKChQeU9iamVjdCAqKW9wKTsNCiAJcmV0dXJuIG9wOw0KK30NCisN CitQeU9iamVjdCAqDQorX1B5T2JqZWN0X05ldyh0cCkNCisJUHlUeXBlT2JqZWN0ICp0cDsN Cit7DQorCVB5T2JqZWN0ICpvcDsNCisjaWZkZWYgV0lUSF9DWUNMRV9HQw0KKwlpZiAoUFlf VFlQRUlTR0ModHApKSB7DQorCQlQeUdDSW5mbyAqZzsNCisJCWcgPSAoUHlHQ0luZm8gKikg bWFsbG9jKHNpemVvZigqZykgKyB0cC0+dHBfYmFzaWNzaXplKTsNCisJCWlmIChnID09IE5V TEwpIHsNCisJCQlvcCA9IE5VTEw7DQorCQl9IGVsc2Ugew0KKwkJCW9wID0gUFlfR0NPQkoo Zyk7DQorCQl9DQorCX0gZWxzZQ0KKyNlbmRpZiAvKiBXSVRIX0NZQ0xFX0dDICovDQorCXsN CisJCW9wID0gKFB5T2JqZWN0ICopIG1hbGxvYyh0cC0+dHBfYmFzaWNzaXplKTsNCisJfQ0K KwlyZXR1cm4gX1B5T2JqZWN0X0Zyb21UeXBlKHRwLCBvcCk7DQorfQ0KKw0KK1B5VmFyT2Jq ZWN0ICoNCitfUHlPYmplY3RfTmV3VmFyKHRwLCBzaXplKQ0KKwlQeVR5cGVPYmplY3QgKnRw Ow0KKwlpbnQgc2l6ZTsNCit7DQorCVB5VmFyT2JqZWN0ICpvcDsNCisjaWZkZWYgV0lUSF9D WUNMRV9HQw0KKwlpZiAoUFlfVFlQRUlTR0ModHApKSB7DQorCQlQeUdDSW5mbyAqZzsNCisJ CWcgPSAoUHlHQ0luZm8gKikgbWFsbG9jKHNpemVvZigqZykgKyANCisJCQkJCXRwLT50cF9i YXNpY3NpemUgKw0KKwkJCQkJc2l6ZSAqIHRwLT50cF9pdGVtc2l6ZSk7DQorCQlpZiAoZyA9 PSBOVUxMKSB7DQorCQkJb3AgPSBOVUxMOw0KKwkJfSBlbHNlIHsNCisJCQlvcCA9IChQeVZh ck9iamVjdCAqKVBZX0dDT0JKKGcpOw0KKwkJfQ0KKwl9IGVsc2UNCisjZW5kaWYgLyogV0lU SF9DWUNMRV9HQyAqLw0KKwl7DQorCQlvcCA9IChQeVZhck9iamVjdCAqKQ0KKwkJCW1hbGxv Yyh0cC0+dHBfYmFzaWNzaXplICsgc2l6ZSAqIHRwLT50cF9pdGVtc2l6ZSk7DQorCX0NCisJ cmV0dXJuIF9QeU9iamVjdF9WYXJGcm9tVHlwZSh0cCwgc2l6ZSwgb3ApOw0KK30NCisNCit2 b2lkDQorUHlPYmplY3RfRGVsKG9wKQ0KKwlQeU9iamVjdCAqb3A7DQorew0KKyNpZmRlZiBX SVRIX0NZQ0xFX0dDDQorCWlmIChQWV9JU0dDKG9wKSkgew0KKwkJb3AgPSAoUHlPYmplY3Qg KilQWV9HQ0lORk9fVU5TQUZFKG9wKTsNCisJfQ0KKyNlbmRpZg0KKwlmcmVlKG9wKTsNCiB9 DQogDQogaW50DQotLS0gUHl0aG9uLWN2cy9PYmplY3RzL3R1cGxlb2JqZWN0LmMJRnJpIE1h ciAyNCAyMjozMjozMCAyMDAwDQorKysgUHl0aG9uLWdjL09iamVjdHMvdHVwbGVvYmplY3Qu YwlNb24gQXByIDI0IDIwOjQ4OjA1IDIwMDANCkBAIC05NywxMiArOTcsMTAgQEANCiAJCQly ZXR1cm4gUHlFcnJfTm9NZW1vcnkoKTsNCiAJCX0NCiAJCTsNCi0JCW9wID0gKFB5VHVwbGVP YmplY3QgKikgbWFsbG9jKG5ieXRlcyk7DQorCQlvcCA9IFB5T2JqZWN0X05ld1ZhcihQeVR1 cGxlT2JqZWN0LCAmUHlUdXBsZV9UeXBlLCBzaXplKTsNCiAJCWlmIChvcCA9PSBOVUxMKQ0K IAkJCXJldHVybiBQeUVycl9Ob01lbW9yeSgpOw0KIA0KLQkJb3AtPm9iX3R5cGUgPSAmUHlU dXBsZV9UeXBlOw0KLQkJb3AtPm9iX3NpemUgPSBzaXplOw0KIAl9DQogCWZvciAoaSA9IDA7 IGkgPCBzaXplOyBpKyspDQogCQlvcC0+b2JfaXRlbVtpXSA9IE5VTEw7DQpAQCAtMTEwLDEw ICsxMDgsMTIgQEANCiAjaWYgTUFYU0FWRVNJWkUgPiAwDQogCWlmIChzaXplID09IDApIHsN CiAJCWZyZWVfdHVwbGVzWzBdID0gb3A7DQotCQkrK251bV9mcmVlX3R1cGxlc1swXTsNCiAJ CVB5X0lOQ1JFRihvcCk7CS8qIGV4dHJhIElOQ1JFRiBzbyB0aGF0IHRoaXMgaXMgbmV2ZXIg ZnJlZWQgKi8NCiAJfQ0KICNlbmRpZg0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDDQorCVB5R0Nf SW5zZXJ0KChQeU9iamVjdCAqKW9wKTsNCisjZW5kaWYNCiAJcmV0dXJuIChQeU9iamVjdCAq KSBvcDsNCiB9DQogDQpAQCAtMTgwLDYgKzE4MCw5IEBADQogCXJlZ2lzdGVyIGludCBpOw0K IAlyZWdpc3RlciBpbnQgbGVuID0gIG9wLT5vYl9zaXplOw0KIAlQeV9UUkFTSENBTl9TQUZF X0JFR0lOKG9wKQ0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDDQorCVB5R0NfUmVtb3ZlKChQeU9i amVjdCAqKW9wKTsNCisjZW5kaWYNCiAJaWYgKGxlbiA+IDApIHsNCiAJCWkgPSBsZW47DQog CQl3aGlsZSAoLS1pID49IDApDQpAQCAtMTkzLDcgKzE5Niw3IEBADQogCQl9DQogI2VuZGlm DQogCX0NCi0JZnJlZSgoQU5ZICopb3ApOw0KKwlQeU9iamVjdF9EZWwoKFB5T2JqZWN0ICop b3ApOw0KIGRvbmU6DQogCVB5X1RSQVNIQ0FOX1NBRkVfRU5EKG9wKQ0KIH0NCkBAIC00MDEs NiArNDA0LDIyIEBADQogCXJldHVybiAoUHlPYmplY3QgKikgbnA7DQogfQ0KIA0KKyNpZmRl ZiBXSVRIX0NZQ0xFX0dDDQorc3RhdGljIGludA0KK3R1cGxlcmVjdXJzZShQeVR1cGxlT2Jq ZWN0ICpvLCB2aXNpdHByb2MgdmlzaXQsIHZvaWQgKmNsb3N1cmUpDQorew0KKwlpbnQgaTsN CisJUHlPYmplY3QgKng7DQorDQorCWZvciAoaSA9IG8tPm9iX3NpemU7IC0taSA+PSAwOyAp IHsNCisJCXggPSBvLT5vYl9pdGVtW2ldOw0KKwkJaWYgKHggIT0gTlVMTCAmJiAhdmlzaXQo eCwgY2xvc3VyZSkpDQorCQkJcmV0dXJuIDA7DQorCX0NCisJcmV0dXJuIDE7DQorfQ0KKyNl bmRpZiAvKiBXSVRIX0NZQ0xFX0dDICovDQorDQogc3RhdGljIFB5U2VxdWVuY2VNZXRob2Rz IHR1cGxlX2FzX3NlcXVlbmNlID0gew0KIAkoaW5xdWlyeSl0dXBsZWxlbmd0aCwgLypzcV9s ZW5ndGgqLw0KIAkoYmluYXJ5ZnVuYyl0dXBsZWNvbmNhdCwgLypzcV9jb25jYXQqLw0KQEAg LTQyNyw2ICs0NDYsMTYgQEANCiAJJnR1cGxlX2FzX3NlcXVlbmNlLAkvKnRwX2FzX3NlcXVl bmNlKi8NCiAJMCwJCS8qdHBfYXNfbWFwcGluZyovDQogCShoYXNoZnVuYyl0dXBsZWhhc2gs IC8qdHBfaGFzaCovDQorI2lmZGVmIFdJVEhfQ1lDTEVfR0MNCisJMCwJCS8qIHRwX2NhbGwg Ki8NCisJMCwJCS8qIHRwX3N0ciAqLw0KKwkwLAkJLyogdHBfZ2V0YXR0cm8gKi8NCisJMCwJ CS8qIHRwX3NldGF0dHJvICovDQorCTAsCQkvKiB0cF9hc19idWZmZXIgKi8NCisJUHlfVFBG TEFHU19ERUZBVUxUIHwgUHlfVFBGTEFHU19IQVZFX0dDSU5GTywJLyogdHBfZmxhZ3MgKi8N CisJMCwJCS8qIHRwX2RvYyAqLw0KKwkocmVjdXJzZXByb2MpdHVwbGVyZWN1cnNlLAkvKiB0 cF9yZWN1cnNlICovDQorI2VuZGlmDQogfTsNCiANCiAvKiBUaGUgZm9sbG93aW5nIGZ1bmN0 aW9uIGJyZWFrcyB0aGUgbm90aW9uIHRoYXQgdHVwbGVzIGFyZSBpbW11dGFibGU6DQpAQCAt NDQ5LDYgKzQ3OCw5IEBADQogCWludCBpOw0KIAlpbnQgc2l6ZWRpZmY7DQogDQorI2lmZGVm IFdJVEhfQ1lDTEVfR0MNCisJUHlHQ0luZm8gKmcgPSBQWV9HQ0lORk8oKnB2KTsgDQorI2Vu ZGlmDQogCXYgPSAoUHlUdXBsZU9iamVjdCAqKSAqcHY7DQogCWlmICh2ID09IE5VTEwgfHwg IVB5VHVwbGVfQ2hlY2sodikgfHwgdi0+b2JfcmVmY250ICE9IDEpIHsNCiAJCSpwdiA9IDA7 DQpAQCAtNDc5LDcgKzUxMSw2IEBADQogCX0NCiAjaWYgTUFYU0FWRVNJWkUgPiAwDQogCWlm IChuZXdzaXplID09IDAgJiYgZnJlZV90dXBsZXNbMF0pIHsNCi0JCW51bV9mcmVlX3R1cGxl c1swXS0tOw0KIAkJc3YgPSBmcmVlX3R1cGxlc1swXTsNCiAJCXN2LT5vYl9zaXplID0gMDsN CiAJCVB5X0lOQ1JFRihzdik7DQpAQCAtNTExLDkgKzU0MiwyMiBAQA0KIAl9IGVsc2UgDQog I2VuZGlmCQkNCiAJew0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDDQorCQlQeUdDX1JlbW92ZSh2 KTsNCisNCisJCWcgPSAoUHlHQ0luZm8gKikgcmVhbGxvYygoY2hhciAqKWcsIHNpemVvZigq ZykgKyANCisJCQkJc2l6ZW9mKFB5VHVwbGVPYmplY3QpICsgDQorCQkJCW5ld3NpemUgKiBz aXplb2YoUHlPYmplY3QgKikpOw0KKwkJaWYgKGcgPT0gTlVMTCkgew0KKwkJCXN2ID09IE5V TEw7DQorCQl9IGVsc2Ugew0KKwkJCXN2ID0gKFB5VHVwbGVPYmplY3QgKikgUFlfR0NPQkoo Zyk7DQorCQl9DQorI2Vsc2UNCiAJCXN2ID0gKFB5VHVwbGVPYmplY3QgKikNCiAJCQlyZWFs bG9jKChjaGFyICopdiwNCiAJCQkJc2l6ZW9mKFB5VHVwbGVPYmplY3QpICsgbmV3c2l6ZSAq IHNpemVvZihQeU9iamVjdCAqKSk7DQorI2VuZGlmDQogCQkqcHYgPSAoUHlPYmplY3QgKikg c3Y7DQogCQlpZiAoc3YgPT0gTlVMTCkgew0KIAkJCVB5TWVtX0RFTCh2KTsNCkBAIC01MjIs NiArNTY2LDkgQEANCiAJCX0NCiAJfQ0KIAlfUHlfTmV3UmVmZXJlbmNlKChQeU9iamVjdCAq KXN2KTsNCisjaWZkZWYgV0lUSF9DWUNMRV9HQw0KKwlQeUdDX0luc2VydCgoUHlPYmplY3Qg Kilzdik7DQorI2VuZGlmDQogCWZvciAoaSA9IHN2LT5vYl9zaXplOyBpIDwgbmV3c2l6ZTsg aSsrKQ0KIAkJc3YtPm9iX2l0ZW1baV0gPSBOVUxMOw0KIAlpZiAobGFzdF9pc19zdGlja3kg JiYgc2l6ZWRpZmYgPiAwKSB7DQpAQCAtNTUxLDcgKzU5OCw3IEBADQogCQl3aGlsZSAocCkg ew0KIAkJCXEgPSBwOw0KIAkJCXAgPSAoUHlUdXBsZU9iamVjdCAqKShwLT5vYl9pdGVtWzBd KTsNCi0JCQlQeU1lbV9ERUwocSk7DQorCQkJUHlPYmplY3RfRGVsKChQeU9iamVjdCAqKXEp Ow0KIAkJfQ0KIAl9DQogI2VuZGlmDQotLS0gUHl0aG9uLWN2cy9QQy9jb25maWcuYwlGcmkg QXByICA3IDE1OjI3OjA0IDIwMDANCisrKyBQeXRob24tZ2MvUEMvY29uZmlnLmMJU2F0IEFw ciAgOCAwMzoxMjo1OCAyMDAwDQpAQCAtNDEsNiArNDEsOSBAQA0KIGV4dGVybiB2b2lkIGlu aXRiaW5hc2NpaSgpOw0KIGV4dGVybiB2b2lkIGluaXRjbWF0aCgpOw0KIGV4dGVybiB2b2lk IGluaXRlcnJubygpOw0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDDQorZXh0ZXJuIHZvaWQgaW5p dGdjKCk7DQorI2VuZGlmDQogZXh0ZXJuIHZvaWQgaW5pdGltYWdlb3AoKTsNCiBleHRlcm4g dm9pZCBpbml0bWF0aCgpOw0KIGV4dGVybiB2b2lkIGluaXRtZDUoKTsNCkBAIC04MCw2ICs4 Myw5IEBADQogICAgICAgICB7ImJpbmFzY2lpIiwgaW5pdGJpbmFzY2lpfSwNCiAgICAgICAg IHsiY21hdGgiLCBpbml0Y21hdGh9LA0KICAgICAgICAgeyJlcnJubyIsIGluaXRlcnJub30s DQorI2lmZGVmIFdJVEhfQ1lDTEVfR0MNCisgICAgICAgIHsiZ2MiLCBpbml0Z2N9LA0KKyNl bmRpZg0KICAgICAgICAgeyJpbWFnZW9wIiwgaW5pdGltYWdlb3B9LA0KICAgICAgICAgeyJt YXRoIiwgaW5pdG1hdGh9LA0KICAgICAgICAgeyJtZDUiLCBpbml0bWQ1fSwNCi0tLSBQeXRo b24tY3ZzL1BDL2NvbmZpZy5oCVRodSBNYXIgMzAgMjI6MDI6NTMgMjAwMA0KKysrIFB5dGhv bi1nYy9QQy9jb25maWcuaAlTYXQgQXByICA4IDAyOjI0OjAwIDIwMDANCkBAIC0zODEsNiAr MzgxLDkgQEANCiAvKiBEZWZpbmUgaWYgeW91IHdhbnQgdG8gdXNlIHRoZSBHTlUgcmVhZGxp bmUgbGlicmFyeSAqLw0KIC8qICNkZWZpbmUgV0lUSF9SRUFETElORSAxICovDQogDQorLyog RGVmaW5lIGlmIHlvdSB3YW50IGN5Y2xlIGdhcmJhZ2UgY29sbGVjdGlvbiAqLw0KKyNkZWZp bmUgV0lUSF9DWUNMRV9HQyAxDQorDQogLyogRGVmaW5lIGlmIHlvdSBoYXZlIGNsb2NrLiAg Ki8NCiAvKiAjZGVmaW5lIEhBVkVfQ0xPQ0sgKi8NCiANCi0tLSBQeXRob24tY3ZzL01ha2Vm aWxlLmluCVN1biBBcHIgIDIgMjI6NTY6MjUgMjAwMA0KKysrIFB5dGhvbi1nYy9NYWtlZmls ZS5pbglTYXQgQXByICA4IDAxOjM4OjI1IDIwMDANCkBAIC00MDEsNyArNDAxLDcgQEANCiAJ CSQoSU5TVEFMTF9EQVRBKSBNb2R1bGVzL01ha2VmaWxlICQoTElCUEwpL01ha2VmaWxlDQog CQkkKElOU1RBTExfREFUQSkgTW9kdWxlcy9TZXR1cCAkKExJQlBMKS9TZXR1cA0KIAkJJChJ TlNUQUxMX0RBVEEpIE1vZHVsZXMvU2V0dXAubG9jYWwgJChMSUJQTCkvU2V0dXAubG9jYWwN Ci0JCSQoSU5TVEFMTF9EQVRBKSBNb2R1bGVzL1NldHVwLnRocmVhZCAkKExJQlBMKS9TZXR1 cC50aHJlYWQNCisJCSQoSU5TVEFMTF9EQVRBKSBNb2R1bGVzL1NldHVwLmF1dG8gJChMSUJQ TCkvU2V0dXAuYXV0bw0KIAkJJChJTlNUQUxMX1BST0dSQU0pICQoc3JjZGlyKS9Nb2R1bGVz L21ha2VzZXR1cCAkKExJQlBMKS9tYWtlc2V0dXANCiAJCSQoSU5TVEFMTF9QUk9HUkFNKSAk KHNyY2RpcikvaW5zdGFsbC1zaCAkKExJQlBMKS9pbnN0YWxsLXNoDQogCQkkKElOU1RBTExf REFUQSkgJChzcmNkaXIpL01pc2MvTWFrZWZpbGUucHJlLmluICQoTElCUEwpL01ha2VmaWxl LnByZS5pbg0KLS0tIFB5dGhvbi1jdnMvY29uZmlnLmguaW4JRnJpIE1hciAyNCAyMjozMTo0 MiAyMDAwDQorKysgUHl0aG9uLWdjL2NvbmZpZy5oLmluCVNhdCBBcHIgIDggMDE6Mzg6MjUg MjAwMA0KQEAgLTIwNCw2ICsyMDQsOSBAQA0KICAgIChzaGFyZWQgbGlicmFyeSBwbHVzIGFj Y2Vzc29yeSBmaWxlcykuICovDQogI3VuZGVmIFdJVEhfTkVYVF9GUkFNRVdPUksNCiANCisv KiBEZWZpbmUgaWYgeW91IHdhbnQgY3ljbGUgZ2FyYmFnZSBjb2xsZWN0aW9uICovDQorI3Vu ZGVmIFdJVEhfQ1lDTEVfR0MNCisNCiAvKiBUaGUgbnVtYmVyIG9mIGJ5dGVzIGluIGFuIG9m Zl90LiAqLw0KICN1bmRlZiBTSVpFT0ZfT0ZGX1QNCiANCi0tLSBQeXRob24tY3ZzL2NvbmZp Z3VyZS5pbglTdW4gQXByICAyIDIyOjU2OjI1IDIwMDANCisrKyBQeXRob24tZ2MvY29uZmln dXJlLmluCVNhdCBBcHIgIDggMDE6Mzg6MjUgMjAwMA0KQEAgLTEwNjksMTAgKzEwNjksMjEg QEANCiBmaV0sDQogW0FDX01TR19SRVNVTFQobm8pXSkNCiANCitBQ19TVUJTVChVU0VfR0Nf TU9EVUxFKQ0KK1VTRV9HQ19NT0RVTEU9IiMiDQorDQorQUNfTVNHX0NIRUNLSU5HKGZvciAt LXdpdGgtY3ljbGUtZ2MpDQorQUNfQVJHX1dJVEgoY3ljbGUtZ2MsIFstLXdpdGgtY3ljbGUt Z2MgICAgICAgICAgIGVuYWJsZSBnYXJiYWdlIGNvbGxlY3Rpb25dLCBbDQorQUNfTVNHX1JF U1VMVCgkd2l0aHZhbCkNCitBQ19ERUZJTkUoV0lUSF9DWUNMRV9HQykNCitVU0VfR0NfTU9E VUxFPQ0KK10sDQorQUNfTVNHX1JFU1VMVChubykpDQorDQogIyBnZW5lcmF0ZSBvdXRwdXQg ZmlsZXMNCiBBQ19PVVRQVVQoTWFrZWZpbGUgXA0KICBPYmplY3RzL01ha2VmaWxlIFwNCiAg UGFyc2VyL01ha2VmaWxlIFwNCiAgUHl0aG9uL01ha2VmaWxlIFwNCiAgTW9kdWxlcy9NYWtl ZmlsZS5wcmUgXA0KLSBNb2R1bGVzL1NldHVwLnRocmVhZCkNCisgTW9kdWxlcy9TZXR1cC5h dXRvKQ0KLS0tIFB5dGhvbi1jdnMvTWlzYy9NYWtlZmlsZS5wcmUuaW4JV2VkIERlYyAgOSAx MDowNTozMyAxOTk4DQorKysgUHl0aG9uLWdjL01pc2MvTWFrZWZpbGUucHJlLmluCVNhdCBB cHIgIDggMDE6Mzg6MjUgMjAwMA0KQEAgLTE2OCw3ICsxNjgsNyBAQA0KIE1BS0VGSUxFPQkk KExJQlBMKS9NYWtlZmlsZQ0KIENPTkZJR0M9CSQoTElCUEwpL2NvbmZpZy5jDQogQ09ORklH Q0lOPQkkKExJQlBMKS9jb25maWcuYy5pbg0KLVNFVFVQPQkJJChMSUJQTCkvU2V0dXAudGhy ZWFkICQoTElCUEwpL1NldHVwLmxvY2FsICQoTElCUEwpL1NldHVwDQorU0VUVVA9CQkkKExJ QlBMKS9TZXR1cC5hdXRvICQoTElCUEwpL1NldHVwLmxvY2FsICQoTElCUEwpL1NldHVwDQog DQogU1lTTElCUz0JJChMSUJNKSAkKExJQkMpDQogDQotLS0gUHl0aG9uLWN2cy9Nb2R1bGVz L01ha2VmaWxlLnByZS5pbglGcmkgTWFyIDI0IDIyOjMyOjI1IDIwMDANCisrKyBQeXRob24t Z2MvTW9kdWxlcy9NYWtlZmlsZS5wcmUuaW4JU2F0IEFwciAgOCAwMTozODoyNSAyMDAwDQpA QCAtMTQ3LDEwICsxNDcsMTAgQEANCiAjIGdldHMgcmVtYWRlIGZyb20gc2NyYXRjaDsgdGhp cyBlbnN1cmVzIHRvIHJlbW92ZSBtb2R1bGVzIHRoYXQgYXJlIG5vDQogIyBsb25nZXIgcGVy dGluZW50IChidXQgdGhhdCB3ZXJlIGluIGEgcHJldmlvdXMgY29uZmlndXJhdGlvbikuDQog Y29uZmlnLmMgTWFrZWZpbGU6IE1ha2VmaWxlLnByZSBjb25maWcuYy5pbiAkKE1BS0VTRVRV UCkNCi1jb25maWcuYyBNYWtlZmlsZTogU2V0dXAudGhyZWFkIFNldHVwIFNldHVwLmxvY2Fs DQorY29uZmlnLmMgTWFrZWZpbGU6IFNldHVwLmF1dG8gU2V0dXAgU2V0dXAubG9jYWwNCiBj b25maWcuYyBNYWtlZmlsZToNCiAJCS1ybSAtZiAkKExJQlJBUlkpDQotCQkkKFNIRUxMKSAk KE1BS0VTRVRVUCkgU2V0dXAudGhyZWFkIFNldHVwLmxvY2FsIFNldHVwDQorCQkkKFNIRUxM KSAkKE1BS0VTRVRVUCkgU2V0dXAuYXV0byBTZXR1cC5sb2NhbCBTZXR1cA0KIA0KIGhhc3Np Z25hbDoNCiAJCS1ybSAtZiBoYXNzaWduYWwNCi0tLSBQeXRob24tY3ZzL01vZHVsZXMvU2V0 dXAuaW4JU3VuIEFwciAgMiAyMjo1NjozNyAyMDAwDQorKysgUHl0aG9uLWdjL01vZHVsZXMv U2V0dXAuaW4JU2F0IEFwciAgOCAwMTozODoyNSAyMDAwDQpAQCAtMTAwLDcgKzEwMCw3IEBA DQogR0xIQUNLPS1EY2xlYXI9X19HTGNsZWFyDQogI2dsIGdsbW9kdWxlLmMgY2dlbnN1cHBv cnQuYyAtSSQoc3JjZGlyKSAkKEdMSEFDSykgLWxnbCAtbFgxMQ0KIA0KLSMgVGhlIHRocmVh ZCBtb2R1bGUgaXMgbm93IGF1dG9tYXRpY2FsbHkgZW5hYmxlZCwgc2VlIFNldHVwLnRocmVh ZC4NCisjIFRoZSB0aHJlYWQgbW9kdWxlIGlzIG5vdyBhdXRvbWF0aWNhbGx5IGVuYWJsZWQs IHNlZSBTZXR1cC5hdXRvLg0KIA0KICMgUHVyZSBtb2R1bGUuICBDYW5ub3QgYmUgbGlua2Vk IGR5bmFtaWNhbGx5Lg0KICMgLURXSVRIX1FVQU5USUZZLCAtRFdJVEhfUFVSSUZZLCBvciAt RFdJVEhfQUxMX1BVUkUNCi0tLSBQeXRob24tY3ZzL01vZHVsZXMvU2V0dXAuYXV0by5pbg0K KysrIFB5dGhvbi1nYy9Nb2R1bGVzL1NldHVwLmF1dG8uaW4JU2F0IEFwciAgOCAwMTozODoy NSAyMDAwDQpAQCAtMCwwICsxLDE2IEBADQorIyBUaGlzIGZpbGUgaXMgdHJhbnNtb2dyaWZp ZWQgaW50byBTZXR1cC5hdXRvIGJ5IGNvbmZpZy5zdGF0dXMuICBJdHMNCisjIHB1cnBvc2Ug aXMgdG8gYXV0b21hdGljYWxseSBlbmFibGUgbW9kdWxlcyBnaXZlbiB3aGVuIGNlcnRhaW4N CisjIGFyZ3VtZW50cyBhcmUgZ2l2ZW4gdG8gdGhlIGNvbmZpZ3VyZSBzY3JpcHQuICBJdCBy ZXBsYWNlcyB0aGUgb2xkDQorIyBTZXR1cC50aHJlYWQuaW4gZmlsZS4NCisNCisjIEluY2x1 ZGUgdGhlIHRocmVhZCBtb2R1bGUgd2hlbiB0aGUgLS13aXRoLXRocmVhZCBhcmd1bWVudCBp cyBnaXZlbiB0bw0KKyMgdGhlIGNvbmZpZ3VyZSBzY3JpcHQuDQorIw0KKyMgKk5PVEUqOiBp ZiB0aGUgY29uZmlndXJlIHNjcmlwdCBkZWNpZGVzIGl0IGNhbid0IHN1cHBvcnQgdGhyZWFk cywgdGhlDQorIyB0aHJlYWQgbW9kdWxlIHdpbGwgc3RpbGwgYmUgZW5hYmxlZCBhbmQgY2F1 c2UgY29tcGlsZSBlcnJvcnMuICBUaGUNCisjIHNvbHV0aW9uIGlzIG5vdCB0byB1c2UgLS13 aXRoLXRocmVhZCBvbiBwbGF0Zm9ybXMgdGhhdCBkb24ndCBzdXBwb3J0DQorIyB0aHJlYWRz Lg0KK0BVU0VfVEhSRUFEX01PRFVMRUB0aHJlYWQgdGhyZWFkbW9kdWxlLmMNCisNCisjIEdh cmJhZ2UgY29sbGVjdGlvbiBlbmFibGVkIHdpdGggLS13aXRoLWN5Y2xlLWdjDQorQFVTRV9H Q19NT0RVTEVAZ2MgZ2Ntb2R1bGUuYw0KLS0tIFB5dGhvbi1jdnMvTGliL3Rlc3QvdGVzdF9n Yy5weQ0KKysrIFB5dGhvbi1nYy9MaWIvdGVzdC90ZXN0X2djLnB5CVNhdCBBcHIgIDggMDM6 MjU6MjUgMjAwMA0KQEAgLTAsMCArMSw5MCBAQA0KK2ltcG9ydCBnYw0KKw0KK2RlZiB0ZXN0 X2xpc3QoKToNCisgICAgbCA9IFtdDQorICAgIGwuYXBwZW5kKGwpDQorICAgIHByaW50ICds aXN0IDB4JXgnICUgaWQobCkNCisgICAgZ2MuY29sbGVjdCgpDQorICAgIGRlbCBsDQorICAg IGFzc2VydCBnYy5jb2xsZWN0KCkgPT0gMQ0KKw0KK2RlZiB0ZXN0X2RpY3QoKToNCisgICAg ZCA9IHt9DQorICAgIGRbMV0gPSBkDQorICAgIHByaW50ICdkaWN0IDB4JXgnICUgaWQoZCkN CisgICAgZ2MuY29sbGVjdCgpDQorICAgIGRlbCBkDQorICAgIGFzc2VydCBnYy5jb2xsZWN0 KCkgPT0gMQ0KKw0KK2RlZiB0ZXN0X3R1cGxlKCk6DQorICAgIGwgPSBbXQ0KKyAgICB0ID0g KGwsKQ0KKyAgICBsLmFwcGVuZCh0KQ0KKyAgICBwcmludCAnbGlzdCAweCV4JyAlIGlkKGwp DQorICAgIHByaW50ICd0dXBsZSAweCV4JyAlIGlkKHQpDQorICAgIGdjLmNvbGxlY3QoKQ0K KyAgICBkZWwgdA0KKyAgICBkZWwgbA0KKyAgICBhc3NlcnQgZ2MuY29sbGVjdCgpID09IDIN CisNCitkZWYgdGVzdF9jbGFzcygpOg0KKyAgICBjbGFzcyBBOg0KKyAgICAgICAgcGFzcw0K KyAgICBBLmEgPSBBDQorICAgIHByaW50ICdjbGFzcyAweCV4JyAlIGlkKEEpDQorICAgIGdj LmNvbGxlY3QoKQ0KKyAgICBkZWwgQQ0KKyAgICBhc3NlcnQgZ2MuY29sbGVjdCgpID09IDIN CisNCitkZWYgdGVzdF9pbnN0YW5jZSgpOg0KKyAgICBjbGFzcyBBOg0KKyAgICAgICAgcGFz cw0KKyAgICBhID0gQSgpDQorICAgIGEuYSA9IGENCisgICAgcHJpbnQgcmVwcihhKQ0KKyAg ICBnYy5jb2xsZWN0KCkNCisgICAgZGVsIGENCisgICAgYXNzZXJ0IGdjLmNvbGxlY3QoKSA9 PSAyDQorDQorZGVmIHRlc3RfZmluYWxpemVyKCk6DQorICAgIGNsYXNzIEE6DQorICAgICAg ICBkZWYgX19kZWxfXyhzZWxmKTogcGFzcw0KKyAgICBjbGFzcyBCOg0KKyAgICAgICAgcGFz cw0KKyAgICBhID0gQSgpDQorICAgIGEuYSA9IGENCisgICAgaWRfYSA9IGlkKGEpDQorICAg IGIgPSBCKCkNCisgICAgYi5iID0gYg0KKyAgICBwcmludCAnYScsIHJlcHIoYSkNCisgICAg cHJpbnQgJ2InLCByZXByKGIpDQorICAgIGdjLmNvbGxlY3QoKQ0KKyAgICBnYy5nYXJiYWdl WzpdID0gW10NCisgICAgZGVsIGENCisgICAgZGVsIGINCisgICAgYXNzZXJ0IGdjLmNvbGxl Y3QoKSA9PSA0DQorICAgIGFzc2VydCBpZChnYy5nYXJiYWdlWzBdKSA9PSBpZF9hDQorDQor ZGVmIHRlc3RfZnVuY3Rpb24oKToNCisgICAgZCA9IHt9DQorICAgIGV4ZWMoImRlZiBmKCk6 IHBhc3NcbiIpIGluIGQNCisgICAgcHJpbnQgJ2RpY3QgMHgleCcgJSBpZChkKQ0KKyAgICBw cmludCAnZnVuYyAweCV4JyAlIGlkKGRbJ2YnXSkNCisgICAgZ2MuY29sbGVjdCgpDQorICAg IGRlbCBkDQorICAgIGFzc2VydCBnYy5jb2xsZWN0KCkgPT0gMg0KKw0KKw0KK2RlZiB0ZXN0 X2FsbCgpOg0KKyAgICBkZWJ1ZyA9IGdjLmdldF9kZWJ1ZygpDQorICAgIGdjLnNldF9kZWJ1 ZyhnYy5ERUJVR19MRUFLIHwgZ2MuREVCVUdfU1RBVFMpDQorICAgIHRlc3RfbGlzdCgpDQor ICAgIHRlc3RfZGljdCgpDQorICAgIHRlc3RfdHVwbGUoKQ0KKyAgICB0ZXN0X2NsYXNzKCkN CisgICAgdGVzdF9pbnN0YW5jZSgpDQorICAgIHRlc3RfZmluYWxpemVyKCkNCisgICAgdGVz dF9mdW5jdGlvbigpDQorICAgIGdjLnNldF9kZWJ1ZyhkZWJ1ZykNCisNCit0ZXN0X2FsbCgp DQotLS0gUHl0aG9uLWN2cy9QQ2J1aWxkL3B5dGhvbjE2LmRzcAlGcmkgQXByICA3IDE1OjI3 OjA0IDIwMDANCisrKyBQeXRob24tZ2MvUENidWlsZC9weXRob24xNi5kc3AJU2F0IEFwciAg OCAwMjoyMjo0OCAyMDAwDQpAQCAtNjQ1LDYgKzY0NSwyMSBAQA0KICMgRW5kIFNvdXJjZSBG aWxlDQ0KICMgQmVnaW4gU291cmNlIEZpbGUNDQogDQ0KK1NPVVJDRT0uLlxNb2R1bGVzXGdj bW9kdWxlLmMNDQorDQ0KKyFJRiAgIiQoQ0ZHKSIgPT0gInB5dGhvbjE2IC0gV2luMzIgUmVs ZWFzZSINDQorDQ0KKyFFTFNFSUYgICIkKENGRykiID09ICJweXRob24xNiAtIFdpbjMyIERl YnVnIg0NCisNDQorIUVMU0VJRiAgIiQoQ0ZHKSIgPT0gInB5dGhvbjE2IC0gV2luMzIgQWxw aGEgRGVidWciDQ0KKw0NCishRUxTRUlGICAiJChDRkcpIiA9PSAicHl0aG9uMTYgLSBXaW4z MiBBbHBoYSBSZWxlYXNlIg0NCisNDQorIUVORElGIA0NCisNDQorIyBFbmQgU291cmNlIEZp bGUNDQorIyBCZWdpbiBTb3VyY2UgRmlsZQ0NCisNDQogU09VUkNFPS4uXFB5dGhvblxnZXRh cmdzLmMNDQogDQ0KICFJRiAgIiQoQ0ZHKSIgPT0gInB5dGhvbjE2IC0gV2luMzIgUmVsZWFz ZSIN From cgw@alum.mit.edu Tue Apr 25 16:01:48 2000 From: cgw@alum.mit.edu (Charles G Waldman) Date: Tue, 25 Apr 2000 10:01:48 -0500 (CDT) Subject: [Patches] fix for pcremodule.c (DECREF, don't DEL) Message-ID: <14597.45916.428921.176160@sirius.net.home> Doing a PyObject_New then PyMem_DEL causes havoc if you are trying to use Py_TRACE_REFS. Disclaimer: http://www.python.org/patches/bugrelease.html Index: Modules/pcremodule.c =================================================================== RCS file: /projects/cvsroot/python/dist/src/Modules/pcremodule.c,v retrieving revision 2.17 diff -c -r2.17 pcremodule.c *** pcremodule.c 2000/02/29 13:59:23 2.17 --- pcremodule.c 2000/04/25 14:58:59 *************** *** 204,210 **** &error, &erroroffset, dictionary); if (rv->regex==NULL) { ! PyMem_DEL(rv); if (!PyErr_Occurred()) { PyObject *errval = Py_BuildValue("si", error, erroroffset); --- 204,210 ---- &error, &erroroffset, dictionary); if (rv->regex==NULL) { ! Py_DECREF(rv); if (!PyErr_Occurred()) { PyObject *errval = Py_BuildValue("si", error, erroroffset); *************** *** 217,223 **** if (rv->regex_extra==NULL && error!=NULL) { PyObject *errval = Py_BuildValue("si", error, 0); ! PyMem_DEL(rv); PyErr_SetObject(ErrorObject, errval); Py_XDECREF(errval); return NULL; --- 217,223 ---- if (rv->regex_extra==NULL && error!=NULL) { PyObject *errval = Py_BuildValue("si", error, 0); ! Py_DECREF(rv); PyErr_SetObject(ErrorObject, errval); Py_XDECREF(errval); return NULL; *************** *** 228,234 **** PyObject *errval = Py_BuildValue("si", error, rv->num_groups); PyErr_SetObject(ErrorObject, errval); Py_XDECREF(errval); ! PyMem_DEL(rv); return NULL; } return (PyObject *)rv; --- 228,234 ---- PyObject *errval = Py_BuildValue("si", error, rv->num_groups); PyErr_SetObject(ErrorObject, errval); Py_XDECREF(errval); ! Py_DECREF(rv); return NULL; } return (PyObject *)rv; From tismer@tismer.com Tue Apr 25 17:07:00 2000 From: tismer@tismer.com (Christian Tismer) Date: Tue, 25 Apr 2000 18:07:00 +0200 Subject: [Patches] Slightly cleaned-up cycle-gc patch References: <14597.45272.956559.551023@sirius.net.home> Message-ID: <3905C2A4.D9007891@tismer.com> Charles G Waldman wrote: > > The problems I was having getting Neil's cyclic-gc stuff to work with > the latest CVS Python had nothing to do with Trashcan - sorry, > Christian! Tss tss - my poor little trashcan pet, now it's happy again :-) ciao - chris p.s.: Oh, did you look at the end of your patch? There appears to be some binary crap. Maybe your python16.dsp file is broekn? -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaunstr. 26 : *Starship* http://starship.python.net 14163 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF where do you want to jump today? http://www.stackless.com From cgw@fnal.gov Tue Apr 25 17:02:09 2000 From: cgw@fnal.gov (Charles G Waldman) Date: Tue, 25 Apr 2000 11:02:09 -0500 (CDT) Subject: [Patches] Sightly clean-up cycle-gc patch Message-ID: <14597.49537.611625.343576@buffalo.fnal.gov> DQogSSBkb24ndCBrbm93IHdoYXQgaGFwcGVuZWQgd2l0aCB0aGF0IGxhc3QgbWVzc2FnZSAt IGl0IHNvbWVob3cgZ290DQpiYXNlLTY0IGVuY29kZWQgd2l0aG91dCBtZSBhc2tpbmcgZm9y IHRoYXQuICBTb3JyeSEgIFR1cm5zIG91dCB0aGF0DQpub3Qgb25seSB3YXMgdGhlIG1lc3Nh Z2UgdW5yZWFkYWJsZSwgYnV0IEkgYXR0YWNoZWQgdGhlIHdyb25nIGZpbGUuDQpEb3VibGUt b29wcyENCg0KDQpUaGUgcHJvYmxlbXMgSSB3YXMgaGF2aW5nIGdldHRpbmcgTmVpbCdzIGN5 Y2xpYy1nYyBzdHVmZiB0byB3b3JrIHdpdGgNCnRoZSBsYXRlc3QgQ1ZTIFB5dGhvbiBoYWQg bm90aGluZyB0byBkbyB3aXRoIFRyYXNoY2FuIC0gc29ycnksDQpDaHJpc3RpYW4hICBJdCB3 YXMgbXkgb3duIGNoYW5nZXMgdG8gdHVwbGVvYmplY3QuYy4gIEl0IHR1cm5lZCBvdXQgdG8N CmJlIGEgbGl0dGxlIHRyaWNreSB0byBnZXQgdGhlIEdDIGluZm8gaGFuZGxlZCBjb3JyZWN0 bHkgZHVyaW5nDQpfUHlUdXBsZV9SZXNpemUuICBCZWxvdyBpcyBhIHZlcnNpb24gb2YgTmVp bCdzIHBhdGNoIHRoYXQgYXBwbGllcw0KY2xlYW5seSB0byBjdXJyZW50IENWUyBhbmQgc2Vl bXMgdG8gd29yayBjb3JyZWN0bHkuICBBbGwgY3JlZGl0IGlzIGR1ZQ0KdG8gTmVpbCwgSSBq dXN0IGRpZCBhIHRpbnkgYW1vdW50IG9mIGNsZWFudXAgd29yayBpbiBhIGZldyBwbGFjZXMu DQooSSB3YXMgdGhpbmtpbmcgb2YgcG9zdGluZyB0aGlzIGFzIGEgZGlmZiB0byBOZWlsJ3Mg ZGlmZiwgYnV0IHdhc24ndA0Kc3VyZSBob3cgdGhhdCB3b3VsZCBnbyBvdmVyLi4uICBJZiB0 aGlzIGdldHMgY2hlY2tlZCBpbiBpdCB3aWxsIGJlIGENCmxvdCBlYXNpZXIgdG8gd29yayBv biBpdCBhbmQgc2VuZCBzbWFsbCBwYXRjaGVzLCByYXRoZXIgdGhhbiBoYXZpbmcgdG8NCnJl Z2VuZXJhdGUgdGhlIHdob2xlIHRoaW5nIGVhY2ggdGltZSkuDQoNCg0KDQpEaWZmZXJlbmNl czogIA0KDQogICgxKSBUaGUgYWJvdmUtbWVudGlvbmVkIF9QeVR1cGxlX1Jlc2l6ZSBmaXgN Cg0KICAoMikgQSBmZXcgcHJvYmxlbXMgd2VyZSBleHBvc2VkIGJ5IGJ1aWxkaW5nIHdpdGgg UHlfVFJBQ0VfUkVGUw0KICBkZWZpbmVkLiAgU3BlY2lmaWFsbHksIFB5T2JqZWN0X05ldyBh bmQgUHlPYmplY3RfTmV3VmFyIGFscmVhZHkgZG8gYQ0KICBfUHlfTmV3UmVmZXJlbmNlIGlu dGVybmFsbHksIGJ1dCBpbiBhIGZldyBwbGFjZXMgKGUuZy4gUHlMaXN0X05ldyksDQogIFB5 T2JqZWN0X05ldyB3YXMgYmVpbmcgdXNlZCB0byBjcmVhdGUgYSBuZXcgb2JqZWN0IHdoaWNo IGlzIHRoZW4NCiAgX1B5X05ld1JlZmVyZW5jZSdkLiAgSWYgUHlfVFJBQ0VfUkVGUyBpcyBu b3Qgc2V0LCB0aGlzIGlzIG1lcmVseQ0KICByZWR1bmRhbnQ7IHdpdGggUHlfVFJBQ0VfUkVG UyBzZXQgaXQgY2F1c2VzIHNlcmlvdXMgcHJvYmxlbXMgYmVjYXVzZQ0KICB0aGUgb2JqZWN0 IGlzIGFkZGVkIHRvIHRoZSByZWZlcmVuY2UgY2hhaW4gdHdpY2UuDQoNCg0KDQogICAgICAg ICAgICAgICAgICAgSSBjb25maXJtIHRoYXQsIHRvIHRoZSBiZXN0IG9mIG15IGtub3dsZWRn ZSBhbmQgYmVsaWVmLCB0aGlzDQogICAgICAgICAgICAgICAgICAgY29udHJpYnV0aW9uIGlz IGZyZWUgb2YgYW55IGNsYWltcyBvZiB0aGlyZCBwYXJ0aWVzIHVuZGVyDQogICAgICAgICAg ICAgICAgICAgY29weXJpZ2h0LCBwYXRlbnQgb3Igb3RoZXIgcmlnaHRzIG9yIGludGVyZXN0 cyAoImNsYWltcyIpLiAgVG8NCiAgICAgICAgICAgICAgICAgICB0aGUgZXh0ZW50IHRoYXQg SSBoYXZlIGFueSBzdWNoIGNsYWltcywgSSBoZXJlYnkgZ3JhbnQgdG8gQ05SSSBhDQogICAg ICAgICAgICAgICAgICAgbm9uZXhjbHVzaXZlLCBpcnJldm9jYWJsZSwgcm95YWx0eS1mcmVl LCB3b3JsZHdpZGUgbGljZW5zZSB0bw0KICAgICAgICAgICAgICAgICAgIHJlcHJvZHVjZSwg ZGlzdHJpYnV0ZSwgcGVyZm9ybSBhbmQvb3IgZGlzcGxheSBwdWJsaWNseSwgcHJlcGFyZQ0K ICAgICAgICAgICAgICAgICAgIGRlcml2YXRpdmUgdmVyc2lvbnMsIGFuZCBvdGhlcndpc2Ug dXNlIHRoaXMgY29udHJpYnV0aW9uIGFzIHBhcnQNCiAgICAgICAgICAgICAgICAgICBvZiB0 aGUgUHl0aG9uIHNvZnR3YXJlIGFuZCBpdHMgcmVsYXRlZCBkb2N1bWVudGF0aW9uLCBvciBh bnkNCiAgICAgICAgICAgICAgICAgICBkZXJpdmF0aXZlIHZlcnNpb25zIHRoZXJlb2YsIGF0 IG5vIGNvc3QgdG8gQ05SSSBvciBpdHMgbGljZW5zZWQNCiAgICAgICAgICAgICAgICAgICB1 c2VycywgYW5kIHRvIGF1dGhvcml6ZSBvdGhlcnMgdG8gZG8gc28uDQoNCiAgICAgICAgICAg ICAgICAgICBJIGFja25vd2xlZGdlIHRoYXQgQ05SSSBtYXksIGF0IGl0cyBzb2xlIGRpc2Ny ZXRpb24sIGRlY2lkZQ0KICAgICAgICAgICAgICAgICAgIHdoZXRoZXIgb3Igbm90IHRvIGlu Y29ycG9yYXRlIHRoaXMgY29udHJpYnV0aW9uIGluIHRoZSBQeXRob24NCiAgICAgICAgICAg ICAgICAgICBzb2Z0d2FyZSBhbmQgaXRzIHJlbGF0ZWQgZG9jdW1lbnRhdGlvbi4gIEkgZnVy dGhlciBncmFudCBDTlJJDQogICAgICAgICAgICAgICAgICAgcGVybWlzc2lvbiB0byB1c2Ug bXkgbmFtZSBhbmQgb3RoZXIgaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24NCiAgICAgICAgICAg ICAgICAgICBwcm92aWRlZCB0byBDTlJJIGJ5IG1lIGZvciB1c2UgaW4gY29ubmVjdGlvbiB3 aXRoIHRoZSBQeXRob24NCiAgICAgICAgICAgICAgICAgICBzb2Z0d2FyZSBhbmQgaXRzIHJl bGF0ZWQgZG9jdW1lbnRhdGlvbi4NCg0KLS0tIFB5dGhvbi1jdnMvSW5jbHVkZS9vYmplY3Qu aAlGcmkgTWFyIDI0IDIyOjMyOjE2IDIwMDANCisrKyBQeXRob24tZ2MvSW5jbHVkZS9vYmpl Y3QuaAlTYXQgQXByICA4IDAxOjM4OjI1IDIwMDANCkBAIC0xNDUsNiArMTQ1LDEwIEBADQog dHlwZWRlZiBpbnQgKCpnZXRzZWdjb3VudHByb2MpIFB5X1BST1RPKChQeU9iamVjdCAqLCBp bnQgKikpOw0KIHR5cGVkZWYgaW50ICgqZ2V0Y2hhcmJ1ZmZlcnByb2MpIFB5X1BST1RPKChQ eU9iamVjdCAqLCBpbnQsIGNvbnN0IGNoYXIgKiopKTsNCiB0eXBlZGVmIGludCAoKm9iam9i anByb2MpIFB5X1BST1RPKChQeU9iamVjdCAqLCBQeU9iamVjdCAqKSk7DQorI2lmZGVmIFdJ VEhfQ1lDTEVfR0MNCit0eXBlZGVmIGludCAoKnZpc2l0cHJvYykgUHlfUFJPVE8oKFB5T2Jq ZWN0ICosIHZvaWQgKikpOw0KK3R5cGVkZWYgaW50ICgqcmVjdXJzZXByb2MpIFB5X1BST1RP KChQeU9iamVjdCAqLCB2aXNpdHByb2MsIHZvaWQgKikpOw0KKyNlbmRpZg0KIA0KIHR5cGVk ZWYgc3RydWN0IHsNCiAJYmluYXJ5ZnVuYyBuYl9hZGQ7DQpAQCAtMjQzLDkgKzI0NywxOCBA QA0KIA0KIAljaGFyICp0cF9kb2M7IC8qIERvY3VtZW50YXRpb24gc3RyaW5nICovDQogDQot CS8qIE1vcmUgc3BhcmVzICovDQorI2lmZGVmIFdJVEhfQ1lDTEVfR0MNCisJLyogY2FsbCBm dW5jdGlvbiBmb3IgYWxsIGFjY2Vzc2libGUgb2JqZWN0cyAqLw0KKwlyZWN1cnNlcHJvYyB0 cF9yZWN1cnNlOw0KKwkNCisJLyogZGVsZXRlIHJlZmVyZW5jZXMgdG8gY29udGFpbmVkIG9i amVjdHMgKi8NCisJaW5xdWlyeSB0cF9jbGVhcjsNCisjZWxzZQ0KIAlsb25nIHRwX3h4eDU7 DQogCWxvbmcgdHBfeHh4NjsNCisjZW5kaWYNCisNCisJLyogTW9yZSBzcGFyZXMgKi8NCiAJ bG9uZyB0cF94eHg3Ow0KIAlsb25nIHRwX3h4eDg7DQogDQpAQCAtMzE1LDYgKzMyOCw5IEBA DQogDQogLyogUHlTZXF1ZW5jZU1ldGhvZHMgY29udGFpbnMgc3FfY29udGFpbnMgKi8NCiAj ZGVmaW5lIFB5X1RQRkxBR1NfSEFWRV9TRVFVRU5DRV9JTiAoMUw8PDEpDQorDQorLyogT2Jq ZWN0cyB3aXRoIGEgR0MgaW5mbyBwcmVmaXggKGFsbG9jYXRlZCAqYmVmb3JlKiB0aGUgb2Jq ZWN0IGl0c2VsZiEpICovDQorI2RlZmluZSBQeV9UUEZMQUdTX0hBVkVfR0NJTkZPICgxTDw8 MikNCiANCiAjZGVmaW5lIFB5X1RQRkxBR1NfREVGQVVMVCAgKFB5X1RQRkxBR1NfSEFWRV9H RVRDSEFSQlVGRkVSIHwgXA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfVFBG TEFHU19IQVZFX1NFUVVFTkNFX0lOKQ0KLS0tIFB5dGhvbi1jdnMvSW5jbHVkZS9vYmppbXBs LmgJVGh1IE1hciAgMiAxNzowMjoyMyAyMDAwDQorKysgUHl0aG9uLWdjL0luY2x1ZGUvb2Jq aW1wbC5oCVNhdCBBcHIgIDggMDM6MTg6MjIgMjAwMA0KQEAgLTM4LDggKzM4LDQyIEBADQog LyoNCiBBZGRpdGlvbmFsIG1hY3JvcyBmb3IgbW9kdWxlcyB0aGF0IGltcGxlbWVudCBuZXcg b2JqZWN0IHR5cGVzLg0KIFlvdSBtdXN0IGZpcnN0IGluY2x1ZGUgIm9iamVjdC5oIi4NCisq Lw0KKw0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDIA0KKw0KKy8qIFN0cnVjdHVyZSAqcHJlZml4 ZWQqIHRvIGNvbnRhaW5lciBvYmplY3RzIHBhcnRpY2lwYXRpbmcgaW4gR0MgKi8gDQordHlw ZWRlZiBzdHJ1Y3QgX2djaW5mbyB7DQorCXN0cnVjdCBfZ2NpbmZvICpnY19uZXh0Ow0KKwlz dHJ1Y3QgX2djaW5mbyAqZ2NfcHJldjsNCisJaW50IGdjX3JlZnM7DQorfSBQeUdDSW5mbzsN CisNCisvKiBUZXN0IGlmIGEgdHlwZSBoYXMgR0MgaW5mbyAqLw0KKyNkZWZpbmUgUFlfVFlQ RUlTR0ModCkgUHlUeXBlX0hhc0ZlYXR1cmUoKHQpLCBQeV9UUEZMQUdTX0hBVkVfR0NJTkZP KQ0KKw0KKy8qIFRlc3QgaWYgYW4gb2JqZWN0IGhhcyBHQyBpbmZvICovDQorI2RlZmluZSBQ WV9JU0dDKG8pIFBZX1RZUEVJU0dDKChvKS0+b2JfdHlwZSkNCisNCisvKiBHZXQgYW4gb2Jq ZWN0J3MgR0MgaW5mbyAtLSBOVUxMIGlmIHRoZSBvYmplY3QgaGFzIG5vbmUgKi8NCisjZGVm aW5lIFBZX0dDSU5GTyhvKSAoUFlfSVNHQyhvKSA/ICgoUHlHQ0luZm8gKikobyktMSkgOiBO VUxMKQ0KKw0KKy8qIFVuc2FmZSB2ZXJzaW9uIG9mIFBZX0dDSU5GTygpIC0tIG9ubHkgY2Fs bCBpZiBQWV9JU0dDKHApIGlzIHRydWUgKi8NCisjZGVmaW5lIFBZX0dDSU5GT19VTlNBRkUo bykgKChQeUdDSW5mbyAqKShvKS0xKQ0KKw0KKy8qIEdldCB0aGUgb2JqZWN0IGdpdmVuIHRo ZSBQeUdDSW5mbyAqLw0KKyNkZWZpbmUgUFlfR0NPQkooZykgKChQeU9iamVjdCAqKSgoZykr MSkpDQogDQotUHlPYmplY3RfTkVXKHR5cGUsIHR5cGVvYmopIGFsbG9jYXRlcyBtZW1vcnkg Zm9yIGEgbmV3IG9iamVjdCBvZiB0aGUgZ2l2ZW4NCisvKiBBZGQgdGhlIG9iamVjdCBpbnRv IHRoZSBjb250YWluZXIgc2V0ICovDQorZXh0ZXJuIERMX0lNUE9SVCh2b2lkKSBQeUdDX0lu c2VydCBQeV9QUk9UTygoUHlPYmplY3QgKikpOw0KKw0KKy8qIFJlbW92ZSB0aGUgb2JqZWN0 IGZyb20gdGhlIGNvbnRhaW5lciBzZXQgKi8NCitleHRlcm4gRExfSU1QT1JUKHZvaWQpIFB5 R0NfUmVtb3ZlIFB5X1BST1RPKChQeU9iamVjdCAqKSk7DQorDQorI2VuZGlmDQorDQorLyoN CitQeU9iamVjdF9OZXcodHlwZSwgdHlwZW9iaikgYWxsb2NhdGVzIG1lbW9yeSBmb3IgYSBu ZXcgb2JqZWN0IG9mIHRoZSBnaXZlbg0KIHR5cGU7IGhlcmUgJ3R5cGUnIG11c3QgYmUgdGhl IEMgc3RydWN0dXJlIHR5cGUgdXNlZCB0byByZXByZXNlbnQgdGhlDQogb2JqZWN0IGFuZCAn dHlwZW9iaicgdGhlIGFkZHJlc3Mgb2YgdGhlIGNvcnJlc3BvbmRpbmcgdHlwZSBvYmplY3Qu DQogUmVmZXJlbmNlIGNvdW50IGFuZCB0eXBlIHBvaW50ZXIgYXJlIGZpbGxlZCBpbjsgdGhl IHJlc3Qgb2YgdGhlIGJ5dGVzIG9mDQpAQCAtNDcsMzAgKzgxLDI5IEBADQogVGhlIHNpemUg b2YgdGhlIG9iamVjdCBpcyBhY3R1YWxseSBkZXRlcm1pbmVkIGJ5IHRoZSB0cF9iYXNpY3Np emUgZmllbGQNCiBvZiB0aGUgdHlwZSBvYmplY3QuDQogDQotUHlPYmplY3RfTkVXX1ZBUih0 eXBlLCB0eXBlb2JqLCBuKSBpcyBzaW1pbGFyIGJ1dCBhbGxvY2F0ZXMgYSB2YXJpYWJsZS1z aXplDQorUHlPYmplY3RfTmV3VmFyKHR5cGUsIHR5cGVvYmosIG4pIGlzIHNpbWlsYXIgYnV0 IGFsbG9jYXRlcyBhIHZhcmlhYmxlLXNpemUNCiBvYmplY3Qgd2l0aCBuIGV4dHJhIGl0ZW1z LiAgVGhlIHNpemUgaXMgY29tcHV0ZWQgYXMgdHBfYmFzaWNzaXplIHBsdXMNCiBuICogdHBf aXRlbXNpemUuICBUaGlzIGZpbGxzIGluIHRoZSBvYl9zaXplIGZpZWxkIGFzIHdlbGwuDQog Ki8NCiANCi0jaWZuZGVmIE1TX0NPUkVETEwNCiBleHRlcm4gRExfSU1QT1JUKFB5T2JqZWN0 ICopIF9QeU9iamVjdF9OZXcgUHlfUFJPVE8oKFB5VHlwZU9iamVjdCAqKSk7DQogZXh0ZXJu IERMX0lNUE9SVChQeVZhck9iamVjdCAqKSBfUHlPYmplY3RfTmV3VmFyIFB5X1BST1RPKChQ eVR5cGVPYmplY3QgKiwgaW50KSk7DQorZXh0ZXJuIERMX0lNUE9SVCh2b2lkKSBQeU9iamVj dF9EZWwgUHlfUFJPVE8oKFB5T2JqZWN0ICopKTsNCiANCi0jZGVmaW5lIFB5T2JqZWN0X05F Vyh0eXBlLCB0eXBlb2JqKSAoKHR5cGUgKikgX1B5T2JqZWN0X05ldyh0eXBlb2JqKSkNCi0j ZGVmaW5lIFB5T2JqZWN0X05FV19WQVIodHlwZSwgdHlwZW9iaiwgbikgKCh0eXBlICopIF9Q eU9iamVjdF9OZXdWYXIodHlwZW9iaiwgbikpDQotDQotI2Vsc2UNCi0vKiBGb3IgYW4gTVMt V2luZG93cyBETEwsIHdlIGNoYW5nZSB0aGUgd2F5IGFuIG9iamVjdCBpcyBjcmVhdGVkLCBz byB0aGF0IHRoZQ0KLSAgIGV4dGVuc2lvbiBtb2R1bGUncyBtYWxsb2MgaXMgdXNlZCwgcmF0 aGVyIHRoYW4gdGhlIGNvcmUgRExMIG1hbGxvYywgYXMgdGhlcmUgaXMNCi0gICBubyBndWFy YW50ZWUgdGhleSB3aWxsIHVzZSB0aGUgc2FtZSBoZWFwDQotKi8NCi1leHRlcm4gRExfSU1Q T1JUKFB5T2JqZWN0ICopIF9QeU9iamVjdF9OZXcgUHlfUFJPVE8oKFB5VHlwZU9iamVjdCAq LCBQeU9iamVjdCAqKSk7DQotZXh0ZXJuIERMX0lNUE9SVChQeVZhck9iamVjdCAqKSBfUHlP YmplY3RfTmV3VmFyIFB5X1BST1RPKChQeVR5cGVPYmplY3QgKiwgaW50LCBQeVZhck9iamVj dCAqKSk7DQotDQotI2RlZmluZSBQeU9iamVjdF9ORVcodHlwZSwgdHlwZW9iaikgKCh0eXBl ICopIF9QeU9iamVjdF9OZXcodHlwZW9iaiwoUHlPYmplY3QgKiltYWxsb2MoKHR5cGVvYmop LT50cF9iYXNpY3NpemUpKSkNCi0jZGVmaW5lIFB5T2JqZWN0X05FV19WQVIodHlwZSwgdHlw ZW9iaiwgbikgKCh0eXBlICopIF9QeU9iamVjdF9OZXdWYXIodHlwZW9iaiwgbiwgKFB5VmFy T2JqZWN0ICopbWFsbG9jKCh0eXBlb2JqKS0+dHBfYmFzaWNzaXplICsgbiAqICh0eXBlb2Jq KS0+dHBfaXRlbXNpemUpKSkNCi0NCi0jZW5kaWYgLyogTVNfQ09SRURMTCAqLw0KKy8qIEZ1 bmN0aW9ucyAqLw0KKyNkZWZpbmUgUHlPYmplY3RfTmV3KHR5cGUsIHR5cGVvYmopIFwNCisJ CSgodHlwZSAqKSBfUHlPYmplY3RfTmV3KHR5cGVvYmopKQ0KKyNkZWZpbmUgUHlPYmplY3Rf TmV3VmFyKHR5cGUsIHR5cGVvYmosIG4pIFwNCisgICAgICAgICAgICAgICAgKCh0eXBlICop IF9QeU9iamVjdF9OZXdWYXIoKHR5cGVvYmopLCAobikpKQ0KKw0KKw0KK2V4dGVybiBETF9J TVBPUlQoUHlPYmplY3QgKikgX1B5T2JqZWN0X0Zyb21UeXBlIFB5X1BST1RPKChQeVR5cGVP YmplY3QgKiwgUHlPYmplY3QgKikpOw0KK2V4dGVybiBETF9JTVBPUlQoUHlWYXJPYmplY3Qg KikgX1B5T2JqZWN0X1ZhckZyb21UeXBlIFB5X1BST1RPKChQeVR5cGVPYmplY3QgKiwgaW50 LCBQeVZhck9iamVjdCAqKSk7DQorDQorLyogVGhlc2UgbWFjcm9zIG1heSBub3QgdXNlIHRo ZSBzYW1lIG1hbGxvYyBhcyBQeXRob24uIFRoZXkgY2Fubm90IGJlIHVzZWQNCisgKiBvYmpl Y3RzIHRoYXQgYXJlIGludm9sdmVkIGluIGdhcmJhZ2UgY29sbGVjdGlvbiAqLw0KKyNkZWZp bmUgUHlPYmplY3RfTkVXKHR5cGUsIHR5cGVvYmopICgodHlwZSAqKSBfUHlPYmplY3RfRnJv bVR5cGUodHlwZW9iaiwoUHlPYmplY3QgKiltYWxsb2MoKHR5cGVvYmopLT50cF9iYXNpY3Np emUpKSkNCisjZGVmaW5lIFB5T2JqZWN0X05FV19WQVIodHlwZSwgdHlwZW9iaiwgbikgKCh0 eXBlICopIF9QeU9iamVjdF9WYXJGcm9tVHlwZSh0eXBlb2JqLCBuLCAoUHlWYXJPYmplY3Qg KiltYWxsb2MoKHR5cGVvYmopLT50cF9iYXNpY3NpemUgKyBuICogKHR5cGVvYmopLT50cF9p dGVtc2l6ZSkpKQ0KIA0KICNpZmRlZiBfX2NwbHVzcGx1cw0KIH0NCi0tLSBQeXRob24tY3Zz L01vZHVsZXMvY1BpY2tsZS5jCUZyaSBNYXIgMjQgMjI6MzI6MjUgMjAwMA0KKysrIFB5dGhv bi1nYy9Nb2R1bGVzL2NQaWNrbGUuYwlTYXQgQXByICA4IDAyOjEzOjExIDIwMDANCkBAIC0y ODg2LDcgKzI4ODYsNyBAQA0KICAgICAgICAgICAgICAgUHlJbnN0YW5jZU9iamVjdCAqaW5z dDsNCiANCiAgICAgICAgICAgICAgIFB5RXJyX0NsZWFyKCk7DQotICAgICAgICAgICAgICBV TkxFU1MgKGluc3Q9UHlPYmplY3RfTkVXKFB5SW5zdGFuY2VPYmplY3QsICZQeUluc3RhbmNl X1R5cGUpKQ0KKyAgICAgICAgICAgICAgVU5MRVNTIChpbnN0PVB5T2JqZWN0X05ldyhQeUlu c3RhbmNlT2JqZWN0LCAmUHlJbnN0YW5jZV9UeXBlKSkNCiAgICAgICAgICAgICAgICAgZ290 byBlcnI7DQogICAgICAgICAgICAgICBpbnN0LT5pbl9jbGFzcz0oUHlDbGFzc09iamVjdCop Y2xzOw0KICAgICAgICAgICAgICAgUHlfSU5DUkVGKGNscyk7DQpAQCAtMjg5NCw3ICsyODk0 LDkgQEANCiAgICAgICAgICAgICAgICAgUHlfREVDUkVGKGluc3QpOw0KICAgICAgICAgICAg ICAgICBnb3RvIGVycjsNCiAgICAgICAgICAgICAgIH0NCi0NCisjaWZkZWYgV0lUSF9DWUNM RV9HQw0KKyAgICAgICAgICAgICAgUHlHQ19JbnNlcnQoKFB5T2JqZWN0ICopaW5zdCk7DQor I2VuZGlmDQogICAgICAgICAgICAgICByZXR1cm4gKFB5T2JqZWN0ICopaW5zdDsNCiAgICAg ICAgICAgICB9DQogICAgICAgICAgIFB5X0RFQ1JFRihfX2dldGluaXRhcmdzX18pOw0KLS0t IFB5dGhvbi1jdnMvTW9kdWxlcy9uZXdtb2R1bGUuYwlUdWUgRmViIDI5IDE0OjU1OjA5IDIw MDANCisrKyBQeXRob24tZ2MvTW9kdWxlcy9uZXdtb2R1bGUuYwlTYXQgQXByICA4IDAyOjEz OjI2IDIwMDANCkBAIC00OSwxMyArNDksMTYgQEANCiAJCQkgICAgICAmUHlDbGFzc19UeXBl LCAma2xhc3MsDQogCQkJICAgICAgJlB5RGljdF9UeXBlLCAmZGljdCkpDQogCQlyZXR1cm4g TlVMTDsNCi0JaW5zdCA9IFB5T2JqZWN0X05FVyhQeUluc3RhbmNlT2JqZWN0LCAmUHlJbnN0 YW5jZV9UeXBlKTsNCisJaW5zdCA9IFB5T2JqZWN0X05ldyhQeUluc3RhbmNlT2JqZWN0LCAm UHlJbnN0YW5jZV9UeXBlKTsNCiAJaWYgKGluc3QgPT0gTlVMTCkNCiAJCXJldHVybiBOVUxM Ow0KIAlQeV9JTkNSRUYoa2xhc3MpOw0KIAlQeV9JTkNSRUYoZGljdCk7DQogCWluc3QtPmlu X2NsYXNzID0gKFB5Q2xhc3NPYmplY3QgKilrbGFzczsNCiAJaW5zdC0+aW5fZGljdCA9IGRp Y3Q7DQorI2lmZGVmIFdJVEhfQ1lDTEVfR0MNCisJUHlHQ19JbnNlcnQoKFB5T2JqZWN0ICop aW5zdCk7DQorI2VuZGlmDQogCXJldHVybiAoUHlPYmplY3QgKilpbnN0Ow0KIH0NCiANCi0t LSBQeXRob24tY3ZzL01vZHVsZXMvZ2Ntb2R1bGUuYw0KKysrIFB5dGhvbi1nYy9Nb2R1bGVz L2djbW9kdWxlLmMJU2F0IEFwciAgOCAwMzoyNTo1NyAyMDAwDQpAQCAtMCwwICsxLDY3NyBA QA0KKy8qDQorIA0KKyAgUmVmZXJlbmNlIEN5Y2xlIEdhcmJhZ2UgQ29sbGVjdGlvbg0KKyAg PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQ0KKw0KKyAgTmVpbCBTY2hlbWVu YXVlciA8bmFzY2hlbWVAZW5tZS51Y2FsZ2FyeS5jYT4NCisNCisgIEJhc2VkIG9uIGEgcG9z dCBvbiB0aGUgcHl0aG9uLWRldiBsaXN0LiAgSWRlYXMgZnJvbSBHdWlkbyB2YW4gUm9zc3Vt LA0KKyAgRXJpYyBUaWVkZW1hbm4sIGFuZCB2YXJpb3VzIG90aGVycy4NCisNCisgIGh0dHA6 Ly93d3cuZW5tZS5jYWxnYXJ5LmNhL35uYXNjaGVtZS9weXRob24vZ2MuaHRtbA0KKyAgaHR0 cDovL3d3dy5weXRob24ub3JnL3BpcGVybWFpbC9weXRob24tZGV2LzIwMDAtTWFyY2gvMDAz ODY5Lmh0bWwNCisgIGh0dHA6Ly93d3cucHl0aG9uLm9yZy9waXBlcm1haWwvcHl0aG9uLWRl di8yMDAwLU1hcmNoLzAwNDAxMC5odG1sDQorICBodHRwOi8vd3d3LnB5dGhvbi5vcmcvcGlw ZXJtYWlsL3B5dGhvbi1kZXYvMjAwMC1NYXJjaC8wMDQwMjIuaHRtbA0KKw0KKyAgRm9yIGEg aGlnaGxldmVsIHZpZXcgb2YgdGhlIGNvbGxlY3Rpb24gcHJvY2VzcywgcmVhZCB0aGUgY29s bGVjdA0KKyAgZnVuY3Rpb24uDQorDQorICBUT0RPOg0KKwl1c2UgYSBkaWZmZXJlbnQgaW50 ZXJmYWNlIGZvciBzZXRfZGVidWcoKSAoa2V5d29yZHMpPw0KKwlpbmxpbmUgUHlHQ19JbnNl cnQgYW5kIFB5R0NfUmVtb3ZlIGNhbGxzPw0KKwl0dW5lIHBhcmFtZXRlcnMNCisNCisqLw0K Kw0KKyNpbmNsdWRlICJQeXRob24uaCINCisNCisjaWZuZGVmIFdJVEhfQ1lDTEVfR0MNCisj ZXJyb3IgIllvdSBtdXN0IGRlZmluZSBXSVRIX0NZQ0xFX0dDIHRvIGluY2x1ZGUgdGhpcyBt b2R1bGUiDQorI2VuZGlmDQorDQorLyogbWFnaWMgZ2NfcmVmcyB2YWx1ZSAqLw0KKyNkZWZp bmUgR0NfTU9WRUQgLTENCisNCisNCisvKioqIEdsb2JhbCBHQyBzdGF0ZSAqKiovDQorDQor LyogbGlua2VkIGxpc3RzIG9mIGNvbnRhaW5lciBvYmplY3RzICovDQorc3RhdGljIFB5R0NJ bmZvIGdlbmVyYXRpb24wID0geyZnZW5lcmF0aW9uMCwgJmdlbmVyYXRpb24wLCAwfTsNCitz dGF0aWMgUHlHQ0luZm8gZ2VuZXJhdGlvbjEgPSB7JmdlbmVyYXRpb24xLCAmZ2VuZXJhdGlv bjEsIDB9Ow0KK3N0YXRpYyBQeUdDSW5mbyBnZW5lcmF0aW9uMiA9IHsmZ2VuZXJhdGlvbjIs ICZnZW5lcmF0aW9uMiwgMH07DQorc3RhdGljIGludCBnZW5lcmF0aW9uID0gMDsgLyogY3Vy cmVudCBnZW5lcmF0aW9uIGJlaW5nIGNvbGxlY3RlZCAqLw0KKw0KKy8qIGNvbGxlY3Rpb24g ZnJlcXVlbmNpZXMsIFhYWCB0dW5lIHRoZXNlICovDQorc3RhdGljIGludCB0aHJlc2hvbGQw ID0gMTAwOyAvKiBuZXQgbmV3IGNvbnRhaW5lcnMgYmVmb3JlIGNvbGxlY3Rpb24gKi8NCitz dGF0aWMgaW50IHRocmVzaG9sZDEgPSAxMDsgIC8qIGdlbmVyYXRpb24wIGNvbGxlY3Rpb25z IGJlZm9yZSBjb2xsZWN0aW5nIDEgKi8NCitzdGF0aWMgaW50IHRocmVzaG9sZDIgPSAxMDsg IC8qIGdlbmVyYXRpb24xIGNvbGxlY3Rpb25zIGJlZm9yZSBjb2xsZWN0aW5nIDIgKi8NCisN CisvKiBuZXQgbmV3IG9iamVjdHMgYWxsb2NhdGVkIHNpbmNlIGxhc3QgY29sbGVjdGlvbiAq Lw0KK3N0YXRpYyBpbnQgYWxsb2NhdGVkID0gMDsNCisNCisvKiBzZXQgZm9yIGRlYnVnZ2lu ZyBpbmZvcm1hdGlvbiAqLw0KKyNkZWZpbmUgREVCVUdfU1RBVFMJCSgxPDwwKSAvKiBwcmlu dCBjb2xsZWN0aW9uIHN0YXRpc3RpY3MgKi8NCisjZGVmaW5lIERFQlVHX0NPTExFQ1RBQkxF CSgxPDwxKSAvKiBwcmludCBjb2xsZWN0YWJsZSBvYmplY3RzICovDQorI2RlZmluZSBERUJV R19VTkNPTExFQ1RBQkxFCSgxPDwyKSAvKiBwcmludCB1bmNvbGxlY3RhYmxlIG9iamVjdHMg Ki8NCisjZGVmaW5lIERFQlVHX0lOU1RBTkNFUwkJKDE8PDMpIC8qIHByaW50IGluc3RhbmNl cyAqLw0KKyNkZWZpbmUgREVCVUdfT0JKRUNUUwkJKDE8PDQpIC8qIHByaW50IG90aGVyIG9i amVjdHMgKi8NCisjZGVmaW5lIERFQlVHX0xFQUsJCURFQlVHX0NPTExFQ1RBQkxFIHwgXA0K KwkJCQlERUJVR19VTkNPTExFQ1RBQkxFIHwgXA0KKwkJCQlERUJVR19JTlNUQU5DRVMgfCBc DQorCQkJCURFQlVHX09CSkVDVFMNCitzdGF0aWMgaW50IGRlYnVnID0gREVCVUdfTEVBSzsN CisNCisvKiBsaXN0IG9mIHVuY29sbGVjdGFibGUgb2JqZWN0cyAqLw0KK3N0YXRpYyBQeU9i amVjdCAqZ2FyYmFnZSA9IE5VTEw7DQorDQorDQorLyoqKiBsaXN0IGZ1bmN0aW9ucyAoc2hv dWxkIHByb2JhYmx5IGJlIG1hY3Jvcywgc3R1cGlkIGNvbXBpbGVycykgKioqLw0KKw0KK3N0 YXRpYyB2b2lkDQorTElTVF9JTklUKFB5R0NJbmZvICpsaXN0KQ0KK3sNCisJbGlzdC0+Z2Nf cHJldiA9IGxpc3Q7DQorCWxpc3QtPmdjX25leHQgPSBsaXN0Ow0KK30NCisNCitzdGF0aWMg dm9pZA0KK0xJU1RfQVBQRU5EKFB5R0NJbmZvICpub2RlLCBQeUdDSW5mbyAqbGlzdCkNCit7 DQorCW5vZGUtPmdjX25leHQgPSBsaXN0Ow0KKwlub2RlLT5nY19wcmV2ID0gbGlzdC0+Z2Nf cHJldjsNCisJbm9kZS0+Z2NfcHJldi0+Z2NfbmV4dCA9IG5vZGU7DQorCWxpc3QtPmdjX3By ZXYgPSBub2RlOw0KK30NCisNCitzdGF0aWMgdm9pZA0KK0xJU1RfUkVNT1ZFKFB5R0NJbmZv ICpub2RlKQ0KK3sNCisJbm9kZS0+Z2NfcHJldi0+Z2NfbmV4dCA9IG5vZGUtPmdjX25leHQ7 DQorCW5vZGUtPmdjX25leHQtPmdjX3ByZXYgPSBub2RlLT5nY19wcmV2Ow0KK30NCisNCitz dGF0aWMgdm9pZCANCitMSVNUX01PVkUoUHlHQ0luZm8gKmZyb20sIFB5R0NJbmZvICp0bykN Cit7DQorCWlmIChmcm9tLT5nY19uZXh0ID09IGZyb20pIHsNCisJCS8qIGVtcHR5IGZyb20g bGlzdCAqLw0KKwkJTElTVF9JTklUKHRvKTsNCisJfSBlbHNlIHsNCisJCXRvLT5nY19uZXh0 ID0gZnJvbS0+Z2NfbmV4dDsNCisJCXRvLT5nY19uZXh0LT5nY19wcmV2ID0gdG87DQorCQl0 by0+Z2NfcHJldiA9IGZyb20tPmdjX3ByZXY7DQorCQl0by0+Z2NfcHJldi0+Z2NfbmV4dCA9 IHRvOw0KKwl9DQorCUxJU1RfSU5JVChmcm9tKTsNCit9DQorDQorLyogYXBwZW5kIGEgbGlz dCBvbnRvIGFub3RoZXIgbGlzdCAqLw0KK3N0YXRpYyB2b2lkDQorTElTVF9MQVBQRU5EKFB5 R0NJbmZvICpmcm9tLCBQeUdDSW5mbyAqdG8pDQorew0KKwlQeUdDSW5mbyAqdGFpbDsNCisJ aWYgKGZyb20tPmdjX25leHQgIT0gZnJvbSkgew0KKwkJdGFpbCA9IHRvLT5nY19wcmV2Ow0K KwkJdGFpbC0+Z2NfbmV4dCA9IGZyb20tPmdjX25leHQ7DQorCQl0YWlsLT5nY19uZXh0LT5n Y19wcmV2ID0gdGFpbDsNCisJCXRvLT5nY19wcmV2ID0gZnJvbS0+Z2NfcHJldjsNCisJCXRv LT5nY19wcmV2LT5nY19uZXh0ID0gdG87DQorCX0NCisJTElTVF9JTklUKGZyb20pOw0KK30N CisNCitzdGF0aWMgbG9uZw0KK0xJU1RfU0laRShQeUdDSW5mbyAqbGlzdCkNCit7DQorCVB5 R0NJbmZvICpnYzsNCisJbG9uZyBuID0gMDsNCisJZm9yIChnYyA9IGxpc3QtPmdjX25leHQ7 IGdjICE9IGxpc3Q7IGdjID0gZ2MtPmdjX25leHQpIHsNCisJCW4rKzsNCisJfQ0KKwlyZXR1 cm4gbjsNCit9DQorDQorDQorI2lmZGVmIERFQlVHDQorc3RhdGljIHZvaWQNCitsaXN0X3By aW50KFB5R0NJbmZvICpsaXN0KSB7DQorCVB5R0NJbmZvICpvcCA9IGxpc3Q7DQorCWRvIHsN CisJCXByaW50ZigiJXggJXggJXggJWRcbiIsIChsb25nKW9wLCAobG9uZylvcC0+Z2NfcHJl diwgDQorCQkJCShsb25nKW9wLT5nY19uZXh0LCAobG9uZylvcC0+Z2NfcmVmcyk7DQorDQor CQlvcCA9IG9wLT5nY19uZXh0Ow0KKwl9IHdoaWxlIChvcCAhPSBsaXN0KTsNCit9DQorI2Vu ZGlmDQorDQorLyoqKiBlbmQgb2YgbGlzdCBzdHVmZiAqKiovDQorDQorDQorLyogU2V0IGFs bCBnY19yZWZzID0gb2JfcmVmY250ICovDQorc3RhdGljIHZvaWQNCit1cGRhdGVfcmVmcyhQ eUdDSW5mbyAqY29udGFpbmVycykNCit7DQorCVB5R0NJbmZvICpnYyA9IGNvbnRhaW5lcnMt PmdjX25leHQ7DQorCWZvciAoOyBnYyAhPSBjb250YWluZXJzOyBnYz1nYy0+Z2NfbmV4dCkg ew0KKwkJZ2MtPmdjX3JlZnMgPSBQWV9HQ09CSihnYyktPm9iX3JlZmNudDsNCisJfQ0KK30N CisNCitzdGF0aWMgaW50DQordmlzaXRfZGVjcmVmKFB5T2JqZWN0ICpvcCwgdm9pZCAqZGF0 YSkNCit7DQorCWlmIChvcCAmJiBQWV9JU0dDKG9wKSkgew0KKwkJUFlfR0NJTkZPX1VOU0FG RShvcCktPmdjX3JlZnMtLTsNCisJfQ0KKwlyZXR1cm4gMTsNCit9DQorDQorLyogU3VidHJh Y3QgaW50ZXJuYWwgcmVmZXJlbmNlcyBmcm9tIGdjX3JlZnMgKi8NCitzdGF0aWMgdm9pZA0K K3N1YnRyYWN0X3JlZnMoUHlHQ0luZm8gKmNvbnRhaW5lcnMpDQorew0KKwlyZWN1cnNlcHJv YyByZWN1cnNlOw0KKwlQeUdDSW5mbyAqZ2MgPSBjb250YWluZXJzLT5nY19uZXh0Ow0KKwlm b3IgKDsgZ2MgIT0gY29udGFpbmVyczsgZ2M9Z2MtPmdjX25leHQpIHsNCisJCXJlY3Vyc2Ug PSBQWV9HQ09CSihnYyktPm9iX3R5cGUtPnRwX3JlY3Vyc2U7DQorCQkodm9pZCkgcmVjdXJz ZShQWV9HQ09CSihnYyksDQorCQkJICAgICAgICh2aXNpdHByb2MpdmlzaXRfZGVjcmVmLA0K KwkJCSAgICAgICBOVUxMKTsNCisJfQ0KK30NCisNCisvKiBBcHBlbmQgb2JqZWN0cyB3aXRo IGdjX3JlZnMgPiAwIHRvIHJvb3RzIGxpc3QgKi8NCitzdGF0aWMgdm9pZA0KK21vdmVfcm9v dHMoUHlHQ0luZm8gKmNvbnRhaW5lcnMsIFB5R0NJbmZvICpyb290cykNCit7DQorCVB5R0NJ bmZvICpuZXh0Ow0KKwlQeUdDSW5mbyAqZ2MgPSBjb250YWluZXJzLT5nY19uZXh0Ow0KKwl3 aGlsZSAoZ2MgIT0gY29udGFpbmVycykgew0KKwkJbmV4dCA9IGdjLT5nY19uZXh0Ow0KKwkJ aWYgKGdjLT5nY19yZWZzID4gMCkgew0KKwkJCUxJU1RfUkVNT1ZFKGdjKTsNCisJCQlMSVNU X0FQUEVORChnYywgcm9vdHMpOw0KKwkJCWdjLT5nY19yZWZzID0gR0NfTU9WRUQ7DQorCQl9 DQorCQlnYyA9IG5leHQ7DQorCX0NCit9DQorDQorc3RhdGljIGludA0KK3Zpc2l0X3JlYWNo YWJsZShQeU9iamVjdCAqb3AsIFB5R0NJbmZvICpyb290cykNCit7DQorCVB5R0NJbmZvICpn YyA9IFBZX0dDSU5GTyhvcCk7DQorCWlmIChnYyAmJiBnYy0+Z2NfcmVmcyAhPSBHQ19NT1ZF RCkgew0KKwkJTElTVF9SRU1PVkUoZ2MpOw0KKwkJTElTVF9BUFBFTkQoZ2MsIHJvb3RzKTsN CisJCWdjLT5nY19yZWZzID0gR0NfTU9WRUQ7DQorCX0NCisJcmV0dXJuIDE7DQorfQ0KKw0K Ky8qIE1vdmUgb2JqZWN0cyByZWZlcmVuY2VkIGZyb20gcmVhY2hhYmxlIHRvIHJlYWNoYWJs ZSBzZXQuICovDQorc3RhdGljIHZvaWQNCittb3ZlX3Jvb3RfcmVhY2hhYmxlKFB5R0NJbmZv ICpyZWFjaGFibGUpDQorew0KKwlyZWN1cnNlcHJvYyByZWN1cnNlOw0KKwlQeUdDSW5mbyAq Z2MgPSByZWFjaGFibGUtPmdjX25leHQ7DQorCWZvciAoOyBnYyAhPSByZWFjaGFibGU7IGdj PWdjLT5nY19uZXh0KSB7DQorCQkvKiBjYXJlZnVsLCByZWFjaGFibGUgbGlzdCBpcyBncm93 aW5nIGhlcmUgKi8NCisJCVB5T2JqZWN0ICpvcCA9IFBZX0dDT0JKKGdjKTsNCisJCXJlY3Vy c2UgPSBvcC0+b2JfdHlwZS0+dHBfcmVjdXJzZTsNCisJCSh2b2lkKSByZWN1cnNlKG9wLA0K KwkJCSAgICAgICAodmlzaXRwcm9jKXZpc2l0X3JlYWNoYWJsZSwNCisJCQkgICAgICAgKHZv aWQgKilyZWFjaGFibGUpOw0KKwl9DQorfQ0KKw0KKy8qIG1vdmUgYWxsIG9iamVjdHMgd2l0 aCBmaW5hbGl6ZXJzIChpbnN0YW5jZXMgd2l0aCBfX2RlbF9fKSAqLw0KK3N0YXRpYyB2b2lk DQorbW92ZV9maW5hbGl6ZXJzKFB5R0NJbmZvICp1bnJlYWNoYWJsZSwgUHlHQ0luZm8gKmZp bmFsaXplcnMpDQorew0KKwlQeUdDSW5mbyAqbmV4dDsNCisJUHlHQ0luZm8gKmdjID0gdW5y ZWFjaGFibGUtPmdjX25leHQ7DQorCXN0YXRpYyBQeU9iamVjdCAqZGVsc3RyOw0KKwlpZiAo ZGVsc3RyID09IE5VTEwpIHsNCisJCWRlbHN0ciA9IFB5U3RyaW5nX0ludGVybkZyb21TdHJp bmcoIl9fZGVsX18iKTsNCisJfQ0KKwlmb3IgKDsgZ2MgIT0gdW5yZWFjaGFibGU7IGdjPW5l eHQpIHsNCisJCVB5T2JqZWN0ICpvcCA9IFBZX0dDT0JKKGdjKTsNCisJCW5leHQgPSBnYy0+ Z2NfbmV4dDsNCisJCWlmIChQeUluc3RhbmNlX0NoZWNrKG9wKSAmJiBQeU9iamVjdF9IYXNB dHRyKG9wLCBkZWxzdHIpKSB7DQorCQkJTElTVF9SRU1PVkUoZ2MpOw0KKwkJCUxJU1RfQVBQ RU5EKGdjLCBmaW5hbGl6ZXJzKTsNCisJCX0NCisJfQ0KK30NCisNCisNCisvKiBjYWxsZWQg YnkgdHBfcmVjdXJzZSAqLw0KK3N0YXRpYyBpbnQNCit2aXNpdF9maW5hbGl6ZXJfcmVhY2hh YmxlKFB5T2JqZWN0ICpvcCwgUHlHQ0luZm8gKmZpbmFsaXplcnMpDQorew0KKwlQeUdDSW5m byAqZ2MgPSBQWV9HQ0lORk8ob3ApOw0KKwlpZiAoZ2MgJiYgZ2MtPmdjX3JlZnMgIT0gR0Nf TU9WRUQpIHsNCisJCUxJU1RfUkVNT1ZFKGdjKTsNCisJCUxJU1RfQVBQRU5EKGdjLCBmaW5h bGl6ZXJzKTsNCisJCWdjLT5nY19yZWZzID0gR0NfTU9WRUQ7DQorCX0NCisJcmV0dXJuIDE7 DQorfQ0KKw0KKy8qIE1vdmUgb2JqZWN0cyByZWZlcmVuY2VkIGZyb20gcm9vdHMgdG8gcm9v dHMgKi8NCitzdGF0aWMgdm9pZA0KK21vdmVfZmluYWxpemVyX3JlYWNoYWJsZShQeUdDSW5m byAqZmluYWxpemVycykNCit7DQorCXJlY3Vyc2Vwcm9jIHJlY3Vyc2U7DQorCVB5R0NJbmZv ICpnYyA9IGZpbmFsaXplcnMtPmdjX25leHQ7DQorCWZvciAoOyBnYyAhPSBmaW5hbGl6ZXJz OyBnYz1nYy0+Z2NfbmV4dCkgew0KKwkJLyogY2FyZWZ1bCwgZmluYWxpemVycyBsaXN0IGlz IGdyb3dpbmcgaGVyZSAqLw0KKwkJcmVjdXJzZSA9IFBZX0dDT0JKKGdjKS0+b2JfdHlwZS0+ dHBfcmVjdXJzZTsNCisJCSh2b2lkKSByZWN1cnNlKFBZX0dDT0JKKGdjKSwgDQorCQkJICAg ICAgICh2aXNpdHByb2MpdmlzaXRfZmluYWxpemVyX3JlYWNoYWJsZSwNCisJCQkgICAgICAg KHZvaWQgKilmaW5hbGl6ZXJzKTsNCisJfQ0KK30NCisNCitzdGF0aWMgdm9pZA0KK2RlYnVn X2luc3RhbmNlKFB5T2JqZWN0ICpvdXRwdXQsIGNoYXIgKm1zZywgUHlJbnN0YW5jZU9iamVj dCAqaW5zdCkNCit7DQorCWNoYXIgYnVmWzIwMF07DQorCWNoYXIgKmNuYW1lOw0KKwkvKiBi ZSBjYXJlZnVsIG5vdCB0byBjcmVhdGUgbmV3IGRpY3Rpb25hcmllcyAqLw0KKwlQeU9iamVj dCAqY2xhc3NuYW1lID0gaW5zdC0+aW5fY2xhc3MtPmNsX25hbWU7DQorCWlmIChjbGFzc25h bWUgIT0gTlVMTCAmJiBQeVN0cmluZ19DaGVjayhjbGFzc25hbWUpKQ0KKwkJY25hbWUgPSBQ eVN0cmluZ19Bc1N0cmluZyhjbGFzc25hbWUpOw0KKwllbHNlDQorCQljbmFtZSA9ICI/IjsN CisJc3ByaW50ZihidWYsICJnYzogJXM8JS4xMDBzIGluc3RhbmNlIGF0ICVseD5cbiIsIA0K KwkJCW1zZywgY25hbWUsIChsb25nKWluc3QpOw0KKwlQeUZpbGVfV3JpdGVTdHJpbmcoYnVm LCBvdXRwdXQpOw0KK30NCisNCitzdGF0aWMgdm9pZA0KK2RlYnVnX2N5Y2xlKFB5T2JqZWN0 ICpvdXRwdXQsIGNoYXIgKm1zZywgUHlPYmplY3QgKm9wKQ0KK3sNCisJaWYgKChkZWJ1ZyAm IERFQlVHX0lOU1RBTkNFUykgJiYgUHlJbnN0YW5jZV9DaGVjayhvcCkpIHsNCisJCWRlYnVn X2luc3RhbmNlKG91dHB1dCwgbXNnLCAoUHlJbnN0YW5jZU9iamVjdCAqKW9wKTsNCisJfSBl bHNlIGlmIChkZWJ1ZyAmIERFQlVHX09CSkVDVFMpIHsNCisJCWNoYXIgYnVmWzIwMF07DQor CQlzcHJpbnRmKGJ1ZiwgImdjOiAlczxPYmplY3QgMHgleD5cbiIsIG1zZywgKGxvbmcpb3Ap Ow0KKwkJUHlGaWxlX1dyaXRlU3RyaW5nKGJ1Ziwgb3V0cHV0KTsNCisJfQ0KK30NCisNCisv KiBIYW5kbGUgdW5jb2xsZWN0YWJsZSBnYXJiYWdlIChjeWNsZXMgd2l0aCBmaW5hbGl6ZXJz KS4gKi8NCitzdGF0aWMgdm9pZA0KK2hhbmRsZV9maW5hbGl6ZXJzKFB5R0NJbmZvICpmaW5h bGl6ZXJzLCBQeUdDSW5mbyAqb2xkKQ0KK3sNCisJUHlHQ0luZm8gKmdjOw0KKwlpZiAoZ2Fy YmFnZSA9PSBOVUxMKSB7DQorCQlnYXJiYWdlID0gUHlMaXN0X05ldygwKTsNCisJfQ0KKwlm b3IgKGdjID0gZmluYWxpemVycy0+Z2NfbmV4dDsgZ2MgIT0gZmluYWxpemVyczsNCisJCQln YyA9IGZpbmFsaXplcnMtPmdjX25leHQpIHsNCisJCVB5T2JqZWN0ICpvcCA9IFBZX0dDT0JK KGdjKTsNCisJCS8qIEFkZCBhbGwgaW5zdGFuY2VzIHRvIGEgUHl0aG9uIGFjY2Vzc2libGUg bGlzdCBvZiBnYXJiYWdlICovDQorCQlpZiAoUHlJbnN0YW5jZV9DaGVjayhvcCkpIHsNCisJ CQlQeUxpc3RfQXBwZW5kKGdhcmJhZ2UsIG9wKTsNCisJCX0NCisJCS8qIFdlIGFzc3VtZSB0 aGF0IGFsbCBvYmplY3RzIGluIGZpbmFsaXplcnMgYXJlIHJlYWNoYWJsZSBmcm9tDQorCQkg KiBpbnN0YW5jZXMuICBPbmNlIHdlIGFkZCB0aGUgaW5zdGFuY2VzIHRvIHRoZSBnYXJiYWdl IGxpc3QNCisJCSAqIGV2ZXJ5dGhpbmcgaXMgcmVhY2hhYmxlIGZyb20gUHl0aG9uIGFnYWlu LiAqLw0KKwkJTElTVF9SRU1PVkUoZ2MpOw0KKwkJTElTVF9BUFBFTkQoZ2MsIG9sZCk7DQor CX0NCit9DQorDQorLyogQnJlYWsgcmVmZXJlbmNlIGN5Y2xlcyBieSBjbGVhcmluZyB0aGUg Y29udGFpbmVycyBpbnZvbHZlZC4gIFRoaXMgaXMNCisgKiB0cmlja3kgYnVzaW5lc3MgYXMg dGhlIGxpc3RzIGNhbiBiZSBjaGFuZ2luZyBhbmQgd2UgZG9uJ3Qga25vdyB3aGljaA0KKyAq IG9iamVjdHMgbWF5IGJlIGZyZWVkLiAgSXQgaXMgcG9zc2libGUgSSBzY3Jld2VkIHNvbWV0 aGluZyB1cCBoZXJlLiAqLw0KK3N0YXRpYyB2b2lkDQorZGVsZXRlX2dhcmJhZ2UoUHlHQ0lu Zm8gKnVucmVhY2hhYmxlLCBQeUdDSW5mbyAqb2xkKQ0KK3sNCisJaW5xdWlyeSBjbGVhcjsN CisNCisJd2hpbGUgKHVucmVhY2hhYmxlLT5nY19uZXh0ICE9IHVucmVhY2hhYmxlKSB7DQor CQlQeUdDSW5mbyAqZ2MgPSB1bnJlYWNoYWJsZS0+Z2NfbmV4dDsNCisJCVB5T2JqZWN0ICpv cCA9IFBZX0dDT0JKKGdjKTsNCisJCWlmICgoY2xlYXIgPSBvcC0+b2JfdHlwZS0+dHBfY2xl YXIpICE9IE5VTEwpIHsNCisJCQlQeV9JTkNSRUYob3ApOw0KKwkJCWNsZWFyKChQeU9iamVj dCAqKW9wKTsNCisJCQlQeV9ERUNSRUYob3ApOw0KKwkJfQ0KKwkJLyogb25seSB0cnkgdG8g Y2FsbCB0cF9jbGVhciBvbmNlIGZvciBlYWNoIG9iamVjdCAqLw0KKwkJaWYgKHVucmVhY2hh YmxlLT5nY19uZXh0ID09IGdjKSB7DQorCQkJLyogc3RpbGwgYWxpdmUsIG1vdmUgaXQsIGl0 IG1heSBkaWUgbGF0ZXIgKi8NCisJCQlMSVNUX1JFTU9WRShnYyk7DQorCQkJTElTVF9BUFBF TkQoZ2MsIG9sZCk7DQorCQl9DQorCX0NCit9DQorDQorLyogVGhpcyBpcyB0aGUgbWFpbiBm dW5jdGlvbi4gIFJlYWQgdGhpcyB0byB1bmRlcnN0YW5kIGhvdyB0aGUNCisgKiBjb2xsZWN0 aW9uIHByb2Nlc3Mgd29ya3MuICovDQorc3RhdGljIGxvbmcNCitjb2xsZWN0KFB5R0NJbmZv ICp5b3VuZywgUHlHQ0luZm8gKm9sZCkNCit7DQorCWxvbmcgbiA9IDA7DQorCWxvbmcgbSA9 IDA7DQorCVB5R0NJbmZvIHJlYWNoYWJsZTsNCisJUHlHQ0luZm8gdW5yZWFjaGFibGU7DQor CVB5R0NJbmZvIGZpbmFsaXplcnM7DQorCVB5R0NJbmZvICpnYzsNCisJUHlPYmplY3QgKm91 dHB1dCA9IE5VTEw7DQorDQorCWlmIChkZWJ1Zykgew0KKwkJb3V0cHV0ID0gUHlTeXNfR2V0 T2JqZWN0KCJzdGRlcnIiKTsNCisJfQ0KKwlpZiAoZGVidWcgJiBERUJVR19TVEFUUykgew0K KwkJY2hhciBidWZbMTAwXTsNCisJCXNwcmludGYoYnVmLCAiZ2M6IGNvbGxlY3RpbmcgZ2Vu ZXJhdGlvbiAlZC4uLlxuIiwgZ2VuZXJhdGlvbik7DQorCQlQeUZpbGVfV3JpdGVTdHJpbmco YnVmLG91dHB1dCk7DQorCQlzcHJpbnRmKGJ1ZiwgImdjOiBvYmplY3RzIGluIGVhY2ggZ2Vu ZXJhdGlvbjogJWQgJWQgJWRcbiIsDQorCQkJTElTVF9TSVpFKCZnZW5lcmF0aW9uMCksDQor CQkJTElTVF9TSVpFKCZnZW5lcmF0aW9uMSksDQorCQkJTElTVF9TSVpFKCZnZW5lcmF0aW9u MikpOw0KKwkJUHlGaWxlX1dyaXRlU3RyaW5nKGJ1ZixvdXRwdXQpOw0KKwl9DQorDQorCS8q IFVzaW5nIG9iX3JlZmNudCBhbmQgZ2NfcmVmcywgY2FsY3VsYXRlIHdoaWNoIG9iamVjdHMg aW4gdGhlDQorCSAqIGNvbnRhaW5lciBzZXQgYXJlIHJlYWNoYWJsZSBmcm9tIG91dHNpZGUg dGhlIHNldCAoaWUuIGhhdmUgYQ0KKwkgKiByZWZjb3VudCBncmVhdGVyIHRoYW4gMCB3aGVu IGFsbCB0aGUgcmVmZXJlbmNlcyB3aXRoaW4gdGhlDQorCSAqIHNldCBhcmUgdGFrZW4gaW50 byBhY2NvdW50ICovDQorCXVwZGF0ZV9yZWZzKHlvdW5nKTsNCisJc3VidHJhY3RfcmVmcyh5 b3VuZyk7DQorDQorCS8qIE1vdmUgZXZlcnl0aGluZyByZWFjaGFibGUgZnJvbSBvdXRzaWRl IHRoZSBzZXQgaW50byB0aGUNCisJICogcmVhY2hhYmxlIHNldCAoaWUuIGdjX3JlZnMgPiAw KS4gIE5leHQsIG1vdmUgZXZlcnl0aGluZw0KKwkgKiByZWFjaGFibGUgZnJvbSBvYmplY3Rz IGluIHRoZSByZWFjaGFibGUgc2V0LiAqLw0KKwlMSVNUX0lOSVQoJnJlYWNoYWJsZSk7DQor CW1vdmVfcm9vdHMoeW91bmcsICZyZWFjaGFibGUpOw0KKwltb3ZlX3Jvb3RfcmVhY2hhYmxl KCZyZWFjaGFibGUpOw0KKw0KKwkvKiBtb3ZlIHVucmVhY2hhYmxlIG9iamVjdHMgdG8gYSB0 ZW1wb3JhcnkgbGlzdCwgbmV3IG9iamVjdHMgY2FuIGJlDQorCSAqIGFsbG9jYXRlZCBhZnRl ciB0aGlzIHBvaW50ICovDQorCUxJU1RfSU5JVCgmdW5yZWFjaGFibGUpOw0KKwlMSVNUX01P VkUoeW91bmcsICZ1bnJlYWNoYWJsZSk7DQorCS8vTElTVF9JTklUKHlvdW5nKTsNCisNCisJ LyogbW92ZSByZWFjaGFibGUgb2JqZWN0cyB0byBuZXh0IGdlbmVyYXRpb24gKi8NCisJTElT VF9MQVBQRU5EKCZyZWFjaGFibGUsIG9sZCk7DQorDQorCS8qIE1vdmUgb2JqZWN0cyByZWFj aGFibGUgZnJvbSBmaW5hbGl6ZXJzLCB3ZSBjYW4ndCBzYWZlbHkgZGVsZXRlDQorCSAqIHRo ZW0uICBQeXRob24gcHJvZ3JhbW1lcnMgc2hvdWxkIHRha2UgY2FyZSBub3QgdG8gY3JlYXRl IHN1Y2gNCisJICogdGhpbmdzLiAgRm9yIFB5dGhvbiBmaW5hbGl6ZXJzIG1lYW5zIGluc3Rh bmNlIG9iamVjdHMgd2l0aA0KKwkgKiBfX2RlbF9fIG1ldGhvZHMuICovDQorCUxJU1RfSU5J VCgmZmluYWxpemVycyk7DQorCW1vdmVfZmluYWxpemVycygmdW5yZWFjaGFibGUsICZmaW5h bGl6ZXJzKTsNCisJbW92ZV9maW5hbGl6ZXJfcmVhY2hhYmxlKCZmaW5hbGl6ZXJzKTsNCisN CisJLyogQ29sbGVjdCBzdGF0aXN0aWNzIG9uIGNvbGxlY3RhYmxlIG9iamVjdHMgZm91bmQg YW5kIHByaW50DQorCSAqIGRlYnVnZ2luZyBpbmZvcm1hdGlvbi4gKi8NCisJZm9yIChnYyA9 IHVucmVhY2hhYmxlLmdjX25leHQ7IGdjICE9ICZ1bnJlYWNoYWJsZTsNCisJCQlnYyA9IGdj LT5nY19uZXh0KSB7DQorCQltKys7DQorCQlpZiAob3V0cHV0ICE9IE5VTEwgJiYgKGRlYnVn ICYgREVCVUdfQ09MTEVDVEFCTEUpKSB7DQorCQkJZGVidWdfY3ljbGUob3V0cHV0LCAiY29s bGVjdGFibGUgIiwgUFlfR0NPQkooZ2MpKTsNCisJCX0NCisJfQ0KKwkvKiBjYWxsIHRwX2Ns ZWFyIG9uIG9iamVjdHMgaW4gdGhlIGNvbGxlY3RhYmxlIHNldC4gIFRoaXMgd2lsbCBjYXVz ZQ0KKwkgKiB0aGUgcmVmZXJlbmNlIGN5Y2xlcyB0byBiZSBicm9rZW4uIEl0IG1heSBhbHNv IGNhdXNlIHNvbWUgb2JqZWN0cyBpbg0KKwkgKiBmaW5hbGl6ZXJzIHRvIGJlIGZyZWVkICov DQorCWRlbGV0ZV9nYXJiYWdlKCZ1bnJlYWNoYWJsZSwgb2xkKTsNCisNCisJLyogQ29sbGVj dCBzdGF0aXN0aWNzIG9uIHVuY29sbGVjdGFibGUgb2JqZWN0cyBmb3VuZCBhbmQgcHJpbnQN CisJICogZGVidWdnaW5nIGluZm9ybWF0aW9uLiAqLw0KKwlmb3IgKGdjID0gZmluYWxpemVy cy5nY19uZXh0OyBnYyAhPSAmZmluYWxpemVyczsNCisJCQlnYyA9IGdjLT5nY19uZXh0KSB7 DQorCQluKys7DQorCQlpZiAob3V0cHV0ICE9IE5VTEwgJiYgKGRlYnVnICYgREVCVUdfVU5D T0xMRUNUQUJMRSkpIHsNCisJCQlkZWJ1Z19jeWNsZShvdXRwdXQsICJ1bmNvbGxlY3RhYmxl ICIsIFBZX0dDT0JKKGdjKSk7DQorCQl9DQorCX0NCisJaWYgKG91dHB1dCAhPSBOVUxMICYm IChkZWJ1ZyAmIERFQlVHX1NUQVRTKSkgew0KKwkJaWYgKG0gPT0gMCAmJiBuID09IDApIHsN CisJCQlQeUZpbGVfV3JpdGVTdHJpbmcoImdjOiBkb25lLlxuIiwgb3V0cHV0KTsNCisJCX0g ZWxzZSB7DQorCQkJY2hhciBidWZbMjAwXTsNCisJCQlzcHJpbnRmKGJ1ZiwNCisJCQkJImdj OiBkb25lLCAlZCB1bnJlYWNoYWJsZSwgJWQgdW5jb2xsZWN0YWJsZS5cbiIsDQorCQkJCW4r bSwgbik7DQorCQkJUHlGaWxlX1dyaXRlU3RyaW5nKGJ1Ziwgb3V0cHV0KTsNCisJCX0NCisJ fQ0KKw0KKwkvKiBBcHBlbmQgaW5zdGFuY2VzIGluIHRoZSB1bmNvbGxlY3RhYmxlIHNldCB0 byBhIFB5dGhvbg0KKwkgKiByZWFjaGFibGUgbGlzdCBvZiBnYXJiYWdlLiAgVGhlIHByb2dy YW1tZXIgaGFzIHRvIGRlYWwgd2l0aA0KKwkgKiB0aGlzIGlmIHRoZXkgaW5zaXN0IG9uIGNy ZWF0aW5nIHRoaXMgdHlwZSBvZiBzdHJ1Y3R1cmUuICovDQorCWhhbmRsZV9maW5hbGl6ZXJz KCZmaW5hbGl6ZXJzLCBvbGQpOw0KKw0KKwlhbGxvY2F0ZWQgPSAwOw0KKwlQeUVycl9DbGVh cigpOyAvKiBpbiBjYXNlIHdyaXRpbmcgdG8gc3lzLnN0ZGVyciBmYWlsZWQgKi8NCisJcmV0 dXJuIG4rbTsNCit9DQorDQorc3RhdGljIGxvbmcNCitjb2xsZWN0X2dlbmVyYXRpb25zKHZv aWQpDQorew0KKwlzdGF0aWMgbG9uZyBjb2xsZWN0aW9uczAgPSAwOw0KKwlzdGF0aWMgbG9u ZyBjb2xsZWN0aW9uczEgPSAwOw0KKwlsb25nIG47DQorDQorDQorCWlmIChjb2xsZWN0aW9u czEgPiB0aHJlc2hvbGQyKSB7DQorCQlnZW5lcmF0aW9uID0gMjsNCisJCUxJU1RfTEFQUEVO RCgmZ2VuZXJhdGlvbjAsICZnZW5lcmF0aW9uMik7DQorCQlMSVNUX0xBUFBFTkQoJmdlbmVy YXRpb24xLCAmZ2VuZXJhdGlvbjIpOw0KKwkJaWYgKGdlbmVyYXRpb24yLmdjX25leHQgIT0g JmdlbmVyYXRpb24yKSB7DQorCQkJbiA9IGNvbGxlY3QoJmdlbmVyYXRpb24yLCAmZ2VuZXJh dGlvbjIpOw0KKwkJfQ0KKwkJY29sbGVjdGlvbnMxID0gMDsNCisJfSBlbHNlIGlmIChjb2xs ZWN0aW9uczAgPiB0aHJlc2hvbGQxKSB7DQorCQlnZW5lcmF0aW9uID0gMTsNCisJCWNvbGxl Y3Rpb25zMSsrOw0KKwkJTElTVF9MQVBQRU5EKCZnZW5lcmF0aW9uMCwgJmdlbmVyYXRpb24x KTsNCisJCWlmIChnZW5lcmF0aW9uMS5nY19uZXh0ICE9ICZnZW5lcmF0aW9uMSkgew0KKwkJ CW4gPSBjb2xsZWN0KCZnZW5lcmF0aW9uMSwgJmdlbmVyYXRpb24yKTsNCisJCX0NCisJCWNv bGxlY3Rpb25zMCA9IDA7DQorCX0gZWxzZSB7DQorCQlnZW5lcmF0aW9uID0gMDsNCisJCWNv bGxlY3Rpb25zMCsrOw0KKwkJaWYgKGdlbmVyYXRpb24wLmdjX25leHQgIT0gJmdlbmVyYXRp b24wKSB7DQorCQkJbiA9IGNvbGxlY3QoJmdlbmVyYXRpb24wLCAmZ2VuZXJhdGlvbjEpOw0K KwkJfQ0KKwl9DQorCXJldHVybiBuOw0KK30NCisNCit2b2lkDQorUHlHQ19JbnNlcnQoUHlP YmplY3QgKm9wKQ0KK3sNCisJLyogY29sbGVjdGlvbiBsb2NrIHNpbmNlIGNvbGxlY3Rpbmcg bWF5IGNhdXNlIGFsbG9jYXRpb25zICovDQorCXN0YXRpYyBpbnQgY29sbGVjdGluZyA9IDA7 DQorDQorI2lmZGVmIERFQlVHDQorCS8qZnByaW50ZihzdGRlcnIsICJJbnNlcnQgMHgleFxu Iiwgb3ApOyovDQorI2VuZGlmDQorCWlmICh0aHJlc2hvbGQwICYmIGFsbG9jYXRlZCA+IHRo cmVzaG9sZDAgJiYgIWNvbGxlY3RpbmcpIHsNCisJCWNvbGxlY3RpbmcrKzsNCisJCWNvbGxl Y3RfZ2VuZXJhdGlvbnMoKTsNCisJCWNvbGxlY3RpbmctLTsNCisJfQ0KKwlhbGxvY2F0ZWQr KzsNCisJTElTVF9BUFBFTkQoUFlfR0NJTkZPKG9wKSwgJmdlbmVyYXRpb24wKTsNCit9DQor DQordm9pZA0KK1B5R0NfUmVtb3ZlKFB5T2JqZWN0ICpvcCkNCit7DQorI2lmZGVmIERFQlVH DQorCS8qZnByaW50ZihzdGRlcnIsICJSZW1vdmUgMHgleFxuIiwgb3ApOyovDQorI2VuZGlm DQorCWlmIChhbGxvY2F0ZWQgPiAwKSB7DQorCQlhbGxvY2F0ZWQtLTsNCisJfQ0KKwlMSVNU X1JFTU9WRShQWV9HQ0lORk8ob3ApKTsNCit9DQorDQorDQorc3RhdGljIGNoYXIgY29sbGVj dF9fZG9jX19bXSA9DQorImNvbGxlY3QoKSAtPiBuXG4iDQorIlxuIg0KKyJSdW4gYSBmdWxs IGNvbGxlY3Rpb24uICBUaGUgbnVtYmVyIG9mIHVucmVhY2hhYmxlIG9iamVjdHMgaXMgcmV0 dXJuZWQuXG4iDQorOw0KKw0KK3N0YXRpYyBQeU9iamVjdCAqDQorUHlfY29sbGVjdChzZWxm LCBhcmdzKQ0KKwlQeU9iamVjdCAqc2VsZjsNCisJUHlPYmplY3QgKmFyZ3M7DQorew0KKwls b25nIG47DQorDQorCWlmKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICIiKSkJLyogY2hlY2sg bm8gYXJncyAqLw0KKwkJcmV0dXJuIE5VTEw7DQorDQorCWdlbmVyYXRpb24gPSAyOw0KKwlM SVNUX0xBUFBFTkQoJmdlbmVyYXRpb24wLCAmZ2VuZXJhdGlvbjIpOw0KKwlMSVNUX0xBUFBF TkQoJmdlbmVyYXRpb24xLCAmZ2VuZXJhdGlvbjIpOw0KKwluID0gY29sbGVjdCgmZ2VuZXJh dGlvbjIsICZnZW5lcmF0aW9uMik7DQorDQorCXJldHVybiBQeV9CdWlsZFZhbHVlKCJpIiwg bik7DQorfQ0KKw0KK3N0YXRpYyBjaGFyIHNldF9kZWJ1Z19fZG9jX19bXSA9IA0KKyJzZXRf ZGVidWcoZmxhZ3MpIC0+IE5vbmVcbiINCisiXG4iDQorIlNldCB0aGUgZ2FyYmFnZSBjb2xs ZWN0aW9uIGRlYnVnZ2luZyBmbGFncy4gRGVidWdnaW5nIGluZm9ybWF0aW9uIGlzXG4iDQor IndyaXR0ZW4gdG8gc3lzLnN0ZGVyci5cbiINCisiXG4iDQorImZsYWdzIGlzIGFuIGludGVn ZXIgYW5kIGNhbiBoYXZlIHRoZSBmb2xsb3dpbmcgYml0cyB0dXJuZWQgb246XG4iDQorIlxu Ig0KKyIgIERFQlVHX1NUQVRTIC0gUHJpbnQgc3RhdGlzdGljcyBkdXJpbmcgY29sbGVjdGlv bi5cbiINCisiICBERUJVR19DT0xMRUNUQUJMRSAtIFByaW50IGNvbGxlY3RhYmxlIG9iamVj dHMgZm91bmQuXG4iDQorIiAgREVCVUdfVU5DT0xMRUNUQUJMRSAtIFByaW50IHVucmVhY2hh YmxlIGJ1dCB1bmNvbGxlY3RhYmxlIG9iamVjdHMgZm91bmQuXG4iDQorIiAgREVCVUdfSU5T VEFOQ0VTIC0gUHJpbnQgaW5zdGFuY2Ugb2JqZWN0cy5cbiINCisiICBERUJVR19PQkpFQ1RT IC0gUHJpbnQgb2JqZWN0cyBvdGhlciB0aGFuIGluc3RhbmNlcy5cbiINCisiICBERUJVR19M RUFLIC0gRGVidWcgbGVha2luZyBwcm9ncmFtcyAoZXZlcnl0aGluZyBidXQgU1RBVFMpLlxu Ig0KKzsNCisNCitzdGF0aWMgUHlPYmplY3QgKg0KK1B5X3NldF9kZWJ1ZyhzZWxmLCBhcmdz KQ0KKwlQeU9iamVjdCAqc2VsZjsNCisJUHlPYmplY3QgKmFyZ3M7DQorew0KKwlpZiAoIVB5 QXJnX1BhcnNlVHVwbGUoYXJncywgImwiLCAmZGVidWcpKQ0KKwkJcmV0dXJuIE5VTEw7DQor DQorCVB5X0lOQ1JFRihQeV9Ob25lKTsNCisJcmV0dXJuIFB5X05vbmU7DQorfQ0KKw0KK3N0 YXRpYyBjaGFyIGdldF9kZWJ1Z19fZG9jX19bXSA9IA0KKyJnZXRfZGVidWcoKSAtPiBmbGFn c1xuIg0KKyJcbiINCisiR2V0IHRoZSBnYXJiYWdlIGNvbGxlY3Rpb24gZGVidWdnaW5nIGZs YWdzLlxuIg0KKzsNCisNCitzdGF0aWMgUHlPYmplY3QgKg0KK1B5X2dldF9kZWJ1ZyhzZWxm LCBhcmdzKQ0KKwlQeU9iamVjdCAqc2VsZjsNCisJUHlPYmplY3QgKmFyZ3M7DQorew0KKwlp ZighUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiIikpCS8qIG5vIGFyZ3MgKi8NCisJCXJldHVy biBOVUxMOw0KKw0KKwlyZXR1cm4gUHlfQnVpbGRWYWx1ZSgiaSIsIGRlYnVnKTsNCit9DQor DQorc3RhdGljIGNoYXIgc2V0X3RocmVzaF9fZG9jX19bXSA9DQorInNldF90aHJlc2hvbGQo dGhyZXNob2xkMCwgW3RocmVob2xkMSwgdGhyZXNob2xkMl0pIC0+IE5vbmVcbiINCisiXG4i DQorIlNldHMgdGhlIGNvbGxlY3Rpb24gdGhyZXNob2xkcy4gIFNldHRpbmcgdGhyZXNob2xk MCB0byB6ZXJvIGRpc2FibGVzXG4iDQorImNvbGxlY3Rpb24uXG4iDQorOw0KKw0KK3N0YXRp YyBQeU9iamVjdCAqDQorUHlfc2V0X3RocmVzaChzZWxmLCBhcmdzKQ0KKwlQeU9iamVjdCAq c2VsZjsNCisJUHlPYmplY3QgKmFyZ3M7DQorew0KKwlpZiAoIVB5QXJnX1BhcnNlVHVwbGUo YXJncywgIml8aWkiLCAmdGhyZXNob2xkMCwgDQorCQkJCSZ0aHJlc2hvbGQxLCAmdGhyZXNo b2xkMikpDQorCQlyZXR1cm4gTlVMTDsNCisNCisJUHlfSU5DUkVGKFB5X05vbmUpOw0KKwly ZXR1cm4gUHlfTm9uZTsNCit9DQorDQorc3RhdGljIGNoYXIgZ2V0X3RocmVzaF9fZG9jX19b XSA9DQorImdldF90cmVzaG9sZCgpIC0+ICh0aHJlc2hvbGQwLCB0aHJlc2hvbGQxLCB0aHJl c2hvbGQyKVxuIg0KKyJcbiINCisiUmV0dXJuIHRoZSBjdXJyZW50IGNvbGxlY3Rpb24gdGhy ZXNob2xkc1xuIg0KKzsNCisNCitzdGF0aWMgUHlPYmplY3QgKg0KK1B5X2dldF90aHJlc2go c2VsZiwgYXJncykNCisJUHlPYmplY3QgKnNlbGY7DQorCVB5T2JqZWN0ICphcmdzOw0KK3sN CisJaWYoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIiIpKQkvKiBubyBhcmdzICovDQorCQly ZXR1cm4gTlVMTDsNCisNCisJcmV0dXJuIFB5X0J1aWxkVmFsdWUoIihpaWkpIiwgdGhyZXNo b2xkMCwgdGhyZXNob2xkMSwgdGhyZXNob2xkMik7DQorfQ0KKw0KKw0KK3N0YXRpYyBjaGFy IGdjX19kb2NfXyBbXSA9DQorIlRoaXMgbW9kdWxlIHByb3ZpZGVzIGFjY2VzcyB0byB0aGUg Z2FyYmFnZSBjb2xsZWN0b3IgZm9yIHJlZmVyZW5jZSBjeWNsZXMuXG4iDQorIlxuIg0KKyJj b2xsZWN0KCkgLS0gRG8gYSBmdWxsIGNvbGxlY3Rpb24gcmlnaHQgbm93LlxuIg0KKyJzZXRf ZGVidWcoKSAtLSBTZXQgZGVidWdnaW5nIGZsYWdzLlxuIg0KKyJnZXRfZGVidWcoKSAtLSBH ZXQgZGVidWdnaW5nIGZsYWdzLlxuIg0KKyJzZXRfdGhyZXNob2xkKCkgLS0gU2V0IHRoZSBj b2xsZWN0aW9uIHRocmVzaG9sZHMuXG4iDQorImdldF90aHJlc2hvbGQoKSAtLSBSZXR1cm4g dGhlIGN1cnJlbnQgdGhlIGNvbGxlY3Rpb24gdGhyZXNob2xkcy5cbiINCis7DQorDQorc3Rh dGljIFB5TWV0aG9kRGVmIEdjTWV0aG9kc1tdID0gew0KKwl7InNldF9kZWJ1ZyIsCQlQeV9z ZXRfZGVidWcsICBNRVRIX1ZBUkFSR1MsIHNldF9kZWJ1Z19fZG9jX199LA0KKwl7ImdldF9k ZWJ1ZyIsCQlQeV9nZXRfZGVidWcsICBNRVRIX1ZBUkFSR1MsIGdldF9kZWJ1Z19fZG9jX199 LA0KKwl7InNldF90aHJlc2hvbGQiLAlQeV9zZXRfdGhyZXNoLCBNRVRIX1ZBUkFSR1MsIHNl dF90aHJlc2hfX2RvY19ffSwNCisJeyJnZXRfdGhyZXNob2xkIiwJUHlfZ2V0X3RocmVzaCwg TUVUSF9WQVJBUkdTLCBnZXRfdGhyZXNoX19kb2NfX30sDQorCXsiY29sbGVjdCIsCQlQeV9j b2xsZWN0LCAgICBNRVRIX1ZBUkFSR1MsIGNvbGxlY3RfX2RvY19ffSwNCisJe05VTEwsCU5V TEx9CQkvKiBTZW50aW5lbCAqLw0KK307DQorDQordm9pZA0KK2luaXRnYyh2b2lkKQ0KK3sN CisJUHlPYmplY3QgKm07DQorCVB5T2JqZWN0ICpkOw0KKw0KKwltID0gUHlfSW5pdE1vZHVs ZTQoImdjIiwNCisJCQkgICAgICBHY01ldGhvZHMsDQorCQkJICAgICAgZ2NfX2RvY19fLA0K KwkJCSAgICAgIE5VTEwsDQorCQkJICAgICAgUFlUSE9OX0FQSV9WRVJTSU9OKTsNCisJZCA9 IFB5TW9kdWxlX0dldERpY3QobSk7DQorCWlmIChnYXJiYWdlID09IE5VTEwpIHsNCisJCWdh cmJhZ2UgPSBQeUxpc3RfTmV3KDApOw0KKwl9DQorCVB5RGljdF9TZXRJdGVtU3RyaW5nKGQs ICJnYXJiYWdlIiwgZ2FyYmFnZSk7DQorCVB5RGljdF9TZXRJdGVtU3RyaW5nKGQsICJERUJV R19TVEFUUyIsDQorCQkJUHlJbnRfRnJvbUxvbmcoREVCVUdfU1RBVFMpKTsNCisJUHlEaWN0 X1NldEl0ZW1TdHJpbmcoZCwgIkRFQlVHX0NPTExFQ1RBQkxFIiwNCisJCQlQeUludF9Gcm9t TG9uZyhERUJVR19DT0xMRUNUQUJMRSkpOw0KKwlQeURpY3RfU2V0SXRlbVN0cmluZyhkLCAi REVCVUdfVU5DT0xMRUNUQUJMRSIsDQorCQkJUHlJbnRfRnJvbUxvbmcoREVCVUdfVU5DT0xM RUNUQUJMRSkpOw0KKwlQeURpY3RfU2V0SXRlbVN0cmluZyhkLCAiREVCVUdfSU5TVEFOQ0VT IiwNCisJCQlQeUludF9Gcm9tTG9uZyhERUJVR19JTlNUQU5DRVMpKTsNCisJUHlEaWN0X1Nl dEl0ZW1TdHJpbmcoZCwgIkRFQlVHX09CSkVDVFMiLA0KKwkJCVB5SW50X0Zyb21Mb25nKERF QlVHX09CSkVDVFMpKTsNCisJUHlEaWN0X1NldEl0ZW1TdHJpbmcoZCwgIkRFQlVHX0xFQUsi LA0KKwkJCVB5SW50X0Zyb21Mb25nKERFQlVHX0xFQUspKTsNCit9DQorDQotLS0gUHl0aG9u LWN2cy9PYmplY3RzL2NsYXNzb2JqZWN0LmMJVHVlIEZlYiAyOSAxNDo1NToxNSAyMDAwDQor KysgUHl0aG9uLWdjL09iamVjdHMvY2xhc3NvYmplY3QuYwlNb24gQXByIDI0IDIxOjE5OjE4 IDIwMDANCkBAIC0xMTAsNyArMTEwLDcgQEANCiAJCX0NCiAJCVB5X0lOQ1JFRihiYXNlcyk7 DQogCX0NCi0Jb3AgPSBQeU9iamVjdF9ORVcoUHlDbGFzc09iamVjdCwgJlB5Q2xhc3NfVHlw ZSk7DQorCW9wID0gUHlPYmplY3RfTmV3KFB5Q2xhc3NPYmplY3QsICZQeUNsYXNzX1R5cGUp Ow0KIAlpZiAob3AgPT0gTlVMTCkgew0KIAkJUHlfREVDUkVGKGJhc2VzKTsNCiAJCXJldHVy biBOVUxMOw0KQEAgLTEzMSw2ICsxMzEsOSBAQA0KIAlQeV9YSU5DUkVGKG9wLT5jbF9nZXRh dHRyKTsNCiAJUHlfWElOQ1JFRihvcC0+Y2xfc2V0YXR0cik7DQogCVB5X1hJTkNSRUYob3At PmNsX2RlbGF0dHIpOw0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDDQorCVB5R0NfSW5zZXJ0KChQ eU9iamVjdCAqKW9wKTsNCisjZW5kaWYNCiAJcmV0dXJuIChQeU9iamVjdCAqKSBvcDsNCiB9 DQogDQpAQCAtMTQwLDEzICsxNDMsMTYgQEANCiBjbGFzc19kZWFsbG9jKG9wKQ0KIAlQeUNs YXNzT2JqZWN0ICpvcDsNCiB7DQorI2lmZGVmIFdJVEhfQ1lDTEVfR0MNCisJUHlHQ19SZW1v dmUoKFB5T2JqZWN0ICopb3ApOw0KKyNlbmRpZg0KIAlQeV9ERUNSRUYob3AtPmNsX2Jhc2Vz KTsNCiAJUHlfREVDUkVGKG9wLT5jbF9kaWN0KTsNCiAJUHlfWERFQ1JFRihvcC0+Y2xfbmFt ZSk7DQogCVB5X1hERUNSRUYob3AtPmNsX2dldGF0dHIpOw0KIAlQeV9YREVDUkVGKG9wLT5j bF9zZXRhdHRyKTsNCiAJUHlfWERFQ1JFRihvcC0+Y2xfZGVsYXR0cik7DQotCWZyZWUoKEFO WSAqKW9wKTsNCisJUHlPYmplY3RfRGVsKChQeU9iamVjdCAqKW9wKTsNCiB9DQogDQogc3Rh dGljIFB5T2JqZWN0ICoNCkBAIC0zODYsNiArMzkyLDIxIEBADQogCXJldHVybiByZXM7DQog fQ0KIA0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDDQorc3RhdGljIGludA0KK2NsYXNzX3JlY3Vy c2UoUHlDbGFzc09iamVjdCAqbywgdmlzaXRwcm9jIHZpc2l0LCB2b2lkICpjbG9zdXJlKQ0K K3sNCisJaWYgKG8tPmNsX2Jhc2VzKSB2aXNpdChvLT5jbF9iYXNlcywgY2xvc3VyZSk7DQor CWlmIChvLT5jbF9kaWN0KSB2aXNpdChvLT5jbF9kaWN0LCBjbG9zdXJlKTsNCisJaWYgKG8t PmNsX25hbWUpIHZpc2l0KG8tPmNsX25hbWUsIGNsb3N1cmUpOw0KKwlpZiAoby0+Y2xfZ2V0 YXR0cikgdmlzaXQoby0+Y2xfZ2V0YXR0ciwgY2xvc3VyZSk7DQorCWlmIChvLT5jbF9zZXRh dHRyKSB2aXNpdChvLT5jbF9zZXRhdHRyLCBjbG9zdXJlKTsNCisJaWYgKG8tPmNsX2RlbGF0 dHIpIHZpc2l0KG8tPmNsX2RlbGF0dHIsIGNsb3N1cmUpOw0KKwlyZXR1cm4gMTsNCit9DQor I2VuZGlmIC8qIFdJVEhfQ1lDTEVfR0MgKi8NCisNCisNCiBQeVR5cGVPYmplY3QgUHlDbGFz c19UeXBlID0gew0KIAlQeU9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlKQ0KIAkwLA0K QEAgLTQwNiw2ICs0MjcsMTIgQEANCiAJKHJlcHJmdW5jKWNsYXNzX3N0ciwgLyp0cF9zdHIq Lw0KIAkoZ2V0YXR0cm9mdW5jKWNsYXNzX2dldGF0dHIsIC8qdHBfZ2V0YXR0cm8qLw0KIAko c2V0YXR0cm9mdW5jKWNsYXNzX3NldGF0dHIsIC8qdHBfc2V0YXR0cm8qLw0KKyNpZmRlZiBX SVRIX0NZQ0xFX0dDDQorCTAsCQkvKiB0cF9hc19idWZmZXIgKi8NCisJUHlfVFBGTEFHU19E RUZBVUxUIHwgUHlfVFBGTEFHU19IQVZFX0dDSU5GTywgLyp0cF9mbGFncyovDQorCTAsCQkv KiB0cF9kb2MgKi8NCisJKHJlY3Vyc2Vwcm9jKWNsYXNzX3JlY3Vyc2UsCS8qIHRwX3JlY3Vy c2UgKi8NCisjZW5kaWYNCiB9Ow0KIA0KIGludA0KQEAgLTQ0NCwxMiArNDcxLDE1IEBADQog CQlQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsNCiAJCXJldHVybiBOVUxMOw0KIAl9DQotCWlu c3QgPSBQeU9iamVjdF9ORVcoUHlJbnN0YW5jZU9iamVjdCwgJlB5SW5zdGFuY2VfVHlwZSk7 DQorCWluc3QgPSBQeU9iamVjdF9OZXcoUHlJbnN0YW5jZU9iamVjdCwgJlB5SW5zdGFuY2Vf VHlwZSk7DQogCWlmIChpbnN0ID09IE5VTEwpDQogCQlyZXR1cm4gTlVMTDsNCiAJUHlfSU5D UkVGKGNsYXNzKTsNCiAJaW5zdC0+aW5fY2xhc3MgPSAoUHlDbGFzc09iamVjdCAqKWNsYXNz Ow0KIAlpbnN0LT5pbl9kaWN0ID0gUHlEaWN0X05ldygpOw0KKyNpZmRlZiBXSVRIX0NZQ0xF X0dDDQorCVB5R0NfSW5zZXJ0KChQeU9iamVjdCAqKWluc3QpOw0KKyNlbmRpZg0KIAlpZiAo aW5zdC0+aW5fZGljdCA9PSBOVUxMKSB7DQogCQlQeV9ERUNSRUYoaW5zdCk7DQogCQlyZXR1 cm4gTlVMTDsNCkBAIC00OTgsMTEgKzUyOCwxNCBAQA0KIAlQeU9iamVjdCAqZXJyb3JfdHlw ZSwgKmVycm9yX3ZhbHVlLCAqZXJyb3JfdHJhY2ViYWNrOw0KIAlQeU9iamVjdCAqZGVsOw0K IAlzdGF0aWMgUHlPYmplY3QgKmRlbHN0cjsNCisJZXh0ZXJuIGxvbmcgX1B5X1JlZlRvdGFs Ow0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDDQorCVB5R0NfUmVtb3ZlKChQeU9iamVjdCAqKWlu c3QpOw0KKyNlbmRpZg0KIAkvKiBDYWxsIHRoZSBfX2RlbF9fIG1ldGhvZCBpZiBpdCBleGlz dHMuICBGaXJzdCB0ZW1wb3JhcmlseQ0KIAkgICByZXZpdmUgdGhlIG9iamVjdCBhbmQgc2F2 ZSB0aGUgY3VycmVudCBleGNlcHRpb24sIGlmIGFueS4gKi8NCiAjaWZkZWYgUHlfVFJBQ0Vf UkVGUw0KIAkvKiBtdWNoIHRvbyBjb21wbGljYXRlZCBpZiBQeV9UUkFDRV9SRUZTIGRlZmlu ZWQgKi8NCi0JZXh0ZXJuIGxvbmcgX1B5X1JlZlRvdGFsOw0KIAlpbnN0LT5vYl90eXBlID0g JlB5SW5zdGFuY2VfVHlwZTsNCiAJX1B5X05ld1JlZmVyZW5jZSgoUHlPYmplY3QgKilpbnN0 KTsNCiAJX1B5X1JlZlRvdGFsLS07CQkvKiBjb21wZW5zYXRlIGZvciBpbmNyZW1lbnQgaW4g TkVXUkVGICovDQpAQCAtNTUwLDYgKzU4Myw5IEBADQogI2lmZGVmIENPVU5UX0FMTE9DUw0K IAkJaW5zdC0+b2JfdHlwZS0+dHBfZnJlZS0tOw0KICNlbmRpZg0KKyNpZmRlZiBXSVRIX0NZ Q0xFX0dDDQorCQlQeUdDX0luc2VydCgoUHlPYmplY3QgKilpbnN0KTsNCisjZW5kaWYNCiAJ CXJldHVybjsgLyogX19kZWxfXyBhZGRlZCBhIHJlZmVyZW5jZTsgZG9uJ3QgZGVsZXRlIG5v dyAqLw0KIAl9DQogI2lmZGVmIFB5X1RSQUNFX1JFRlMNCkBAIC01NTcsMTEgKzU5MywxMCBA QA0KIAlpbnN0LT5vYl90eXBlLT50cF9mcmVlLS07CS8qIGNvbXBlbnNhdGUgZm9yIGluY3Jl bWVudCBpbiBVTlJFRiAqLw0KICNlbmRpZg0KIAlfUHlfRm9yZ2V0UmVmZXJlbmNlKChQeU9i amVjdCAqKWluc3QpOw0KLQlpbnN0LT5vYl90eXBlID0gTlVMTDsNCiAjZW5kaWYgLyogUHlf VFJBQ0VfUkVGUyAqLw0KIAlQeV9ERUNSRUYoaW5zdC0+aW5fY2xhc3MpOw0KIAlQeV9YREVD UkVGKGluc3QtPmluX2RpY3QpOw0KLQlmcmVlKChBTlkgKilpbnN0KTsNCisJUHlPYmplY3Rf RGVsKChQeU9iamVjdCAqKWluc3QpOw0KIH0NCiANCiBzdGF0aWMgUHlPYmplY3QgKg0KQEAg LTg0MCw2ICs4NzUsMTYgQEANCiAJcmV0dXJuIG91dGNvbWU7DQogfQ0KIA0KKyNpZmRlZiBX SVRIX0NZQ0xFX0dDDQorc3RhdGljIGludA0KK2luc3RhbmNlX3JlY3Vyc2UoUHlJbnN0YW5j ZU9iamVjdCAqbywgdmlzaXRwcm9jIHZpc2l0LCB2b2lkICpjbG9zdXJlKQ0KK3sNCisJaWYg KG8tPmluX2NsYXNzKSB2aXNpdCgoUHlPYmplY3QgKikoby0+aW5fY2xhc3MpLCBjbG9zdXJl KTsNCisJaWYgKG8tPmluX2RpY3QpIHZpc2l0KG8tPmluX2RpY3QsIGNsb3N1cmUpOw0KKwly ZXR1cm4gMTsNCit9DQorI2VuZGlmIC8qIFdJVEhfQ1lDTEVfR0MgKi8NCisNCiBzdGF0aWMg UHlPYmplY3QgKmdldGl0ZW1zdHIsICpzZXRpdGVtc3RyLCAqZGVsaXRlbXN0ciwgKmxlbnN0 cjsNCiANCiBzdGF0aWMgaW50DQpAQCAtMTQ2Myw3ICsxNTA4LDExIEBADQogCShnZXRhdHRy b2Z1bmMpaW5zdGFuY2VfZ2V0YXR0ciwgLyp0cF9nZXRhdHRybyovDQogCShzZXRhdHRyb2Z1 bmMpaW5zdGFuY2Vfc2V0YXR0ciwgLyp0cF9zZXRhdHRybyovDQogICAgICAgICAwLCAvKiB0 cF9hc19idWZmZXIgKi8NCi0JUHlfVFBGTEFHU19ERUZBVUxULCAvKnRwX2ZsYWdzICovDQor CVB5X1RQRkxBR1NfREVGQVVMVCB8IFB5X1RQRkxBR1NfSEFWRV9HQ0lORk8sIC8qdHBfZmxh Z3MqLw0KKwkwLAkJLyogdHBfZG9jICovDQorI2lmZGVmIFdJVEhfQ1lDTEVfR0MNCisJKHJl Y3Vyc2Vwcm9jKWluc3RhbmNlX3JlY3Vyc2UsCS8qIHRwX3JlY3Vyc2UgKi8NCisjZW5kaWYN CiB9Ow0KIA0KIA0KQEAgLTE0OTMsNyArMTU0Miw3IEBADQogCQlfUHlfTmV3UmVmZXJlbmNl KChQeU9iamVjdCAqKWltKTsNCiAJfQ0KIAllbHNlIHsNCi0JCWltID0gUHlPYmplY3RfTkVX KFB5TWV0aG9kT2JqZWN0LCAmUHlNZXRob2RfVHlwZSk7DQorCQlpbSA9IFB5T2JqZWN0X05l dyhQeU1ldGhvZE9iamVjdCwgJlB5TWV0aG9kX1R5cGUpOw0KIAkJaWYgKGltID09IE5VTEwp DQogCQkJcmV0dXJuIE5VTEw7DQogCX0NCi0tLSBQeXRob24tY3ZzL09iamVjdHMvZGljdG9i amVjdC5jCVRodSBNYXIgMzAgMjI6MDI6NTIgMjAwMA0KKysrIFB5dGhvbi1nYy9PYmplY3Rz L2RpY3RvYmplY3QuYwlTYXQgQXByICA4IDAyOjA5OjU5IDIwMDANCkBAIC0xMjEsNyArMTIx LDcgQEANCiAJCWlmIChkdW1teSA9PSBOVUxMKQ0KIAkJCXJldHVybiBOVUxMOw0KIAl9DQot CW1wID0gUHlPYmplY3RfTkVXKGRpY3RvYmplY3QsICZQeURpY3RfVHlwZSk7DQorCW1wID0g UHlPYmplY3RfTmV3KGRpY3RvYmplY3QsICZQeURpY3RfVHlwZSk7DQogCWlmIChtcCA9PSBO VUxMKQ0KIAkJcmV0dXJuIE5VTEw7DQogCW1wLT5tYV9zaXplID0gMDsNCkBAIC0xMjksNiAr MTI5LDkgQEANCiAJbXAtPm1hX3RhYmxlID0gTlVMTDsNCiAJbXAtPm1hX2ZpbGwgPSAwOw0K IAltcC0+bWFfdXNlZCA9IDA7DQorI2lmZGVmIFdJVEhfQ1lDTEVfR0MNCisJUHlHQ19JbnNl cnQoKFB5T2JqZWN0ICopbXApOw0KKyNlbmRpZg0KIAlyZXR1cm4gKFB5T2JqZWN0ICopbXA7 DQogfQ0KIA0KQEAgLTQ4MCw2ICs0ODMsOSBAQA0KIAlyZWdpc3RlciBpbnQgaTsNCiAJcmVn aXN0ZXIgZGljdGVudHJ5ICplcDsNCiAJUHlfVFJBU0hDQU5fU0FGRV9CRUdJTihtcCkNCisj aWZkZWYgV0lUSF9DWUNMRV9HQw0KKwlQeUdDX1JlbW92ZSgoUHlPYmplY3QgKiltcCk7DQor I2VuZGlmDQogCWZvciAoaSA9IDAsIGVwID0gbXAtPm1hX3RhYmxlOyBpIDwgbXAtPm1hX3Np emU7IGkrKywgZXArKykgew0KIAkJaWYgKGVwLT5tZV9rZXkgIT0gTlVMTCkgew0KIAkJCVB5 X0RFQ1JFRihlcC0+bWVfa2V5KTsNCkBAIC00ODksNyArNDk1LDcgQEANCiAJCX0NCiAJfQ0K IAlQeU1lbV9YREVMKG1wLT5tYV90YWJsZSk7DQotCVB5TWVtX0RFTChtcCk7DQorCVB5T2Jq ZWN0X0RlbCgoUHlPYmplY3QgKiltcCk7DQogCVB5X1RSQVNIQ0FOX1NBRkVfRU5EKG1wKQ0K IH0NCiANCkBAIC0xMDM2LDYgKzEwNDIsMzMgQEANCiAJcmV0dXJuIFB5X05vbmU7DQogfQ0K IA0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDDQorc3RhdGljIGludA0KK2RpY3RfcmVjdXJzZShQ eU9iamVjdCAqb3AsIHZpc2l0cHJvYyB2aXNpdCwgdm9pZCAqY2xvc3VyZSkNCit7DQorCWlu dCBpID0gMDsNCisJUHlPYmplY3QgKnBrOw0KKwlQeU9iamVjdCAqcHY7DQorDQorCXdoaWxl IChQeURpY3RfTmV4dChvcCwgJmksICZwaywgJnB2KSkgew0KKwkJaWYgKCF2aXNpdChwaywg Y2xvc3VyZSkpIHsNCisJCQlyZXR1cm4gMDsNCisJCX0NCisJCWlmICghdmlzaXQocHYsIGNs b3N1cmUpKSB7DQorCQkJcmV0dXJuIDA7DQorCQl9DQorCX0NCisJcmV0dXJuIDE7DQorfQ0K Kw0KK3N0YXRpYyBpbnQNCitkaWN0X2djX2NsZWFyKFB5T2JqZWN0ICpvcCkNCit7DQorCVB5 RGljdF9DbGVhcihvcCk7DQorCXJldHVybiAwOw0KK30NCisjZW5kaWYgLyogV0lUSF9DWUNM RV9HQyAqLw0KKw0KIHN0YXRpYyBQeU1ldGhvZERlZiBtYXBwX21ldGhvZHNbXSA9IHsNCiAJ eyJoYXNfa2V5IiwJKFB5Q0Z1bmN0aW9uKWRpY3RfaGFzX2tleSwgICAgICBNRVRIX1ZBUkFS R1N9LA0KIAl7ImtleXMiLAkoUHlDRnVuY3Rpb24pZGljdF9rZXlzfSwNCkBAIC0xMDcxLDYg KzExMDQsMTggQEANCiAJMCwJCQkvKnRwX2FzX251bWJlciovDQogCTAsCQkJLyp0cF9hc19z ZXF1ZW5jZSovDQogCSZkaWN0X2FzX21hcHBpbmcsCS8qdHBfYXNfbWFwcGluZyovDQorI2lm ZGVmIFdJVEhfQ1lDTEVfR0MNCisJMCwJCS8qIHRwX2hhc2ggKi8NCisJMCwJCS8qIHRwX2Nh bGwgKi8NCisJMCwJCS8qIHRwX3N0ciAqLw0KKwkwLAkJLyogdHBfZ2V0YXR0cm8gKi8NCisJ MCwJCS8qIHRwX3NldGF0dHJvICovDQorCTAsCQkvKiB0cF9hc19idWZmZXIgKi8NCisJUHlf VFBGTEFHU19ERUZBVUxUIHwgUHlfVFBGTEFHU19IQVZFX0dDSU5GTywgLyp0cF9mbGFncyov DQorCTAsCQkvKiB0cF9kb2MgKi8NCisJKHJlY3Vyc2Vwcm9jKWRpY3RfcmVjdXJzZSwJLyog dHBfcmVjdXJzZSAqLw0KKwkoaW5xdWlyeSlkaWN0X2djX2NsZWFyLAkJLyogdHBfY2xlYXIg Ki8NCisjZW5kaWYNCiB9Ow0KIA0KIC8qIEZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5IHdp dGggb2xkIGRpY3Rpb25hcnkgaW50ZXJmYWNlICovDQotLS0gUHl0aG9uLWN2cy9PYmplY3Rz L2Z1bmNvYmplY3QuYwlUaHUgTWF5IDIxIDE4OjU1OjM0IDE5OTgNCisrKyBQeXRob24tZ2Mv T2JqZWN0cy9mdW5jb2JqZWN0LmMJU2F0IEFwciAgOCAwMjowOTo1MCAyMDAwDQpAQCAtNDAs NyArNDAsNyBAQA0KIAlQeU9iamVjdCAqY29kZTsNCiAJUHlPYmplY3QgKmdsb2JhbHM7DQog ew0KLQlQeUZ1bmN0aW9uT2JqZWN0ICpvcCA9IFB5T2JqZWN0X05FVyhQeUZ1bmN0aW9uT2Jq ZWN0LA0KKwlQeUZ1bmN0aW9uT2JqZWN0ICpvcCA9IFB5T2JqZWN0X05ldyhQeUZ1bmN0aW9u T2JqZWN0LA0KIAkJCQkJICAgICZQeUZ1bmN0aW9uX1R5cGUpOw0KIAlpZiAob3AgIT0gTlVM TCkgew0KIAkJUHlPYmplY3QgKmRvYzsNCkBAIC02Myw2ICs2Myw5IEBADQogCQlQeV9JTkNS RUYoZG9jKTsNCiAJCW9wLT5mdW5jX2RvYyA9IGRvYzsNCiAJfQ0KKyNpZmRlZiBXSVRIX0NZ Q0xFX0dDDQorCVB5R0NfSW5zZXJ0KChQeU9iamVjdCAqKW9wKTsNCisjZW5kaWYNCiAJcmV0 dXJuIChQeU9iamVjdCAqKW9wOw0KIH0NCiANCkBAIC0xODYsMTIgKzE4OSwxNSBAQA0KIGZ1 bmNfZGVhbGxvYyhvcCkNCiAJUHlGdW5jdGlvbk9iamVjdCAqb3A7DQogew0KKyNpZmRlZiBX SVRIX0NZQ0xFX0dDDQorCVB5R0NfUmVtb3ZlKChQeU9iamVjdCAqKW9wKTsNCisjZW5kaWYN CiAJUHlfREVDUkVGKG9wLT5mdW5jX2NvZGUpOw0KIAlQeV9ERUNSRUYob3AtPmZ1bmNfZ2xv YmFscyk7DQogCVB5X0RFQ1JFRihvcC0+ZnVuY19uYW1lKTsNCiAJUHlfWERFQ1JFRihvcC0+ ZnVuY19kZWZhdWx0cyk7DQogCVB5X1hERUNSRUYob3AtPmZ1bmNfZG9jKTsNCi0JUHlNZW1f REVMKG9wKTsNCisJUHlPYmplY3RfRGVsKChQeU9iamVjdCAqKW9wKTsNCiB9DQogDQogc3Rh dGljIFB5T2JqZWN0Kg0KQEAgLTIzOSw2ICsyNDUsMTkgQEANCiAJcmV0dXJuIGg7DQogfQ0K IA0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDDQorc3RhdGljIGludA0KK2Z1bmNfcmVjdXJzZShQ eUZ1bmN0aW9uT2JqZWN0ICpmLCB2aXNpdHByb2MgdmlzaXQsIHZvaWQgKmNsb3N1cmUpDQor ew0KKwlpZiAoZi0+ZnVuY19jb2RlKSB2aXNpdChmLT5mdW5jX2NvZGUsIGNsb3N1cmUpOw0K KwlpZiAoZi0+ZnVuY19nbG9iYWxzKSB2aXNpdChmLT5mdW5jX2dsb2JhbHMsIGNsb3N1cmUp Ow0KKwlpZiAoZi0+ZnVuY19kZWZhdWx0cykgdmlzaXQoZi0+ZnVuY19kZWZhdWx0cywgY2xv c3VyZSk7DQorCWlmIChmLT5mdW5jX2RvYykgdmlzaXQoZi0+ZnVuY19kb2MsIGNsb3N1cmUp Ow0KKwlpZiAoZi0+ZnVuY19uYW1lKSB2aXNpdChmLT5mdW5jX25hbWUsIGNsb3N1cmUpOw0K KwlyZXR1cm4gMTsNCit9DQorI2VuZGlmIC8qIFdJVEhfQ1lDTEVfR0MgKi8NCisNCiBQeVR5 cGVPYmplY3QgUHlGdW5jdGlvbl9UeXBlID0gew0KIAlQeU9iamVjdF9IRUFEX0lOSVQoJlB5 VHlwZV9UeXBlKQ0KIAkwLA0KQEAgLTI1NSw0ICsyNzQsMTQgQEANCiAJMCwJCS8qdHBfYXNf c2VxdWVuY2UqLw0KIAkwLAkJLyp0cF9hc19tYXBwaW5nKi8NCiAJKGhhc2hmdW5jKWZ1bmNf aGFzaCwgLyp0cF9oYXNoKi8NCisjaWZkZWYgV0lUSF9DWUNMRV9HQw0KKwkwLAkJLyp0cF9j YWxsKi8NCisJMCwJCS8qdHBfc3RyKi8NCisJMCwJCS8qdHBfZ2V0YXR0cm8qLw0KKwkwLAkJ Lyp0cF9zZXRhdHRybyovDQorCTAsCQkvKiB0cF9hc19idWZmZXIgKi8NCisJUHlfVFBGTEFH U19ERUZBVUxUIHwgUHlfVFBGTEFHU19IQVZFX0dDSU5GTywgLyp0cF9mbGFncyovDQorCTAs CQkvKiB0cF9kb2MgKi8NCisJKHJlY3Vyc2Vwcm9jKWZ1bmNfcmVjdXJzZSwJLyogdHBfcmVj dXJzZSAqLw0KKyNlbmRpZg0KIH07DQotLS0gUHl0aG9uLWN2cy9PYmplY3RzL2xpc3RvYmpl Y3QuYwlGcmkgTWFyIDI0IDIyOjMyOjMwIDIwMDANCisrKyBQeXRob24tZ2MvT2JqZWN0cy9s aXN0b2JqZWN0LmMJTW9uIEFwciAyNCAyMToxNDo0MiAyMDAwDQpAQCAtNjEsMzQgKzYxLDM3 IEBADQogCWludCBpOw0KIAlQeUxpc3RPYmplY3QgKm9wOw0KIAlzaXplX3QgbmJ5dGVzOw0K KwlQeU9iamVjdCAqKml0ZW07DQorDQogCWlmIChzaXplIDwgMCkgew0KIAkJUHlFcnJfQmFk SW50ZXJuYWxDYWxsKCk7DQogCQlyZXR1cm4gTlVMTDsNCiAJfQ0KLQluYnl0ZXMgPSBzaXpl ICogc2l6ZW9mKFB5T2JqZWN0ICopOw0KLQkvKiBDaGVjayBmb3Igb3ZlcmZsb3cgKi8NCi0J aWYgKG5ieXRlcyAvIHNpemVvZihQeU9iamVjdCAqKSAhPSAoc2l6ZV90KXNpemUpIHsNCi0J CXJldHVybiBQeUVycl9Ob01lbW9yeSgpOw0KLQl9DQotCW9wID0gKFB5TGlzdE9iamVjdCAq KSBtYWxsb2Moc2l6ZW9mKFB5TGlzdE9iamVjdCkpOw0KLQlpZiAob3AgPT0gTlVMTCkgew0K LQkJcmV0dXJuIFB5RXJyX05vTWVtb3J5KCk7DQotCX0NCi0JaWYgKHNpemUgPD0gMCkgew0K LQkJb3AtPm9iX2l0ZW0gPSBOVUxMOw0KLQl9DQorCWlmIChzaXplID09IDApDQorCQlpdGVt ID0gTlVMTDsNCiAJZWxzZSB7DQotCQlvcC0+b2JfaXRlbSA9IChQeU9iamVjdCAqKikgbWFs bG9jKG5ieXRlcyk7DQotCQlpZiAob3AtPm9iX2l0ZW0gPT0gTlVMTCkgew0KLQkJCWZyZWUo KEFOWSAqKW9wKTsNCisJCW5ieXRlcyA9IHNpemUgKiBzaXplb2YoUHlPYmplY3QgKik7DQor CQkvKiBDaGVjayBmb3Igb3ZlcmZsb3cgKi8NCisJCWlmIChuYnl0ZXMgLyBzaXplb2YoUHlP YmplY3QgKikgIT0gKHNpemVfdClzaXplKSB7DQogCQkJcmV0dXJuIFB5RXJyX05vTWVtb3J5 KCk7DQogCQl9DQorCQlpdGVtID0gKFB5T2JqZWN0ICoqKSBtYWxsb2MobmJ5dGVzKTsNCisJ CWlmIChpdGVtID09IE5VTEwpDQorCQkJcmV0dXJuIFB5RXJyX05vTWVtb3J5KCk7DQorCX0N CisJb3AgPSBQeU9iamVjdF9OZXcoUHlMaXN0T2JqZWN0LCAmUHlMaXN0X1R5cGUpOw0KKwlp ZiAob3AgPT0gTlVMTCkgew0KKwkJaWYgKGl0ZW0gIT0gTlVMTCkNCisJCQlmcmVlKChBTlkg KilpdGVtKTsNCisJCXJldHVybiBQeUVycl9Ob01lbW9yeSgpOw0KIAl9DQotCW9wLT5vYl90 eXBlID0gJlB5TGlzdF9UeXBlOw0KIAlvcC0+b2Jfc2l6ZSA9IHNpemU7DQorCW9wLT5vYl9p dGVtID0gaXRlbTsNCiAJZm9yIChpID0gMDsgaSA8IHNpemU7IGkrKykNCiAJCW9wLT5vYl9p dGVtW2ldID0gTlVMTDsNCi0JX1B5X05ld1JlZmVyZW5jZSgoUHlPYmplY3QgKilvcCk7DQor I2lmZGVmIFdJVEhfQ1lDTEVfR0MNCisJUHlHQ19JbnNlcnQoKFB5T2JqZWN0ICopb3ApOw0K KyNlbmRpZg0KIAlyZXR1cm4gKFB5T2JqZWN0ICopIG9wOw0KIH0NCiANCkBAIC0yMTYsNiAr MjE5LDkgQEANCiB7DQogCWludCBpOw0KIAlQeV9UUkFTSENBTl9TQUZFX0JFR0lOKG9wKQ0K KyNpZmRlZiBXSVRIX0NZQ0xFX0dDDQorCVB5R0NfUmVtb3ZlKChQeU9iamVjdCAqKW9wKTsN CisjZW5kaWYNCiAJaWYgKG9wLT5vYl9pdGVtICE9IE5VTEwpIHsNCiAJCS8qIERvIGl0IGJh Y2t3YXJkcywgZm9yIENocmlzdGlhbiBUaXNtZXIuDQogCQkgICBUaGVyZSdzIGEgc2ltcGxl IHRlc3QgY2FzZSB3aGVyZSBzb21laG93IHRoaXMgcmVkdWNlcw0KQEAgLTIyNyw3ICsyMzMs NyBAQA0KIAkJfQ0KIAkJZnJlZSgoQU5ZICopb3AtPm9iX2l0ZW0pOw0KIAl9DQotCWZyZWUo KEFOWSAqKW9wKTsNCisJUHlPYmplY3RfRGVsKChQeU9iamVjdCAqKW9wKTsNCiAJUHlfVFJB U0hDQU5fU0FGRV9FTkQob3ApDQogfQ0KIA0KQEAgLTEzOTksNiArMTQwNSwyOSBAQA0KIAly ZXR1cm4gTlVMTDsNCiB9DQogDQorI2lmZGVmIFdJVEhfQ1lDTEVfR0MNCitzdGF0aWMgaW50 DQorbGlzdF9yZWN1cnNlKFB5TGlzdE9iamVjdCAqbywgdmlzaXRwcm9jIHZpc2l0LCB2b2lk ICpjbG9zdXJlKQ0KK3sNCisJaW50IGk7DQorCVB5T2JqZWN0ICp4Ow0KKw0KKwlmb3IgKGkg PSBvLT5vYl9zaXplOyAtLWkgPj0gMDsgKSB7DQorCQl4ID0gby0+b2JfaXRlbVtpXTsNCisJ CWlmICh4ICE9IE5VTEwgJiYgIXZpc2l0KHgsIGNsb3N1cmUpKQ0KKwkJCXJldHVybiAwOw0K Kwl9DQorCXJldHVybiAxOw0KK30NCisNCitzdGF0aWMgaW50DQorbGlzdF9jbGVhcihQeUxp c3RPYmplY3QgKmxwKQ0KK3sNCisJKHZvaWQpIFB5TGlzdF9TZXRTbGljZSgoUHlPYmplY3Qg KilscCwgMCwgbHAtPm9iX3NpemUsIDApOw0KKwlyZXR1cm4gMDsNCit9DQorI2VuZGlmIC8q IFdJVEhfQ1lDTEVfR0MgKi8NCisNCiBzdGF0aWMgY2hhciBhcHBlbmRfZG9jW10gPQ0KICJM LmFwcGVuZChvYmplY3QpIC0tIGFwcGVuZCBvYmplY3QgdG8gZW5kIjsNCiBzdGF0aWMgY2hh ciBleHRlbmRfZG9jW10gPQ0KQEAgLTE0NjQsNiArMTQ5MywxOCBAQA0KIAkwLAkJLyp0cF9h c19udW1iZXIqLw0KIAkmbGlzdF9hc19zZXF1ZW5jZSwJLyp0cF9hc19zZXF1ZW5jZSovDQog CTAsCQkvKnRwX2FzX21hcHBpbmcqLw0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDDQorCTAsCQkv KiB0cF9oYXNoICovDQorCTAsCQkvKiB0cF9jYWxsICovDQorCTAsCQkvKiB0cF9zdHIgKi8N CisJMCwJCS8qIHRwX2dldGF0dHJvICovDQorCTAsCQkvKiB0cF9zZXRhdHRybyAqLw0KKwkw LAkJLyogdHBfYXNfYnVmZmVyICovDQorCVB5X1RQRkxBR1NfREVGQVVMVCB8IFB5X1RQRkxB R1NfSEFWRV9HQ0lORk8sCS8qIHRwX2ZsYWdzICovDQorCTAsCQkvKiB0cF9kb2MgKi8NCisJ KHJlY3Vyc2Vwcm9jKWxpc3RfcmVjdXJzZSwJLyogdHBfcmVjdXJzZSAqLw0KKwkoaW5xdWly eSlsaXN0X2NsZWFyLAkvKiB0cF9jbGVhciAqLw0KKyNlbmRpZg0KIH07DQogDQogDQpAQCAt MTUzMiw1ICsxNTczLDE2IEBADQogCTAsCQkvKnRwX2FzX251bWJlciovDQogCSZpbW11dGFi bGVfbGlzdF9hc19zZXF1ZW5jZSwJLyp0cF9hc19zZXF1ZW5jZSovDQogCTAsCQkvKnRwX2Fz X21hcHBpbmcqLw0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDDQorCTAsCQkvKiB0cF9oYXNoICov DQorCTAsCQkvKiB0cF9jYWxsICovDQorCTAsCQkvKiB0cF9zdHIgKi8NCisJMCwJCS8qIHRw X2dldGF0dHJvICovDQorCTAsCQkvKiB0cF9zZXRhdHRybyAqLw0KKwkwLAkJLyogdHBfYXNf YnVmZmVyICovDQorCVB5X1RQRkxBR1NfREVGQVVMVCwJLyogdHBfZmxhZ3MgKi8NCisJMCwJ CS8qIHRwX2RvYyAqLw0KKwkocmVjdXJzZXByb2MpbGlzdF9yZWN1cnNlLAkvKiB0cF9yZWN1 cnNlICovDQorI2VuZGlmDQogfTsNCiANCi0tLSBQeXRob24tY3ZzL09iamVjdHMvb2JqZWN0 LmMJVHVlIE1hciAyOCAwODoxMTowOSAyMDAwDQorKysgUHl0aG9uLWdjL09iamVjdHMvb2Jq ZWN0LmMJU2F0IEFwciAgOCAwMjoxMDowNiAyMDAwDQpAQCAtMTA3LDIwICsxMDcsMTIgQEAN CiB9DQogI2VuZGlmDQogDQotI2lmbmRlZiBNU19DT1JFRExMDQotUHlPYmplY3QgKg0KLV9Q eU9iamVjdF9OZXcodHApDQotCVB5VHlwZU9iamVjdCAqdHA7DQotI2Vsc2UNCisNCiBQeU9i amVjdCAqDQotX1B5T2JqZWN0X05ldyh0cCxvcCkNCitfUHlPYmplY3RfRnJvbVR5cGUodHAs b3ApDQogCVB5VHlwZU9iamVjdCAqdHA7DQogCVB5T2JqZWN0ICpvcDsNCi0jZW5kaWYNCiB7 DQotI2lmbmRlZiBNU19DT1JFRExMDQotCVB5T2JqZWN0ICpvcCA9IChQeU9iamVjdCAqKSBt YWxsb2ModHAtPnRwX2Jhc2ljc2l6ZSk7DQotI2VuZGlmDQogCWlmIChvcCA9PSBOVUxMKQ0K IAkJcmV0dXJuIFB5RXJyX05vTWVtb3J5KCk7DQogCW9wLT5vYl90eXBlID0gdHA7DQpAQCAt MTI4LDI5ICsxMjAsNzggQEANCiAJcmV0dXJuIG9wOw0KIH0NCiANCi0jaWZuZGVmIE1TX0NP UkVETEwNCi1QeVZhck9iamVjdCAqDQotX1B5T2JqZWN0X05ld1Zhcih0cCwgc2l6ZSkNCi0J UHlUeXBlT2JqZWN0ICp0cDsNCi0JaW50IHNpemU7DQotI2Vsc2UNCiBQeVZhck9iamVjdCAq DQotX1B5T2JqZWN0X05ld1Zhcih0cCwgc2l6ZSwgb3ApDQorX1B5T2JqZWN0X1ZhckZyb21U eXBlKHRwLCBzaXplLCBvcCkNCiAJUHlUeXBlT2JqZWN0ICp0cDsNCiAJaW50IHNpemU7DQog CVB5VmFyT2JqZWN0ICpvcDsNCi0jZW5kaWYNCiB7DQotI2lmbmRlZiBNU19DT1JFRExMDQot CVB5VmFyT2JqZWN0ICpvcCA9IChQeVZhck9iamVjdCAqKQ0KLQkJbWFsbG9jKHRwLT50cF9i YXNpY3NpemUgKyBzaXplICogdHAtPnRwX2l0ZW1zaXplKTsNCi0jZW5kaWYNCiAJaWYgKG9w ID09IE5VTEwpDQogCQlyZXR1cm4gKFB5VmFyT2JqZWN0ICopUHlFcnJfTm9NZW1vcnkoKTsN CiAJb3AtPm9iX3R5cGUgPSB0cDsNCiAJb3AtPm9iX3NpemUgPSBzaXplOw0KIAlfUHlfTmV3 UmVmZXJlbmNlKChQeU9iamVjdCAqKW9wKTsNCiAJcmV0dXJuIG9wOw0KK30NCisNCitQeU9i amVjdCAqDQorX1B5T2JqZWN0X05ldyh0cCkNCisJUHlUeXBlT2JqZWN0ICp0cDsNCit7DQor CVB5T2JqZWN0ICpvcDsNCisjaWZkZWYgV0lUSF9DWUNMRV9HQw0KKwlpZiAoUFlfVFlQRUlT R0ModHApKSB7DQorCQlQeUdDSW5mbyAqZzsNCisJCWcgPSAoUHlHQ0luZm8gKikgbWFsbG9j KHNpemVvZigqZykgKyB0cC0+dHBfYmFzaWNzaXplKTsNCisJCWlmIChnID09IE5VTEwpIHsN CisJCQlvcCA9IE5VTEw7DQorCQl9IGVsc2Ugew0KKwkJCW9wID0gUFlfR0NPQkooZyk7DQor CQl9DQorCX0gZWxzZQ0KKyNlbmRpZiAvKiBXSVRIX0NZQ0xFX0dDICovDQorCXsNCisJCW9w ID0gKFB5T2JqZWN0ICopIG1hbGxvYyh0cC0+dHBfYmFzaWNzaXplKTsNCisJfQ0KKwlyZXR1 cm4gX1B5T2JqZWN0X0Zyb21UeXBlKHRwLCBvcCk7DQorfQ0KKw0KK1B5VmFyT2JqZWN0ICoN CitfUHlPYmplY3RfTmV3VmFyKHRwLCBzaXplKQ0KKwlQeVR5cGVPYmplY3QgKnRwOw0KKwlp bnQgc2l6ZTsNCit7DQorCVB5VmFyT2JqZWN0ICpvcDsNCisjaWZkZWYgV0lUSF9DWUNMRV9H Qw0KKwlpZiAoUFlfVFlQRUlTR0ModHApKSB7DQorCQlQeUdDSW5mbyAqZzsNCisJCWcgPSAo UHlHQ0luZm8gKikgbWFsbG9jKHNpemVvZigqZykgKyANCisJCQkJCXRwLT50cF9iYXNpY3Np emUgKw0KKwkJCQkJc2l6ZSAqIHRwLT50cF9pdGVtc2l6ZSk7DQorCQlpZiAoZyA9PSBOVUxM KSB7DQorCQkJb3AgPSBOVUxMOw0KKwkJfSBlbHNlIHsNCisJCQlvcCA9IChQeVZhck9iamVj dCAqKVBZX0dDT0JKKGcpOw0KKwkJfQ0KKwl9IGVsc2UNCisjZW5kaWYgLyogV0lUSF9DWUNM RV9HQyAqLw0KKwl7DQorCQlvcCA9IChQeVZhck9iamVjdCAqKQ0KKwkJCW1hbGxvYyh0cC0+ dHBfYmFzaWNzaXplICsgc2l6ZSAqIHRwLT50cF9pdGVtc2l6ZSk7DQorCX0NCisJcmV0dXJu IF9QeU9iamVjdF9WYXJGcm9tVHlwZSh0cCwgc2l6ZSwgb3ApOw0KK30NCisNCit2b2lkDQor UHlPYmplY3RfRGVsKG9wKQ0KKwlQeU9iamVjdCAqb3A7DQorew0KKyNpZmRlZiBXSVRIX0NZ Q0xFX0dDDQorCWlmIChQWV9JU0dDKG9wKSkgew0KKwkJb3AgPSAoUHlPYmplY3QgKilQWV9H Q0lORk9fVU5TQUZFKG9wKTsNCisJfQ0KKyNlbmRpZg0KKwlmcmVlKG9wKTsNCiB9DQogDQog aW50DQotLS0gUHl0aG9uLWN2cy9PYmplY3RzL3R1cGxlb2JqZWN0LmMJRnJpIE1hciAyNCAy MjozMjozMCAyMDAwDQorKysgUHl0aG9uLWdjL09iamVjdHMvdHVwbGVvYmplY3QuYwlNb24g QXByIDI0IDIxOjIxOjU5IDIwMDANCkBAIC04Miw4ICs4Miw4IEBADQogI2VuZGlmDQogI2lm ZGVmIFB5X1RSQUNFX1JFRlMNCiAJCW9wLT5vYl90eXBlID0gJlB5VHVwbGVfVHlwZTsNCi0J CW9wLT5vYl9zaXplID0gc2l6ZTsNCiAjZW5kaWYNCisJCV9QeV9OZXdSZWZlcmVuY2UoKFB5 T2JqZWN0ICopb3ApOw0KIAl9DQogCWVsc2UNCiAjZW5kaWYNCkBAIC05NywyMyArOTcsMjMg QEANCiAJCQlyZXR1cm4gUHlFcnJfTm9NZW1vcnkoKTsNCiAJCX0NCiAJCTsNCi0JCW9wID0g KFB5VHVwbGVPYmplY3QgKikgbWFsbG9jKG5ieXRlcyk7DQorCQlvcCA9IFB5T2JqZWN0X05l d1ZhcihQeVR1cGxlT2JqZWN0LCAmUHlUdXBsZV9UeXBlLCBzaXplKTsNCiAJCWlmIChvcCA9 PSBOVUxMKQ0KIAkJCXJldHVybiBQeUVycl9Ob01lbW9yeSgpOw0KIA0KLQkJb3AtPm9iX3R5 cGUgPSAmUHlUdXBsZV9UeXBlOw0KLQkJb3AtPm9iX3NpemUgPSBzaXplOw0KIAl9DQogCWZv ciAoaSA9IDA7IGkgPCBzaXplOyBpKyspDQogCQlvcC0+b2JfaXRlbVtpXSA9IE5VTEw7DQot CV9QeV9OZXdSZWZlcmVuY2UoKFB5T2JqZWN0ICopb3ApOw0KKw0KICNpZiBNQVhTQVZFU0la RSA+IDANCiAJaWYgKHNpemUgPT0gMCkgew0KIAkJZnJlZV90dXBsZXNbMF0gPSBvcDsNCi0J CSsrbnVtX2ZyZWVfdHVwbGVzWzBdOw0KIAkJUHlfSU5DUkVGKG9wKTsJLyogZXh0cmEgSU5D UkVGIHNvIHRoYXQgdGhpcyBpcyBuZXZlciBmcmVlZCAqLw0KIAl9DQogI2VuZGlmDQorI2lm ZGVmIFdJVEhfQ1lDTEVfR0MNCisJUHlHQ19JbnNlcnQoKFB5T2JqZWN0ICopb3ApOw0KKyNl bmRpZg0KIAlyZXR1cm4gKFB5T2JqZWN0ICopIG9wOw0KIH0NCiANCkBAIC0xODAsNiArMTgw LDkgQEANCiAJcmVnaXN0ZXIgaW50IGk7DQogCXJlZ2lzdGVyIGludCBsZW4gPSAgb3AtPm9i X3NpemU7DQogCVB5X1RSQVNIQ0FOX1NBRkVfQkVHSU4ob3ApDQorI2lmZGVmIFdJVEhfQ1lD TEVfR0MNCisJUHlHQ19SZW1vdmUoKFB5T2JqZWN0ICopb3ApOw0KKyNlbmRpZg0KIAlpZiAo bGVuID4gMCkgew0KIAkJaSA9IGxlbjsNCiAJCXdoaWxlICgtLWkgPj0gMCkNCkBAIC0xOTMs NyArMTk2LDcgQEANCiAJCX0NCiAjZW5kaWYNCiAJfQ0KLQlmcmVlKChBTlkgKilvcCk7DQor CVB5T2JqZWN0X0RlbCgoUHlPYmplY3QgKilvcCk7DQogZG9uZToNCiAJUHlfVFJBU0hDQU5f U0FGRV9FTkQob3ApDQogfQ0KQEAgLTQwMSw2ICs0MDQsMjIgQEANCiAJcmV0dXJuIChQeU9i amVjdCAqKSBucDsNCiB9DQogDQorI2lmZGVmIFdJVEhfQ1lDTEVfR0MNCitzdGF0aWMgaW50 DQordHVwbGVyZWN1cnNlKFB5VHVwbGVPYmplY3QgKm8sIHZpc2l0cHJvYyB2aXNpdCwgdm9p ZCAqY2xvc3VyZSkNCit7DQorCWludCBpOw0KKwlQeU9iamVjdCAqeDsNCisNCisJZm9yIChp ID0gby0+b2Jfc2l6ZTsgLS1pID49IDA7ICkgew0KKwkJeCA9IG8tPm9iX2l0ZW1baV07DQor CQlpZiAoeCAhPSBOVUxMICYmICF2aXNpdCh4LCBjbG9zdXJlKSkNCisJCQlyZXR1cm4gMDsN CisJfQ0KKwlyZXR1cm4gMTsNCit9DQorI2VuZGlmIC8qIFdJVEhfQ1lDTEVfR0MgKi8NCisN CiBzdGF0aWMgUHlTZXF1ZW5jZU1ldGhvZHMgdHVwbGVfYXNfc2VxdWVuY2UgPSB7DQogCShp bnF1aXJ5KXR1cGxlbGVuZ3RoLCAvKnNxX2xlbmd0aCovDQogCShiaW5hcnlmdW5jKXR1cGxl Y29uY2F0LCAvKnNxX2NvbmNhdCovDQpAQCAtNDI3LDYgKzQ0NiwxNiBAQA0KIAkmdHVwbGVf YXNfc2VxdWVuY2UsCS8qdHBfYXNfc2VxdWVuY2UqLw0KIAkwLAkJLyp0cF9hc19tYXBwaW5n Ki8NCiAJKGhhc2hmdW5jKXR1cGxlaGFzaCwgLyp0cF9oYXNoKi8NCisjaWZkZWYgV0lUSF9D WUNMRV9HQw0KKwkwLAkJLyogdHBfY2FsbCAqLw0KKwkwLAkJLyogdHBfc3RyICovDQorCTAs CQkvKiB0cF9nZXRhdHRybyAqLw0KKwkwLAkJLyogdHBfc2V0YXR0cm8gKi8NCisJMCwJCS8q IHRwX2FzX2J1ZmZlciAqLw0KKwlQeV9UUEZMQUdTX0RFRkFVTFQgfCBQeV9UUEZMQUdTX0hB VkVfR0NJTkZPLAkvKiB0cF9mbGFncyAqLw0KKwkwLAkJLyogdHBfZG9jICovDQorCShyZWN1 cnNlcHJvYyl0dXBsZXJlY3Vyc2UsCS8qIHRwX3JlY3Vyc2UgKi8NCisjZW5kaWYNCiB9Ow0K IA0KIC8qIFRoZSBmb2xsb3dpbmcgZnVuY3Rpb24gYnJlYWtzIHRoZSBub3Rpb24gdGhhdCB0 dXBsZXMgYXJlIGltbXV0YWJsZToNCkBAIC00NDksNiArNDc4LDkgQEANCiAJaW50IGk7DQog CWludCBzaXplZGlmZjsNCiANCisjaWZkZWYgV0lUSF9DWUNMRV9HQw0KKwlQeUdDSW5mbyAq ZyA9IFBZX0dDSU5GTygqcHYpOyANCisjZW5kaWYNCiAJdiA9IChQeVR1cGxlT2JqZWN0ICop ICpwdjsNCiAJaWYgKHYgPT0gTlVMTCB8fCAhUHlUdXBsZV9DaGVjayh2KSB8fCB2LT5vYl9y ZWZjbnQgIT0gMSkgew0KIAkJKnB2ID0gMDsNCkBAIC00NzksNyArNTExLDYgQEANCiAJfQ0K ICNpZiBNQVhTQVZFU0laRSA+IDANCiAJaWYgKG5ld3NpemUgPT0gMCAmJiBmcmVlX3R1cGxl c1swXSkgew0KLQkJbnVtX2ZyZWVfdHVwbGVzWzBdLS07DQogCQlzdiA9IGZyZWVfdHVwbGVz WzBdOw0KIAkJc3YtPm9iX3NpemUgPSAwOw0KIAkJUHlfSU5DUkVGKHN2KTsNCkBAIC01MTEs OSArNTQyLDIyIEBADQogCX0gZWxzZSANCiAjZW5kaWYJCQ0KIAl7DQorI2lmZGVmIFdJVEhf Q1lDTEVfR0MNCisJCVB5R0NfUmVtb3ZlKChQeU9iamVjdCAqKXYpOw0KKw0KKwkJZyA9IChQ eUdDSW5mbyAqKSByZWFsbG9jKChjaGFyICopZywgc2l6ZW9mKCpnKSArIA0KKwkJCQlzaXpl b2YoUHlUdXBsZU9iamVjdCkgKyANCisJCQkJbmV3c2l6ZSAqIHNpemVvZihQeU9iamVjdCAq KSk7DQorCQlpZiAoZyA9PSBOVUxMKSB7DQorCQkJc3YgPT0gTlVMTDsNCisJCX0gZWxzZSB7 DQorCQkJc3YgPSAoUHlUdXBsZU9iamVjdCAqKSBQWV9HQ09CSihnKTsNCisJCX0NCisjZWxz ZQ0KIAkJc3YgPSAoUHlUdXBsZU9iamVjdCAqKQ0KIAkJCXJlYWxsb2MoKGNoYXIgKil2LA0K IAkJCQlzaXplb2YoUHlUdXBsZU9iamVjdCkgKyBuZXdzaXplICogc2l6ZW9mKFB5T2JqZWN0 ICopKTsNCisjZW5kaWYNCiAJCSpwdiA9IChQeU9iamVjdCAqKSBzdjsNCiAJCWlmIChzdiA9 PSBOVUxMKSB7DQogCQkJUHlNZW1fREVMKHYpOw0KQEAgLTUyMiw2ICs1NjYsOSBAQA0KIAkJ fQ0KIAl9DQogCV9QeV9OZXdSZWZlcmVuY2UoKFB5T2JqZWN0ICopc3YpOw0KKyNpZmRlZiBX SVRIX0NZQ0xFX0dDDQorCVB5R0NfSW5zZXJ0KChQeU9iamVjdCAqKXN2KTsNCisjZW5kaWYN CiAJZm9yIChpID0gc3YtPm9iX3NpemU7IGkgPCBuZXdzaXplOyBpKyspDQogCQlzdi0+b2Jf aXRlbVtpXSA9IE5VTEw7DQogCWlmIChsYXN0X2lzX3N0aWNreSAmJiBzaXplZGlmZiA+IDAp IHsNCkBAIC01NTEsNyArNTk4LDExIEBADQogCQl3aGlsZSAocCkgew0KIAkJCXEgPSBwOw0K IAkJCXAgPSAoUHlUdXBsZU9iamVjdCAqKShwLT5vYl9pdGVtWzBdKTsNCi0JCQlQeU1lbV9E RUwocSk7DQorI2lmZGVmIFB5X1RSQUNFX1JFRlMNCisJCQlxLT5vYl90eXBlID0gICZQeVR1 cGxlX1R5cGU7DQorI2VuZGlmDQorCQkJUHlPYmplY3RfRGVsKChQeU9iamVjdCAqKXEpOw0K KwkJCQ0KIAkJfQ0KIAl9DQogI2VuZGlmDQotLS0gUHl0aG9uLWN2cy9QQy9jb25maWcuYwlG cmkgQXByICA3IDE1OjI3OjA0IDIwMDANCisrKyBQeXRob24tZ2MvUEMvY29uZmlnLmMJU2F0 IEFwciAgOCAwMzoxMjo1OCAyMDAwDQpAQCAtNDEsNiArNDEsOSBAQA0KIGV4dGVybiB2b2lk IGluaXRiaW5hc2NpaSgpOw0KIGV4dGVybiB2b2lkIGluaXRjbWF0aCgpOw0KIGV4dGVybiB2 b2lkIGluaXRlcnJubygpOw0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDDQorZXh0ZXJuIHZvaWQg aW5pdGdjKCk7DQorI2VuZGlmDQogZXh0ZXJuIHZvaWQgaW5pdGltYWdlb3AoKTsNCiBleHRl cm4gdm9pZCBpbml0bWF0aCgpOw0KIGV4dGVybiB2b2lkIGluaXRtZDUoKTsNCkBAIC04MCw2 ICs4Myw5IEBADQogICAgICAgICB7ImJpbmFzY2lpIiwgaW5pdGJpbmFzY2lpfSwNCiAgICAg ICAgIHsiY21hdGgiLCBpbml0Y21hdGh9LA0KICAgICAgICAgeyJlcnJubyIsIGluaXRlcnJu b30sDQorI2lmZGVmIFdJVEhfQ1lDTEVfR0MNCisgICAgICAgIHsiZ2MiLCBpbml0Z2N9LA0K KyNlbmRpZg0KICAgICAgICAgeyJpbWFnZW9wIiwgaW5pdGltYWdlb3B9LA0KICAgICAgICAg eyJtYXRoIiwgaW5pdG1hdGh9LA0KICAgICAgICAgeyJtZDUiLCBpbml0bWQ1fSwNCi0tLSBQ eXRob24tY3ZzL1BDL2NvbmZpZy5oCVRodSBNYXIgMzAgMjI6MDI6NTMgMjAwMA0KKysrIFB5 dGhvbi1nYy9QQy9jb25maWcuaAlTYXQgQXByICA4IDAyOjI0OjAwIDIwMDANCkBAIC0zODEs NiArMzgxLDkgQEANCiAvKiBEZWZpbmUgaWYgeW91IHdhbnQgdG8gdXNlIHRoZSBHTlUgcmVh ZGxpbmUgbGlicmFyeSAqLw0KIC8qICNkZWZpbmUgV0lUSF9SRUFETElORSAxICovDQogDQor LyogRGVmaW5lIGlmIHlvdSB3YW50IGN5Y2xlIGdhcmJhZ2UgY29sbGVjdGlvbiAqLw0KKyNk ZWZpbmUgV0lUSF9DWUNMRV9HQyAxDQorDQogLyogRGVmaW5lIGlmIHlvdSBoYXZlIGNsb2Nr LiAgKi8NCiAvKiAjZGVmaW5lIEhBVkVfQ0xPQ0sgKi8NCiANCi0tLSBQeXRob24tY3ZzL01h a2VmaWxlLmluCVN1biBBcHIgIDIgMjI6NTY6MjUgMjAwMA0KKysrIFB5dGhvbi1nYy9NYWtl ZmlsZS5pbglTYXQgQXByICA4IDAxOjM4OjI1IDIwMDANCkBAIC00MDEsNyArNDAxLDcgQEAN CiAJCSQoSU5TVEFMTF9EQVRBKSBNb2R1bGVzL01ha2VmaWxlICQoTElCUEwpL01ha2VmaWxl DQogCQkkKElOU1RBTExfREFUQSkgTW9kdWxlcy9TZXR1cCAkKExJQlBMKS9TZXR1cA0KIAkJ JChJTlNUQUxMX0RBVEEpIE1vZHVsZXMvU2V0dXAubG9jYWwgJChMSUJQTCkvU2V0dXAubG9j YWwNCi0JCSQoSU5TVEFMTF9EQVRBKSBNb2R1bGVzL1NldHVwLnRocmVhZCAkKExJQlBMKS9T ZXR1cC50aHJlYWQNCisJCSQoSU5TVEFMTF9EQVRBKSBNb2R1bGVzL1NldHVwLmF1dG8gJChM SUJQTCkvU2V0dXAuYXV0bw0KIAkJJChJTlNUQUxMX1BST0dSQU0pICQoc3JjZGlyKS9Nb2R1 bGVzL21ha2VzZXR1cCAkKExJQlBMKS9tYWtlc2V0dXANCiAJCSQoSU5TVEFMTF9QUk9HUkFN KSAkKHNyY2RpcikvaW5zdGFsbC1zaCAkKExJQlBMKS9pbnN0YWxsLXNoDQogCQkkKElOU1RB TExfREFUQSkgJChzcmNkaXIpL01pc2MvTWFrZWZpbGUucHJlLmluICQoTElCUEwpL01ha2Vm aWxlLnByZS5pbg0KLS0tIFB5dGhvbi1jdnMvY29uZmlnLmguaW4JRnJpIE1hciAyNCAyMjoz MTo0MiAyMDAwDQorKysgUHl0aG9uLWdjL2NvbmZpZy5oLmluCVNhdCBBcHIgIDggMDE6Mzg6 MjUgMjAwMA0KQEAgLTIwNCw2ICsyMDQsOSBAQA0KICAgIChzaGFyZWQgbGlicmFyeSBwbHVz IGFjY2Vzc29yeSBmaWxlcykuICovDQogI3VuZGVmIFdJVEhfTkVYVF9GUkFNRVdPUksNCiAN CisvKiBEZWZpbmUgaWYgeW91IHdhbnQgY3ljbGUgZ2FyYmFnZSBjb2xsZWN0aW9uICovDQor I3VuZGVmIFdJVEhfQ1lDTEVfR0MNCisNCiAvKiBUaGUgbnVtYmVyIG9mIGJ5dGVzIGluIGFu IG9mZl90LiAqLw0KICN1bmRlZiBTSVpFT0ZfT0ZGX1QNCiANCi0tLSBQeXRob24tY3ZzL2Nv bmZpZ3VyZS5pbglTdW4gQXByICAyIDIyOjU2OjI1IDIwMDANCisrKyBQeXRob24tZ2MvY29u ZmlndXJlLmluCVNhdCBBcHIgIDggMDE6Mzg6MjUgMjAwMA0KQEAgLTEwNjksMTAgKzEwNjks MjEgQEANCiBmaV0sDQogW0FDX01TR19SRVNVTFQobm8pXSkNCiANCitBQ19TVUJTVChVU0Vf R0NfTU9EVUxFKQ0KK1VTRV9HQ19NT0RVTEU9IiMiDQorDQorQUNfTVNHX0NIRUNLSU5HKGZv ciAtLXdpdGgtY3ljbGUtZ2MpDQorQUNfQVJHX1dJVEgoY3ljbGUtZ2MsIFstLXdpdGgtY3lj bGUtZ2MgICAgICAgICAgIGVuYWJsZSBnYXJiYWdlIGNvbGxlY3Rpb25dLCBbDQorQUNfTVNH X1JFU1VMVCgkd2l0aHZhbCkNCitBQ19ERUZJTkUoV0lUSF9DWUNMRV9HQykNCitVU0VfR0Nf TU9EVUxFPQ0KK10sDQorQUNfTVNHX1JFU1VMVChubykpDQorDQogIyBnZW5lcmF0ZSBvdXRw dXQgZmlsZXMNCiBBQ19PVVRQVVQoTWFrZWZpbGUgXA0KICBPYmplY3RzL01ha2VmaWxlIFwN CiAgUGFyc2VyL01ha2VmaWxlIFwNCiAgUHl0aG9uL01ha2VmaWxlIFwNCiAgTW9kdWxlcy9N YWtlZmlsZS5wcmUgXA0KLSBNb2R1bGVzL1NldHVwLnRocmVhZCkNCisgTW9kdWxlcy9TZXR1 cC5hdXRvKQ0KLS0tIFB5dGhvbi1jdnMvTWlzYy9NYWtlZmlsZS5wcmUuaW4JV2VkIERlYyAg OSAxMDowNTozMyAxOTk4DQorKysgUHl0aG9uLWdjL01pc2MvTWFrZWZpbGUucHJlLmluCVNh dCBBcHIgIDggMDE6Mzg6MjUgMjAwMA0KQEAgLTE2OCw3ICsxNjgsNyBAQA0KIE1BS0VGSUxF PQkkKExJQlBMKS9NYWtlZmlsZQ0KIENPTkZJR0M9CSQoTElCUEwpL2NvbmZpZy5jDQogQ09O RklHQ0lOPQkkKExJQlBMKS9jb25maWcuYy5pbg0KLVNFVFVQPQkJJChMSUJQTCkvU2V0dXAu dGhyZWFkICQoTElCUEwpL1NldHVwLmxvY2FsICQoTElCUEwpL1NldHVwDQorU0VUVVA9CQkk KExJQlBMKS9TZXR1cC5hdXRvICQoTElCUEwpL1NldHVwLmxvY2FsICQoTElCUEwpL1NldHVw DQogDQogU1lTTElCUz0JJChMSUJNKSAkKExJQkMpDQogDQotLS0gUHl0aG9uLWN2cy9Nb2R1 bGVzL01ha2VmaWxlLnByZS5pbglGcmkgTWFyIDI0IDIyOjMyOjI1IDIwMDANCisrKyBQeXRo b24tZ2MvTW9kdWxlcy9NYWtlZmlsZS5wcmUuaW4JU2F0IEFwciAgOCAwMTozODoyNSAyMDAw DQpAQCAtMTQ3LDEwICsxNDcsMTAgQEANCiAjIGdldHMgcmVtYWRlIGZyb20gc2NyYXRjaDsg dGhpcyBlbnN1cmVzIHRvIHJlbW92ZSBtb2R1bGVzIHRoYXQgYXJlIG5vDQogIyBsb25nZXIg cGVydGluZW50IChidXQgdGhhdCB3ZXJlIGluIGEgcHJldmlvdXMgY29uZmlndXJhdGlvbiku DQogY29uZmlnLmMgTWFrZWZpbGU6IE1ha2VmaWxlLnByZSBjb25maWcuYy5pbiAkKE1BS0VT RVRVUCkNCi1jb25maWcuYyBNYWtlZmlsZTogU2V0dXAudGhyZWFkIFNldHVwIFNldHVwLmxv Y2FsDQorY29uZmlnLmMgTWFrZWZpbGU6IFNldHVwLmF1dG8gU2V0dXAgU2V0dXAubG9jYWwN CiBjb25maWcuYyBNYWtlZmlsZToNCiAJCS1ybSAtZiAkKExJQlJBUlkpDQotCQkkKFNIRUxM KSAkKE1BS0VTRVRVUCkgU2V0dXAudGhyZWFkIFNldHVwLmxvY2FsIFNldHVwDQorCQkkKFNI RUxMKSAkKE1BS0VTRVRVUCkgU2V0dXAuYXV0byBTZXR1cC5sb2NhbCBTZXR1cA0KIA0KIGhh c3NpZ25hbDoNCiAJCS1ybSAtZiBoYXNzaWduYWwNCi0tLSBQeXRob24tY3ZzL01vZHVsZXMv U2V0dXAuaW4JU3VuIEFwciAgMiAyMjo1NjozNyAyMDAwDQorKysgUHl0aG9uLWdjL01vZHVs ZXMvU2V0dXAuaW4JU2F0IEFwciAgOCAwMTozODoyNSAyMDAwDQpAQCAtMTAwLDcgKzEwMCw3 IEBADQogR0xIQUNLPS1EY2xlYXI9X19HTGNsZWFyDQogI2dsIGdsbW9kdWxlLmMgY2dlbnN1 cHBvcnQuYyAtSSQoc3JjZGlyKSAkKEdMSEFDSykgLWxnbCAtbFgxMQ0KIA0KLSMgVGhlIHRo cmVhZCBtb2R1bGUgaXMgbm93IGF1dG9tYXRpY2FsbHkgZW5hYmxlZCwgc2VlIFNldHVwLnRo cmVhZC4NCisjIFRoZSB0aHJlYWQgbW9kdWxlIGlzIG5vdyBhdXRvbWF0aWNhbGx5IGVuYWJs ZWQsIHNlZSBTZXR1cC5hdXRvLg0KIA0KICMgUHVyZSBtb2R1bGUuICBDYW5ub3QgYmUgbGlu a2VkIGR5bmFtaWNhbGx5Lg0KICMgLURXSVRIX1FVQU5USUZZLCAtRFdJVEhfUFVSSUZZLCBv ciAtRFdJVEhfQUxMX1BVUkUNCi0tLSBQeXRob24tY3ZzL01vZHVsZXMvU2V0dXAuYXV0by5p bg0KKysrIFB5dGhvbi1nYy9Nb2R1bGVzL1NldHVwLmF1dG8uaW4JU2F0IEFwciAgOCAwMToz ODoyNSAyMDAwDQpAQCAtMCwwICsxLDE2IEBADQorIyBUaGlzIGZpbGUgaXMgdHJhbnNtb2dy aWZpZWQgaW50byBTZXR1cC5hdXRvIGJ5IGNvbmZpZy5zdGF0dXMuICBJdHMNCisjIHB1cnBv c2UgaXMgdG8gYXV0b21hdGljYWxseSBlbmFibGUgbW9kdWxlcyBnaXZlbiB3aGVuIGNlcnRh aW4NCisjIGFyZ3VtZW50cyBhcmUgZ2l2ZW4gdG8gdGhlIGNvbmZpZ3VyZSBzY3JpcHQuICBJ dCByZXBsYWNlcyB0aGUgb2xkDQorIyBTZXR1cC50aHJlYWQuaW4gZmlsZS4NCisNCisjIElu Y2x1ZGUgdGhlIHRocmVhZCBtb2R1bGUgd2hlbiB0aGUgLS13aXRoLXRocmVhZCBhcmd1bWVu dCBpcyBnaXZlbiB0bw0KKyMgdGhlIGNvbmZpZ3VyZSBzY3JpcHQuDQorIw0KKyMgKk5PVEUq OiBpZiB0aGUgY29uZmlndXJlIHNjcmlwdCBkZWNpZGVzIGl0IGNhbid0IHN1cHBvcnQgdGhy ZWFkcywgdGhlDQorIyB0aHJlYWQgbW9kdWxlIHdpbGwgc3RpbGwgYmUgZW5hYmxlZCBhbmQg Y2F1c2UgY29tcGlsZSBlcnJvcnMuICBUaGUNCisjIHNvbHV0aW9uIGlzIG5vdCB0byB1c2Ug LS13aXRoLXRocmVhZCBvbiBwbGF0Zm9ybXMgdGhhdCBkb24ndCBzdXBwb3J0DQorIyB0aHJl YWRzLg0KK0BVU0VfVEhSRUFEX01PRFVMRUB0aHJlYWQgdGhyZWFkbW9kdWxlLmMNCisNCisj IEdhcmJhZ2UgY29sbGVjdGlvbiBlbmFibGVkIHdpdGggLS13aXRoLWN5Y2xlLWdjDQorQFVT RV9HQ19NT0RVTEVAZ2MgZ2Ntb2R1bGUuYw0KLS0tIFB5dGhvbi1jdnMvTGliL3Rlc3QvdGVz dF9nYy5weQ0KKysrIFB5dGhvbi1nYy9MaWIvdGVzdC90ZXN0X2djLnB5CVNhdCBBcHIgIDgg MDM6MjU6MjUgMjAwMA0KQEAgLTAsMCArMSw5MCBAQA0KK2ltcG9ydCBnYw0KKw0KK2RlZiB0 ZXN0X2xpc3QoKToNCisgICAgbCA9IFtdDQorICAgIGwuYXBwZW5kKGwpDQorICAgIHByaW50 ICdsaXN0IDB4JXgnICUgaWQobCkNCisgICAgZ2MuY29sbGVjdCgpDQorICAgIGRlbCBsDQor ICAgIGFzc2VydCBnYy5jb2xsZWN0KCkgPT0gMQ0KKw0KK2RlZiB0ZXN0X2RpY3QoKToNCisg ICAgZCA9IHt9DQorICAgIGRbMV0gPSBkDQorICAgIHByaW50ICdkaWN0IDB4JXgnICUgaWQo ZCkNCisgICAgZ2MuY29sbGVjdCgpDQorICAgIGRlbCBkDQorICAgIGFzc2VydCBnYy5jb2xs ZWN0KCkgPT0gMQ0KKw0KK2RlZiB0ZXN0X3R1cGxlKCk6DQorICAgIGwgPSBbXQ0KKyAgICB0 ID0gKGwsKQ0KKyAgICBsLmFwcGVuZCh0KQ0KKyAgICBwcmludCAnbGlzdCAweCV4JyAlIGlk KGwpDQorICAgIHByaW50ICd0dXBsZSAweCV4JyAlIGlkKHQpDQorICAgIGdjLmNvbGxlY3Qo KQ0KKyAgICBkZWwgdA0KKyAgICBkZWwgbA0KKyAgICBhc3NlcnQgZ2MuY29sbGVjdCgpID09 IDINCisNCitkZWYgdGVzdF9jbGFzcygpOg0KKyAgICBjbGFzcyBBOg0KKyAgICAgICAgcGFz cw0KKyAgICBBLmEgPSBBDQorICAgIHByaW50ICdjbGFzcyAweCV4JyAlIGlkKEEpDQorICAg IGdjLmNvbGxlY3QoKQ0KKyAgICBkZWwgQQ0KKyAgICBhc3NlcnQgZ2MuY29sbGVjdCgpID09 IDINCisNCitkZWYgdGVzdF9pbnN0YW5jZSgpOg0KKyAgICBjbGFzcyBBOg0KKyAgICAgICAg cGFzcw0KKyAgICBhID0gQSgpDQorICAgIGEuYSA9IGENCisgICAgcHJpbnQgcmVwcihhKQ0K KyAgICBnYy5jb2xsZWN0KCkNCisgICAgZGVsIGENCisgICAgYXNzZXJ0IGdjLmNvbGxlY3Qo KSA9PSAyDQorDQorZGVmIHRlc3RfZmluYWxpemVyKCk6DQorICAgIGNsYXNzIEE6DQorICAg ICAgICBkZWYgX19kZWxfXyhzZWxmKTogcGFzcw0KKyAgICBjbGFzcyBCOg0KKyAgICAgICAg cGFzcw0KKyAgICBhID0gQSgpDQorICAgIGEuYSA9IGENCisgICAgaWRfYSA9IGlkKGEpDQor ICAgIGIgPSBCKCkNCisgICAgYi5iID0gYg0KKyAgICBwcmludCAnYScsIHJlcHIoYSkNCisg ICAgcHJpbnQgJ2InLCByZXByKGIpDQorICAgIGdjLmNvbGxlY3QoKQ0KKyAgICBnYy5nYXJi YWdlWzpdID0gW10NCisgICAgZGVsIGENCisgICAgZGVsIGINCisgICAgYXNzZXJ0IGdjLmNv bGxlY3QoKSA9PSA0DQorICAgIGFzc2VydCBpZChnYy5nYXJiYWdlWzBdKSA9PSBpZF9hDQor DQorZGVmIHRlc3RfZnVuY3Rpb24oKToNCisgICAgZCA9IHt9DQorICAgIGV4ZWMoImRlZiBm KCk6IHBhc3NcbiIpIGluIGQNCisgICAgcHJpbnQgJ2RpY3QgMHgleCcgJSBpZChkKQ0KKyAg ICBwcmludCAnZnVuYyAweCV4JyAlIGlkKGRbJ2YnXSkNCisgICAgZ2MuY29sbGVjdCgpDQor ICAgIGRlbCBkDQorICAgIGFzc2VydCBnYy5jb2xsZWN0KCkgPT0gMg0KKw0KKw0KK2RlZiB0 ZXN0X2FsbCgpOg0KKyAgICBkZWJ1ZyA9IGdjLmdldF9kZWJ1ZygpDQorICAgIGdjLnNldF9k ZWJ1ZyhnYy5ERUJVR19MRUFLIHwgZ2MuREVCVUdfU1RBVFMpDQorICAgIHRlc3RfbGlzdCgp DQorICAgIHRlc3RfZGljdCgpDQorICAgIHRlc3RfdHVwbGUoKQ0KKyAgICB0ZXN0X2NsYXNz KCkNCisgICAgdGVzdF9pbnN0YW5jZSgpDQorICAgIHRlc3RfZmluYWxpemVyKCkNCisgICAg dGVzdF9mdW5jdGlvbigpDQorICAgIGdjLnNldF9kZWJ1ZyhkZWJ1ZykNCisNCit0ZXN0X2Fs bCgpDQotLS0gUHl0aG9uLWN2cy9QQ2J1aWxkL3B5dGhvbjE2LmRzcAlGcmkgQXByICA3IDE1 OjI3OjA0IDIwMDANCisrKyBQeXRob24tZ2MvUENidWlsZC9weXRob24xNi5kc3AJU2F0IEFw ciAgOCAwMjoyMjo0OCAyMDAwDQpAQCAtNjQ1LDYgKzY0NSwyMSBAQA0KICMgRW5kIFNvdXJj ZSBGaWxlDQ0KICMgQmVnaW4gU291cmNlIEZpbGUNDQogDQ0KK1NPVVJDRT0uLlxNb2R1bGVz XGdjbW9kdWxlLmMNDQorDQ0KKyFJRiAgIiQoQ0ZHKSIgPT0gInB5dGhvbjE2IC0gV2luMzIg UmVsZWFzZSINDQorDQ0KKyFFTFNFSUYgICIkKENGRykiID09ICJweXRob24xNiAtIFdpbjMy IERlYnVnIg0NCisNDQorIUVMU0VJRiAgIiQoQ0ZHKSIgPT0gInB5dGhvbjE2IC0gV2luMzIg QWxwaGEgRGVidWciDQ0KKw0NCishRUxTRUlGICAiJChDRkcpIiA9PSAicHl0aG9uMTYgLSBX aW4zMiBBbHBoYSBSZWxlYXNlIg0NCisNDQorIUVORElGIA0NCisNDQorIyBFbmQgU291cmNl IEZpbGUNDQorIyBCZWdpbiBTb3VyY2UgRmlsZQ0NCisNDQogU09VUkNFPS4uXFB5dGhvblxn ZXRhcmdzLmMNDQogDQ0KICFJRiAgIiQoQ0ZHKSIgPT0gInB5dGhvbjE2IC0gV2luMzIgUmVs ZWFzZSIN From cgw@fnal.gov Tue Apr 25 17:14:06 2000 From: cgw@fnal.gov (Charles G Waldman) Date: Tue, 25 Apr 2000 11:14:06 -0500 (CDT) Subject: [Patches] Cycle-GC patch, one more time In-Reply-To: <20000425160217.CB7F61CE52@dinsdale.python.org> References: <20000425160217.CB7F61CE52@dinsdale.python.org> Message-ID: <14597.50254.400745.494894@buffalo.fnal.gov> I don't know why these messages keep getting base-64 encoded. I certainly didn't intend to send them that way! The first message I sent had the wrong file attached. Please disregard. Sorry for the confusion. The problems I was having getting Neil's cyclic-gc stuff to work with the latest CVS Python had nothing to do with Trashcan - sorry, Christian! It was my own changes to tupleobject.c. It turned out to be a little tricky to get the GC info handled correctly during _PyTuple_Resize. Below is a version of Neil's patch that applies cleanly to current CVS and seems to work correctly. All credit is due to Neil, I just did a tiny amount of cleanup work in a few places. Differences: (1) The above-mentioned _PyTuple_Resize fix (2) A few problems were exposed by building with Py_TRACE_REFS defined. Specifially, PyObject_New and PyObject_NewVar already do a _Py_NewReference internally, but in a few places PyObject_New is used to create a new object which is then _Py_NewReference'd. If Py_TRACE_REFS is not set, this is merely redundant; with Py_TRACE_REFS set it causes serious problems because the object is added to the reference chain twice. Here's a patch against Neil's patch. Please disregard the earlier messages on this topic. I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. --- gc-cycle.diff.neil Mon Apr 24 20:54:44 2000 +++ gc-cycle.diff.cgw Tue Apr 25 10:50:41 2000 @@ -857,7 +857,7 @@ +} + --- Python-cvs/Objects/classobject.c Tue Feb 29 14:55:15 2000 -+++ Python-gc/Objects/classobject.c Sat Apr 8 02:01:35 2000 ++++ Python-gc/Objects/classobject.c Mon Apr 24 21:19:18 2000 @@ -110,7 +110,7 @@ } Py_INCREF(bases); @@ -947,16 +947,22 @@ if (inst->in_dict == NULL) { Py_DECREF(inst); return NULL; -@@ -498,6 +528,9 @@ +@@ -498,11 +528,14 @@ PyObject *error_type, *error_value, *error_traceback; PyObject *del; static PyObject *delstr; ++ extern long _Py_RefTotal; +#ifdef WITH_CYCLE_GC + PyGC_Remove((PyObject *)inst); +#endif /* Call the __del__ method if it exists. First temporarily revive the object and save the current exception, if any. */ #ifdef Py_TRACE_REFS + /* much too complicated if Py_TRACE_REFS defined */ +- extern long _Py_RefTotal; + inst->ob_type = &PyInstance_Type; + _Py_NewReference((PyObject *)inst); + _Py_RefTotal--; /* compensate for increment in NEWREF */ @@ -550,6 +583,9 @@ #ifdef COUNT_ALLOCS inst->ob_type->tp_free--; @@ -967,7 +973,11 @@ return; /* __del__ added a reference; don't delete now */ } #ifdef Py_TRACE_REFS -@@ -561,7 +597,7 @@ +@@ -557,11 +593,10 @@ + inst->ob_type->tp_free--; /* compensate for increment in UNREF */ + #endif + _Py_ForgetReference((PyObject *)inst); +- inst->ob_type = NULL; #endif /* Py_TRACE_REFS */ Py_DECREF(inst->in_class); Py_XDECREF(inst->in_dict); @@ -976,7 +986,7 @@ } static PyObject * -@@ -837,6 +873,16 @@ +@@ -840,6 +875,16 @@ return outcome; } @@ -993,7 +1003,7 @@ static PyObject *getitemstr, *setitemstr, *delitemstr, *lenstr; static int -@@ -1460,7 +1506,11 @@ +@@ -1463,7 +1508,11 @@ (getattrofunc)instance_getattr, /*tp_getattro*/ (setattrofunc)instance_setattr, /*tp_setattro*/ 0, /* tp_as_buffer */ @@ -1006,7 +1016,7 @@ }; -@@ -1490,7 +1540,7 @@ +@@ -1493,7 +1542,7 @@ _Py_NewReference((PyObject *)im); } else { @@ -1182,8 +1192,8 @@ +#endif }; --- Python-cvs/Objects/listobject.c Fri Mar 24 22:32:30 2000 -+++ Python-gc/Objects/listobject.c Sat Apr 8 02:02:36 2000 -@@ -61,34 +61,38 @@ ++++ Python-gc/Objects/listobject.c Mon Apr 24 21:14:42 2000 +@@ -61,34 +61,37 @@ int i; PyListObject *op; size_t nbytes; @@ -1231,14 +1241,14 @@ + op->ob_item = item; for (i = 0; i < size; i++) op->ob_item[i] = NULL; - _Py_NewReference((PyObject *)op); +- _Py_NewReference((PyObject *)op); +#ifdef WITH_CYCLE_GC + PyGC_Insert((PyObject *)op); +#endif return (PyObject *) op; } -@@ -216,6 +220,9 @@ +@@ -216,6 +219,9 @@ { int i; Py_TRASHCAN_SAFE_BEGIN(op) @@ -1248,7 +1258,7 @@ if (op->ob_item != NULL) { /* Do it backwards, for Christian Tismer. There's a simple test case where somehow this reduces -@@ -227,7 +234,7 @@ +@@ -227,7 +233,7 @@ } free((ANY *)op->ob_item); } @@ -1257,7 +1267,7 @@ Py_TRASHCAN_SAFE_END(op) } -@@ -1399,6 +1406,29 @@ +@@ -1399,6 +1405,29 @@ return NULL; } @@ -1287,7 +1297,7 @@ static char append_doc[] = "L.append(object) -- append object to end"; static char extend_doc[] = -@@ -1464,6 +1494,18 @@ +@@ -1464,6 +1493,18 @@ 0, /*tp_as_number*/ &list_as_sequence, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ @@ -1306,7 +1316,7 @@ }; -@@ -1532,5 +1574,16 @@ +@@ -1532,5 +1573,16 @@ 0, /*tp_as_number*/ &immutable_list_as_sequence, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ @@ -1440,8 +1450,18 @@ int --- Python-cvs/Objects/tupleobject.c Fri Mar 24 22:32:30 2000 -+++ Python-gc/Objects/tupleobject.c Sat Apr 8 02:11:45 2000 -@@ -91,12 +91,10 @@ ++++ Python-gc/Objects/tupleobject.c Mon Apr 24 21:21:59 2000 +@@ -82,8 +82,8 @@ + #endif + #ifdef Py_TRACE_REFS + op->ob_type = &PyTuple_Type; +- op->ob_size = size; + #endif ++ _Py_NewReference((PyObject *)op); + } + else + #endif +@@ -97,23 +97,23 @@ return PyErr_NoMemory(); } ; @@ -1455,7 +1475,12 @@ } for (i = 0; i < size; i++) op->ob_item[i] = NULL; -@@ -107,6 +105,9 @@ +- _Py_NewReference((PyObject *)op); ++ + #if MAXSAVESIZE > 0 + if (size == 0) { + free_tuples[0] = op; +- ++num_free_tuples[0]; Py_INCREF(op); /* extra INCREF so that this is never freed */ } #endif @@ -1465,17 +1490,17 @@ return (PyObject *) op; } -@@ -173,6 +174,9 @@ +@@ -180,6 +180,9 @@ register int i; - + register int len = op->ob_size; Py_TRASHCAN_SAFE_BEGIN(op) +#ifdef WITH_CYCLE_GC + PyGC_Remove((PyObject *)op); +#endif - if (op->ob_size > 0) { - i = op->ob_size; + if (len > 0) { + i = len; while (--i >= 0) -@@ -185,7 +189,7 @@ +@@ -193,7 +196,7 @@ } #endif } @@ -1484,7 +1509,7 @@ done: Py_TRASHCAN_SAFE_END(op) } -@@ -393,6 +397,22 @@ +@@ -401,6 +404,22 @@ return (PyObject *) np; } @@ -1507,7 +1532,7 @@ static PySequenceMethods tuple_as_sequence = { (inquiry)tuplelength, /*sq_length*/ (binaryfunc)tupleconcat, /*sq_concat*/ -@@ -419,6 +439,16 @@ +@@ -427,6 +446,16 @@ &tuple_as_sequence, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ (hashfunc)tuplehash, /*tp_hash*/ @@ -1524,43 +1549,49 @@ }; /* The following function breaks the notion that tuples are immutable: -@@ -441,6 +471,10 @@ +@@ -449,6 +478,9 @@ int i; int sizediff; +#ifdef WITH_CYCLE_GC + PyGCInfo *g = PY_GCINFO(*pv); -+ PyGC_Remove(*pv); +#endif v = (PyTupleObject *) *pv; if (v == NULL || !PyTuple_Check(v) || v->ob_refcnt != 1) { *pv = 0; -@@ -469,16 +503,29 @@ - Py_XDECREF(v->ob_item[i]); - v->ob_item[i] = NULL; - } -- sv = (PyTupleObject *) -- realloc((char *)v, -- sizeof(PyTupleObject) + newsize * sizeof(PyObject *)); +@@ -479,7 +511,6 @@ + } + #if MAXSAVESIZE > 0 + if (newsize == 0 && free_tuples[0]) { +- num_free_tuples[0]--; + sv = free_tuples[0]; + sv->ob_size = 0; + Py_INCREF(sv); +@@ -511,9 +542,22 @@ + } else + #endif + { +#ifdef WITH_CYCLE_GC -+ g = (PyGCInfo *) realloc((char *)g, sizeof(*g) + ++ PyGC_Remove((PyObject *)v); ++ ++ g = (PyGCInfo *) realloc((char *)g, sizeof(*g) + + sizeof(PyTupleObject) + + newsize * sizeof(PyObject *)); -+ if (g == NULL) { -+ sv == NULL; -+ } else { -+ sv = (PyTupleObject *) PY_GCOBJ(g); -+ } ++ if (g == NULL) { ++ sv == NULL; ++ } else { ++ sv = (PyTupleObject *) PY_GCOBJ(g); ++ } +#else -+ sv = (PyTupleObject *) realloc((char *)v, sizeof(PyTupleObject) + -+ newsize * sizeof(PyObject *)); -+#endif - *pv = (PyObject *) sv; - if (sv == NULL) { -- PyMem_DEL(v); -+ PyObject_Del((PyObject *)v); - PyErr_NoMemory(); - return -1; + sv = (PyTupleObject *) + realloc((char *)v, + sizeof(PyTupleObject) + newsize * sizeof(PyObject *)); ++#endif + *pv = (PyObject *) sv; + if (sv == NULL) { + PyMem_DEL(v); +@@ -522,6 +566,9 @@ + } } _Py_NewReference((PyObject *)sv); +#ifdef WITH_CYCLE_GC @@ -1569,12 +1600,16 @@ for (i = sv->ob_size; i < newsize; i++) sv->ob_item[i] = NULL; if (last_is_sticky && sizediff > 0) { -@@ -508,7 +555,7 @@ +@@ -551,7 +598,11 @@ while (p) { q = p; p = (PyTupleObject *)(p->ob_item[0]); - PyMem_DEL(q); ++#ifdef Py_TRACE_REFS ++ q->ob_type = &PyTuple_Type; ++#endif + PyObject_Del((PyObject *)q); ++ } } #endif > Send Patches mailing list submissions to > patches@python.org > > To subscribe or unsubscribe via the World Wide Web, visit > http://www.python.org/mailman/listinfo/patches > or, via email, send a message with subject or body 'help' to > patches-request@python.org > > You can reach the person managing the list at > patches-admin@python.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Patches digest..." > > > Today's Topics: > > 1. Re: Slightly cleaned-up cycle-gc patch (Christian Tismer) > 2. Sightly clean-up cycle-gc patch (Charles G Waldman) > > --__--__-- > > Message: 1 > Date: Tue, 25 Apr 2000 18:07:00 +0200 > From: Christian Tismer > To: Charles G Waldman > Cc: patches@python.org > Subject: Re: [Patches] Slightly cleaned-up cycle-gc patch > > > > Charles G Waldman wrote: > > > > The problems I was having getting Neil's cyclic-gc stuff to work with > > the latest CVS Python had nothing to do with Trashcan - sorry, > > Christian! > > Tss tss - my poor little trashcan pet, now it's happy again :-) > > ciao - chris > > p.s.: Oh, did you look at the end of your patch? > There appears to be some binary crap. Maybe your > python16.dsp file is broekn? > > -- > Christian Tismer :^) > Applied Biometrics GmbH : Have a break! Take a ride on Python's > Kaunstr. 26 : *Starship* http://starship.python.net > 14163 Berlin : PGP key -> http://wwwkeys.pgp.net > PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF > where do you want to jump today? http://www.stackless.com > > > --__--__-- > > Message: 2 > From: Charles G Waldman > Date: Tue, 25 Apr 2000 11:02:09 -0500 (CDT) > To: patches@python.org > Subject: [Patches] Sightly clean-up cycle-gc patch > > DQogSSBkb24ndCBrbm93IHdoYXQgaGFwcGVuZWQgd2l0aCB0aGF0IGxhc3QgbWVzc2FnZSAt > IGl0IHNvbWVob3cgZ290DQpiYXNlLTY0IGVuY29kZWQgd2l0aG91dCBtZSBhc2tpbmcgZm9y > IHRoYXQuICBTb3JyeSEgIFR1cm5zIG91dCB0aGF0DQpub3Qgb25seSB3YXMgdGhlIG1lc3Nh > Z2UgdW5yZWFkYWJsZSwgYnV0IEkgYXR0YWNoZWQgdGhlIHdyb25nIGZpbGUuDQpEb3VibGUt > b29wcyENCg0KDQpUaGUgcHJvYmxlbXMgSSB3YXMgaGF2aW5nIGdldHRpbmcgTmVpbCdzIGN5 > Y2xpYy1nYyBzdHVmZiB0byB3b3JrIHdpdGgNCnRoZSBsYXRlc3QgQ1ZTIFB5dGhvbiBoYWQg > bm90aGluZyB0byBkbyB3aXRoIFRyYXNoY2FuIC0gc29ycnksDQpDaHJpc3RpYW4hICBJdCB3 > YXMgbXkgb3duIGNoYW5nZXMgdG8gdHVwbGVvYmplY3QuYy4gIEl0IHR1cm5lZCBvdXQgdG8N > CmJlIGEgbGl0dGxlIHRyaWNreSB0byBnZXQgdGhlIEdDIGluZm8gaGFuZGxlZCBjb3JyZWN0 > bHkgZHVyaW5nDQpfUHlUdXBsZV9SZXNpemUuICBCZWxvdyBpcyBhIHZlcnNpb24gb2YgTmVp > bCdzIHBhdGNoIHRoYXQgYXBwbGllcw0KY2xlYW5seSB0byBjdXJyZW50IENWUyBhbmQgc2Vl > bXMgdG8gd29yayBjb3JyZWN0bHkuICBBbGwgY3JlZGl0IGlzIGR1ZQ0KdG8gTmVpbCwgSSBq > dXN0IGRpZCBhIHRpbnkgYW1vdW50IG9mIGNsZWFudXAgd29yayBpbiBhIGZldyBwbGFjZXMu > DQooSSB3YXMgdGhpbmtpbmcgb2YgcG9zdGluZyB0aGlzIGFzIGEgZGlmZiB0byBOZWlsJ3Mg > ZGlmZiwgYnV0IHdhc24ndA0Kc3VyZSBob3cgdGhhdCB3b3VsZCBnbyBvdmVyLi4uICBJZiB0 > aGlzIGdldHMgY2hlY2tlZCBpbiBpdCB3aWxsIGJlIGENCmxvdCBlYXNpZXIgdG8gd29yayBv > biBpdCBhbmQgc2VuZCBzbWFsbCBwYXRjaGVzLCByYXRoZXIgdGhhbiBoYXZpbmcgdG8NCnJl > Z2VuZXJhdGUgdGhlIHdob2xlIHRoaW5nIGVhY2ggdGltZSkuDQoNCg0KDQpEaWZmZXJlbmNl > czogIA0KDQogICgxKSBUaGUgYWJvdmUtbWVudGlvbmVkIF9QeVR1cGxlX1Jlc2l6ZSBmaXgN > Cg0KICAoMikgQSBmZXcgcHJvYmxlbXMgd2VyZSBleHBvc2VkIGJ5IGJ1aWxkaW5nIHdpdGgg > UHlfVFJBQ0VfUkVGUw0KICBkZWZpbmVkLiAgU3BlY2lmaWFsbHksIFB5T2JqZWN0X05ldyBh > bmQgUHlPYmplY3RfTmV3VmFyIGFscmVhZHkgZG8gYQ0KICBfUHlfTmV3UmVmZXJlbmNlIGlu > dGVybmFsbHksIGJ1dCBpbiBhIGZldyBwbGFjZXMgKGUuZy4gUHlMaXN0X05ldyksDQogIFB5 > T2JqZWN0X05ldyB3YXMgYmVpbmcgdXNlZCB0byBjcmVhdGUgYSBuZXcgb2JqZWN0IHdoaWNo > IGlzIHRoZW4NCiAgX1B5X05ld1JlZmVyZW5jZSdkLiAgSWYgUHlfVFJBQ0VfUkVGUyBpcyBu > b3Qgc2V0LCB0aGlzIGlzIG1lcmVseQ0KICByZWR1bmRhbnQ7IHdpdGggUHlfVFJBQ0VfUkVG > UyBzZXQgaXQgY2F1c2VzIHNlcmlvdXMgcHJvYmxlbXMgYmVjYXVzZQ0KICB0aGUgb2JqZWN0 > IGlzIGFkZGVkIHRvIHRoZSByZWZlcmVuY2UgY2hhaW4gdHdpY2UuDQoNCg0KDQogICAgICAg > ICAgICAgICAgICAgSSBjb25maXJtIHRoYXQsIHRvIHRoZSBiZXN0IG9mIG15IGtub3dsZWRn > ZSBhbmQgYmVsaWVmLCB0aGlzDQogICAgICAgICAgICAgICAgICAgY29udHJpYnV0aW9uIGlz > IGZyZWUgb2YgYW55IGNsYWltcyBvZiB0aGlyZCBwYXJ0aWVzIHVuZGVyDQogICAgICAgICAg > ICAgICAgICAgY29weXJpZ2h0LCBwYXRlbnQgb3Igb3RoZXIgcmlnaHRzIG9yIGludGVyZXN0 > cyAoImNsYWltcyIpLiAgVG8NCiAgICAgICAgICAgICAgICAgICB0aGUgZXh0ZW50IHRoYXQg > SSBoYXZlIGFueSBzdWNoIGNsYWltcywgSSBoZXJlYnkgZ3JhbnQgdG8gQ05SSSBhDQogICAg > ICAgICAgICAgICAgICAgbm9uZXhjbHVzaXZlLCBpcnJldm9jYWJsZSwgcm95YWx0eS1mcmVl > LCB3b3JsZHdpZGUgbGljZW5zZSB0bw0KICAgICAgICAgICAgICAgICAgIHJlcHJvZHVjZSwg > ZGlzdHJpYnV0ZSwgcGVyZm9ybSBhbmQvb3IgZGlzcGxheSBwdWJsaWNseSwgcHJlcGFyZQ0K > ICAgICAgICAgICAgICAgICAgIGRlcml2YXRpdmUgdmVyc2lvbnMsIGFuZCBvdGhlcndpc2Ug > dXNlIHRoaXMgY29udHJpYnV0aW9uIGFzIHBhcnQNCiAgICAgICAgICAgICAgICAgICBvZiB0 > aGUgUHl0aG9uIHNvZnR3YXJlIGFuZCBpdHMgcmVsYXRlZCBkb2N1bWVudGF0aW9uLCBvciBh > bnkNCiAgICAgICAgICAgICAgICAgICBkZXJpdmF0aXZlIHZlcnNpb25zIHRoZXJlb2YsIGF0 > IG5vIGNvc3QgdG8gQ05SSSBvciBpdHMgbGljZW5zZWQNCiAgICAgICAgICAgICAgICAgICB1 > c2VycywgYW5kIHRvIGF1dGhvcml6ZSBvdGhlcnMgdG8gZG8gc28uDQoNCiAgICAgICAgICAg > ICAgICAgICBJIGFja25vd2xlZGdlIHRoYXQgQ05SSSBtYXksIGF0IGl0cyBzb2xlIGRpc2Ny > ZXRpb24sIGRlY2lkZQ0KICAgICAgICAgICAgICAgICAgIHdoZXRoZXIgb3Igbm90IHRvIGlu > Y29ycG9yYXRlIHRoaXMgY29udHJpYnV0aW9uIGluIHRoZSBQeXRob24NCiAgICAgICAgICAg > ICAgICAgICBzb2Z0d2FyZSBhbmQgaXRzIHJlbGF0ZWQgZG9jdW1lbnRhdGlvbi4gIEkgZnVy > dGhlciBncmFudCBDTlJJDQogICAgICAgICAgICAgICAgICAgcGVybWlzc2lvbiB0byB1c2Ug > bXkgbmFtZSBhbmQgb3RoZXIgaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24NCiAgICAgICAgICAg > ICAgICAgICBwcm92aWRlZCB0byBDTlJJIGJ5IG1lIGZvciB1c2UgaW4gY29ubmVjdGlvbiB3 > aXRoIHRoZSBQeXRob24NCiAgICAgICAgICAgICAgICAgICBzb2Z0d2FyZSBhbmQgaXRzIHJl > bGF0ZWQgZG9jdW1lbnRhdGlvbi4NCg0KLS0tIFB5dGhvbi1jdnMvSW5jbHVkZS9vYmplY3Qu > aAlGcmkgTWFyIDI0IDIyOjMyOjE2IDIwMDANCisrKyBQeXRob24tZ2MvSW5jbHVkZS9vYmpl > Y3QuaAlTYXQgQXByICA4IDAxOjM4OjI1IDIwMDANCkBAIC0xNDUsNiArMTQ1LDEwIEBADQog > dHlwZWRlZiBpbnQgKCpnZXRzZWdjb3VudHByb2MpIFB5X1BST1RPKChQeU9iamVjdCAqLCBp > bnQgKikpOw0KIHR5cGVkZWYgaW50ICgqZ2V0Y2hhcmJ1ZmZlcnByb2MpIFB5X1BST1RPKChQ > eU9iamVjdCAqLCBpbnQsIGNvbnN0IGNoYXIgKiopKTsNCiB0eXBlZGVmIGludCAoKm9iam9i > anByb2MpIFB5X1BST1RPKChQeU9iamVjdCAqLCBQeU9iamVjdCAqKSk7DQorI2lmZGVmIFdJ > VEhfQ1lDTEVfR0MNCit0eXBlZGVmIGludCAoKnZpc2l0cHJvYykgUHlfUFJPVE8oKFB5T2Jq > ZWN0ICosIHZvaWQgKikpOw0KK3R5cGVkZWYgaW50ICgqcmVjdXJzZXByb2MpIFB5X1BST1RP > KChQeU9iamVjdCAqLCB2aXNpdHByb2MsIHZvaWQgKikpOw0KKyNlbmRpZg0KIA0KIHR5cGVk > ZWYgc3RydWN0IHsNCiAJYmluYXJ5ZnVuYyBuYl9hZGQ7DQpAQCAtMjQzLDkgKzI0NywxOCBA > QA0KIA0KIAljaGFyICp0cF9kb2M7IC8qIERvY3VtZW50YXRpb24gc3RyaW5nICovDQogDQot > CS8qIE1vcmUgc3BhcmVzICovDQorI2lmZGVmIFdJVEhfQ1lDTEVfR0MNCisJLyogY2FsbCBm > dW5jdGlvbiBmb3IgYWxsIGFjY2Vzc2libGUgb2JqZWN0cyAqLw0KKwlyZWN1cnNlcHJvYyB0 > cF9yZWN1cnNlOw0KKwkNCisJLyogZGVsZXRlIHJlZmVyZW5jZXMgdG8gY29udGFpbmVkIG9i > amVjdHMgKi8NCisJaW5xdWlyeSB0cF9jbGVhcjsNCisjZWxzZQ0KIAlsb25nIHRwX3h4eDU7 > DQogCWxvbmcgdHBfeHh4NjsNCisjZW5kaWYNCisNCisJLyogTW9yZSBzcGFyZXMgKi8NCiAJ > bG9uZyB0cF94eHg3Ow0KIAlsb25nIHRwX3h4eDg7DQogDQpAQCAtMzE1LDYgKzMyOCw5IEBA > DQogDQogLyogUHlTZXF1ZW5jZU1ldGhvZHMgY29udGFpbnMgc3FfY29udGFpbnMgKi8NCiAj > ZGVmaW5lIFB5X1RQRkxBR1NfSEFWRV9TRVFVRU5DRV9JTiAoMUw8PDEpDQorDQorLyogT2Jq > ZWN0cyB3aXRoIGEgR0MgaW5mbyBwcmVmaXggKGFsbG9jYXRlZCAqYmVmb3JlKiB0aGUgb2Jq > ZWN0IGl0c2VsZiEpICovDQorI2RlZmluZSBQeV9UUEZMQUdTX0hBVkVfR0NJTkZPICgxTDw8 > MikNCiANCiAjZGVmaW5lIFB5X1RQRkxBR1NfREVGQVVMVCAgKFB5X1RQRkxBR1NfSEFWRV9H > RVRDSEFSQlVGRkVSIHwgXA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfVFBG > TEFHU19IQVZFX1NFUVVFTkNFX0lOKQ0KLS0tIFB5dGhvbi1jdnMvSW5jbHVkZS9vYmppbXBs > LmgJVGh1IE1hciAgMiAxNzowMjoyMyAyMDAwDQorKysgUHl0aG9uLWdjL0luY2x1ZGUvb2Jq > aW1wbC5oCVNhdCBBcHIgIDggMDM6MTg6MjIgMjAwMA0KQEAgLTM4LDggKzM4LDQyIEBADQog > LyoNCiBBZGRpdGlvbmFsIG1hY3JvcyBmb3IgbW9kdWxlcyB0aGF0IGltcGxlbWVudCBuZXcg > b2JqZWN0IHR5cGVzLg0KIFlvdSBtdXN0IGZpcnN0IGluY2x1ZGUgIm9iamVjdC5oIi4NCisq > Lw0KKw0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDIA0KKw0KKy8qIFN0cnVjdHVyZSAqcHJlZml4 > ZWQqIHRvIGNvbnRhaW5lciBvYmplY3RzIHBhcnRpY2lwYXRpbmcgaW4gR0MgKi8gDQordHlw > ZWRlZiBzdHJ1Y3QgX2djaW5mbyB7DQorCXN0cnVjdCBfZ2NpbmZvICpnY19uZXh0Ow0KKwlz > dHJ1Y3QgX2djaW5mbyAqZ2NfcHJldjsNCisJaW50IGdjX3JlZnM7DQorfSBQeUdDSW5mbzsN > CisNCisvKiBUZXN0IGlmIGEgdHlwZSBoYXMgR0MgaW5mbyAqLw0KKyNkZWZpbmUgUFlfVFlQ > RUlTR0ModCkgUHlUeXBlX0hhc0ZlYXR1cmUoKHQpLCBQeV9UUEZMQUdTX0hBVkVfR0NJTkZP > KQ0KKw0KKy8qIFRlc3QgaWYgYW4gb2JqZWN0IGhhcyBHQyBpbmZvICovDQorI2RlZmluZSBQ > WV9JU0dDKG8pIFBZX1RZUEVJU0dDKChvKS0+b2JfdHlwZSkNCisNCisvKiBHZXQgYW4gb2Jq > ZWN0J3MgR0MgaW5mbyAtLSBOVUxMIGlmIHRoZSBvYmplY3QgaGFzIG5vbmUgKi8NCisjZGVm > aW5lIFBZX0dDSU5GTyhvKSAoUFlfSVNHQyhvKSA/ICgoUHlHQ0luZm8gKikobyktMSkgOiBO > VUxMKQ0KKw0KKy8qIFVuc2FmZSB2ZXJzaW9uIG9mIFBZX0dDSU5GTygpIC0tIG9ubHkgY2Fs > bCBpZiBQWV9JU0dDKHApIGlzIHRydWUgKi8NCisjZGVmaW5lIFBZX0dDSU5GT19VTlNBRkUo > bykgKChQeUdDSW5mbyAqKShvKS0xKQ0KKw0KKy8qIEdldCB0aGUgb2JqZWN0IGdpdmVuIHRo > ZSBQeUdDSW5mbyAqLw0KKyNkZWZpbmUgUFlfR0NPQkooZykgKChQeU9iamVjdCAqKSgoZykr > MSkpDQogDQotUHlPYmplY3RfTkVXKHR5cGUsIHR5cGVvYmopIGFsbG9jYXRlcyBtZW1vcnkg > Zm9yIGEgbmV3IG9iamVjdCBvZiB0aGUgZ2l2ZW4NCisvKiBBZGQgdGhlIG9iamVjdCBpbnRv > IHRoZSBjb250YWluZXIgc2V0ICovDQorZXh0ZXJuIERMX0lNUE9SVCh2b2lkKSBQeUdDX0lu > c2VydCBQeV9QUk9UTygoUHlPYmplY3QgKikpOw0KKw0KKy8qIFJlbW92ZSB0aGUgb2JqZWN0 > IGZyb20gdGhlIGNvbnRhaW5lciBzZXQgKi8NCitleHRlcm4gRExfSU1QT1JUKHZvaWQpIFB5 > R0NfUmVtb3ZlIFB5X1BST1RPKChQeU9iamVjdCAqKSk7DQorDQorI2VuZGlmDQorDQorLyoN > CitQeU9iamVjdF9OZXcodHlwZSwgdHlwZW9iaikgYWxsb2NhdGVzIG1lbW9yeSBmb3IgYSBu > ZXcgb2JqZWN0IG9mIHRoZSBnaXZlbg0KIHR5cGU7IGhlcmUgJ3R5cGUnIG11c3QgYmUgdGhl > IEMgc3RydWN0dXJlIHR5cGUgdXNlZCB0byByZXByZXNlbnQgdGhlDQogb2JqZWN0IGFuZCAn > dHlwZW9iaicgdGhlIGFkZHJlc3Mgb2YgdGhlIGNvcnJlc3BvbmRpbmcgdHlwZSBvYmplY3Qu > DQogUmVmZXJlbmNlIGNvdW50IGFuZCB0eXBlIHBvaW50ZXIgYXJlIGZpbGxlZCBpbjsgdGhl > IHJlc3Qgb2YgdGhlIGJ5dGVzIG9mDQpAQCAtNDcsMzAgKzgxLDI5IEBADQogVGhlIHNpemUg > b2YgdGhlIG9iamVjdCBpcyBhY3R1YWxseSBkZXRlcm1pbmVkIGJ5IHRoZSB0cF9iYXNpY3Np > emUgZmllbGQNCiBvZiB0aGUgdHlwZSBvYmplY3QuDQogDQotUHlPYmplY3RfTkVXX1ZBUih0 > eXBlLCB0eXBlb2JqLCBuKSBpcyBzaW1pbGFyIGJ1dCBhbGxvY2F0ZXMgYSB2YXJpYWJsZS1z > aXplDQorUHlPYmplY3RfTmV3VmFyKHR5cGUsIHR5cGVvYmosIG4pIGlzIHNpbWlsYXIgYnV0 > IGFsbG9jYXRlcyBhIHZhcmlhYmxlLXNpemUNCiBvYmplY3Qgd2l0aCBuIGV4dHJhIGl0ZW1z > LiAgVGhlIHNpemUgaXMgY29tcHV0ZWQgYXMgdHBfYmFzaWNzaXplIHBsdXMNCiBuICogdHBf > aXRlbXNpemUuICBUaGlzIGZpbGxzIGluIHRoZSBvYl9zaXplIGZpZWxkIGFzIHdlbGwuDQog > Ki8NCiANCi0jaWZuZGVmIE1TX0NPUkVETEwNCiBleHRlcm4gRExfSU1QT1JUKFB5T2JqZWN0 > ICopIF9QeU9iamVjdF9OZXcgUHlfUFJPVE8oKFB5VHlwZU9iamVjdCAqKSk7DQogZXh0ZXJu > IERMX0lNUE9SVChQeVZhck9iamVjdCAqKSBfUHlPYmplY3RfTmV3VmFyIFB5X1BST1RPKChQ > eVR5cGVPYmplY3QgKiwgaW50KSk7DQorZXh0ZXJuIERMX0lNUE9SVCh2b2lkKSBQeU9iamVj > dF9EZWwgUHlfUFJPVE8oKFB5T2JqZWN0ICopKTsNCiANCi0jZGVmaW5lIFB5T2JqZWN0X05F > Vyh0eXBlLCB0eXBlb2JqKSAoKHR5cGUgKikgX1B5T2JqZWN0X05ldyh0eXBlb2JqKSkNCi0j > ZGVmaW5lIFB5T2JqZWN0X05FV19WQVIodHlwZSwgdHlwZW9iaiwgbikgKCh0eXBlICopIF9Q > eU9iamVjdF9OZXdWYXIodHlwZW9iaiwgbikpDQotDQotI2Vsc2UNCi0vKiBGb3IgYW4gTVMt > V2luZG93cyBETEwsIHdlIGNoYW5nZSB0aGUgd2F5IGFuIG9iamVjdCBpcyBjcmVhdGVkLCBz > byB0aGF0IHRoZQ0KLSAgIGV4dGVuc2lvbiBtb2R1bGUncyBtYWxsb2MgaXMgdXNlZCwgcmF0 > aGVyIHRoYW4gdGhlIGNvcmUgRExMIG1hbGxvYywgYXMgdGhlcmUgaXMNCi0gICBubyBndWFy > YW50ZWUgdGhleSB3aWxsIHVzZSB0aGUgc2FtZSBoZWFwDQotKi8NCi1leHRlcm4gRExfSU1Q > T1JUKFB5T2JqZWN0ICopIF9QeU9iamVjdF9OZXcgUHlfUFJPVE8oKFB5VHlwZU9iamVjdCAq > LCBQeU9iamVjdCAqKSk7DQotZXh0ZXJuIERMX0lNUE9SVChQeVZhck9iamVjdCAqKSBfUHlP > YmplY3RfTmV3VmFyIFB5X1BST1RPKChQeVR5cGVPYmplY3QgKiwgaW50LCBQeVZhck9iamVj > dCAqKSk7DQotDQotI2RlZmluZSBQeU9iamVjdF9ORVcodHlwZSwgdHlwZW9iaikgKCh0eXBl > ICopIF9QeU9iamVjdF9OZXcodHlwZW9iaiwoUHlPYmplY3QgKiltYWxsb2MoKHR5cGVvYmop > LT50cF9iYXNpY3NpemUpKSkNCi0jZGVmaW5lIFB5T2JqZWN0X05FV19WQVIodHlwZSwgdHlw > ZW9iaiwgbikgKCh0eXBlICopIF9QeU9iamVjdF9OZXdWYXIodHlwZW9iaiwgbiwgKFB5VmFy > T2JqZWN0ICopbWFsbG9jKCh0eXBlb2JqKS0+dHBfYmFzaWNzaXplICsgbiAqICh0eXBlb2Jq > KS0+dHBfaXRlbXNpemUpKSkNCi0NCi0jZW5kaWYgLyogTVNfQ09SRURMTCAqLw0KKy8qIEZ1 > bmN0aW9ucyAqLw0KKyNkZWZpbmUgUHlPYmplY3RfTmV3KHR5cGUsIHR5cGVvYmopIFwNCisJ > CSgodHlwZSAqKSBfUHlPYmplY3RfTmV3KHR5cGVvYmopKQ0KKyNkZWZpbmUgUHlPYmplY3Rf > TmV3VmFyKHR5cGUsIHR5cGVvYmosIG4pIFwNCisgICAgICAgICAgICAgICAgKCh0eXBlICop > IF9QeU9iamVjdF9OZXdWYXIoKHR5cGVvYmopLCAobikpKQ0KKw0KKw0KK2V4dGVybiBETF9J > TVBPUlQoUHlPYmplY3QgKikgX1B5T2JqZWN0X0Zyb21UeXBlIFB5X1BST1RPKChQeVR5cGVP > YmplY3QgKiwgUHlPYmplY3QgKikpOw0KK2V4dGVybiBETF9JTVBPUlQoUHlWYXJPYmplY3Qg > KikgX1B5T2JqZWN0X1ZhckZyb21UeXBlIFB5X1BST1RPKChQeVR5cGVPYmplY3QgKiwgaW50 > LCBQeVZhck9iamVjdCAqKSk7DQorDQorLyogVGhlc2UgbWFjcm9zIG1heSBub3QgdXNlIHRo > ZSBzYW1lIG1hbGxvYyBhcyBQeXRob24uIFRoZXkgY2Fubm90IGJlIHVzZWQNCisgKiBvYmpl > Y3RzIHRoYXQgYXJlIGludm9sdmVkIGluIGdhcmJhZ2UgY29sbGVjdGlvbiAqLw0KKyNkZWZp > bmUgUHlPYmplY3RfTkVXKHR5cGUsIHR5cGVvYmopICgodHlwZSAqKSBfUHlPYmplY3RfRnJv > bVR5cGUodHlwZW9iaiwoUHlPYmplY3QgKiltYWxsb2MoKHR5cGVvYmopLT50cF9iYXNpY3Np > emUpKSkNCisjZGVmaW5lIFB5T2JqZWN0X05FV19WQVIodHlwZSwgdHlwZW9iaiwgbikgKCh0 > eXBlICopIF9QeU9iamVjdF9WYXJGcm9tVHlwZSh0eXBlb2JqLCBuLCAoUHlWYXJPYmplY3Qg > KiltYWxsb2MoKHR5cGVvYmopLT50cF9iYXNpY3NpemUgKyBuICogKHR5cGVvYmopLT50cF9p > dGVtc2l6ZSkpKQ0KIA0KICNpZmRlZiBfX2NwbHVzcGx1cw0KIH0NCi0tLSBQeXRob24tY3Zz > L01vZHVsZXMvY1BpY2tsZS5jCUZyaSBNYXIgMjQgMjI6MzI6MjUgMjAwMA0KKysrIFB5dGhv > bi1nYy9Nb2R1bGVzL2NQaWNrbGUuYwlTYXQgQXByICA4IDAyOjEzOjExIDIwMDANCkBAIC0y > ODg2LDcgKzI4ODYsNyBAQA0KICAgICAgICAgICAgICAgUHlJbnN0YW5jZU9iamVjdCAqaW5z > dDsNCiANCiAgICAgICAgICAgICAgIFB5RXJyX0NsZWFyKCk7DQotICAgICAgICAgICAgICBV > TkxFU1MgKGluc3Q9UHlPYmplY3RfTkVXKFB5SW5zdGFuY2VPYmplY3QsICZQeUluc3RhbmNl > X1R5cGUpKQ0KKyAgICAgICAgICAgICAgVU5MRVNTIChpbnN0PVB5T2JqZWN0X05ldyhQeUlu > c3RhbmNlT2JqZWN0LCAmUHlJbnN0YW5jZV9UeXBlKSkNCiAgICAgICAgICAgICAgICAgZ290 > byBlcnI7DQogICAgICAgICAgICAgICBpbnN0LT5pbl9jbGFzcz0oUHlDbGFzc09iamVjdCop > Y2xzOw0KICAgICAgICAgICAgICAgUHlfSU5DUkVGKGNscyk7DQpAQCAtMjg5NCw3ICsyODk0 > LDkgQEANCiAgICAgICAgICAgICAgICAgUHlfREVDUkVGKGluc3QpOw0KICAgICAgICAgICAg > ICAgICBnb3RvIGVycjsNCiAgICAgICAgICAgICAgIH0NCi0NCisjaWZkZWYgV0lUSF9DWUNM > RV9HQw0KKyAgICAgICAgICAgICAgUHlHQ19JbnNlcnQoKFB5T2JqZWN0ICopaW5zdCk7DQor > I2VuZGlmDQogICAgICAgICAgICAgICByZXR1cm4gKFB5T2JqZWN0ICopaW5zdDsNCiAgICAg > ICAgICAgICB9DQogICAgICAgICAgIFB5X0RFQ1JFRihfX2dldGluaXRhcmdzX18pOw0KLS0t > IFB5dGhvbi1jdnMvTW9kdWxlcy9uZXdtb2R1bGUuYwlUdWUgRmViIDI5IDE0OjU1OjA5IDIw > MDANCisrKyBQeXRob24tZ2MvTW9kdWxlcy9uZXdtb2R1bGUuYwlTYXQgQXByICA4IDAyOjEz > OjI2IDIwMDANCkBAIC00OSwxMyArNDksMTYgQEANCiAJCQkgICAgICAmUHlDbGFzc19UeXBl > LCAma2xhc3MsDQogCQkJICAgICAgJlB5RGljdF9UeXBlLCAmZGljdCkpDQogCQlyZXR1cm4g > TlVMTDsNCi0JaW5zdCA9IFB5T2JqZWN0X05FVyhQeUluc3RhbmNlT2JqZWN0LCAmUHlJbnN0 > YW5jZV9UeXBlKTsNCisJaW5zdCA9IFB5T2JqZWN0X05ldyhQeUluc3RhbmNlT2JqZWN0LCAm > UHlJbnN0YW5jZV9UeXBlKTsNCiAJaWYgKGluc3QgPT0gTlVMTCkNCiAJCXJldHVybiBOVUxM > Ow0KIAlQeV9JTkNSRUYoa2xhc3MpOw0KIAlQeV9JTkNSRUYoZGljdCk7DQogCWluc3QtPmlu > X2NsYXNzID0gKFB5Q2xhc3NPYmplY3QgKilrbGFzczsNCiAJaW5zdC0+aW5fZGljdCA9IGRp > Y3Q7DQorI2lmZGVmIFdJVEhfQ1lDTEVfR0MNCisJUHlHQ19JbnNlcnQoKFB5T2JqZWN0ICop > aW5zdCk7DQorI2VuZGlmDQogCXJldHVybiAoUHlPYmplY3QgKilpbnN0Ow0KIH0NCiANCi0t > LSBQeXRob24tY3ZzL01vZHVsZXMvZ2Ntb2R1bGUuYw0KKysrIFB5dGhvbi1nYy9Nb2R1bGVz > L2djbW9kdWxlLmMJU2F0IEFwciAgOCAwMzoyNTo1NyAyMDAwDQpAQCAtMCwwICsxLDY3NyBA > QA0KKy8qDQorIA0KKyAgUmVmZXJlbmNlIEN5Y2xlIEdhcmJhZ2UgQ29sbGVjdGlvbg0KKyAg > PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQ0KKw0KKyAgTmVpbCBTY2hlbWVu > YXVlciA8bmFzY2hlbWVAZW5tZS51Y2FsZ2FyeS5jYT4NCisNCisgIEJhc2VkIG9uIGEgcG9z > dCBvbiB0aGUgcHl0aG9uLWRldiBsaXN0LiAgSWRlYXMgZnJvbSBHdWlkbyB2YW4gUm9zc3Vt > LA0KKyAgRXJpYyBUaWVkZW1hbm4sIGFuZCB2YXJpb3VzIG90aGVycy4NCisNCisgIGh0dHA6 > Ly93d3cuZW5tZS5jYWxnYXJ5LmNhL35uYXNjaGVtZS9weXRob24vZ2MuaHRtbA0KKyAgaHR0 > cDovL3d3dy5weXRob24ub3JnL3BpcGVybWFpbC9weXRob24tZGV2LzIwMDAtTWFyY2gvMDAz > ODY5Lmh0bWwNCisgIGh0dHA6Ly93d3cucHl0aG9uLm9yZy9waXBlcm1haWwvcHl0aG9uLWRl > di8yMDAwLU1hcmNoLzAwNDAxMC5odG1sDQorICBodHRwOi8vd3d3LnB5dGhvbi5vcmcvcGlw > ZXJtYWlsL3B5dGhvbi1kZXYvMjAwMC1NYXJjaC8wMDQwMjIuaHRtbA0KKw0KKyAgRm9yIGEg > aGlnaGxldmVsIHZpZXcgb2YgdGhlIGNvbGxlY3Rpb24gcHJvY2VzcywgcmVhZCB0aGUgY29s > bGVjdA0KKyAgZnVuY3Rpb24uDQorDQorICBUT0RPOg0KKwl1c2UgYSBkaWZmZXJlbnQgaW50 > ZXJmYWNlIGZvciBzZXRfZGVidWcoKSAoa2V5d29yZHMpPw0KKwlpbmxpbmUgUHlHQ19JbnNl > cnQgYW5kIFB5R0NfUmVtb3ZlIGNhbGxzPw0KKwl0dW5lIHBhcmFtZXRlcnMNCisNCisqLw0K > Kw0KKyNpbmNsdWRlICJQeXRob24uaCINCisNCisjaWZuZGVmIFdJVEhfQ1lDTEVfR0MNCisj > ZXJyb3IgIllvdSBtdXN0IGRlZmluZSBXSVRIX0NZQ0xFX0dDIHRvIGluY2x1ZGUgdGhpcyBt > b2R1bGUiDQorI2VuZGlmDQorDQorLyogbWFnaWMgZ2NfcmVmcyB2YWx1ZSAqLw0KKyNkZWZp > bmUgR0NfTU9WRUQgLTENCisNCisNCisvKioqIEdsb2JhbCBHQyBzdGF0ZSAqKiovDQorDQor > LyogbGlua2VkIGxpc3RzIG9mIGNvbnRhaW5lciBvYmplY3RzICovDQorc3RhdGljIFB5R0NJ > bmZvIGdlbmVyYXRpb24wID0geyZnZW5lcmF0aW9uMCwgJmdlbmVyYXRpb24wLCAwfTsNCitz > dGF0aWMgUHlHQ0luZm8gZ2VuZXJhdGlvbjEgPSB7JmdlbmVyYXRpb24xLCAmZ2VuZXJhdGlv > bjEsIDB9Ow0KK3N0YXRpYyBQeUdDSW5mbyBnZW5lcmF0aW9uMiA9IHsmZ2VuZXJhdGlvbjIs > ICZnZW5lcmF0aW9uMiwgMH07DQorc3RhdGljIGludCBnZW5lcmF0aW9uID0gMDsgLyogY3Vy > cmVudCBnZW5lcmF0aW9uIGJlaW5nIGNvbGxlY3RlZCAqLw0KKw0KKy8qIGNvbGxlY3Rpb24g > ZnJlcXVlbmNpZXMsIFhYWCB0dW5lIHRoZXNlICovDQorc3RhdGljIGludCB0aHJlc2hvbGQw > ID0gMTAwOyAvKiBuZXQgbmV3IGNvbnRhaW5lcnMgYmVmb3JlIGNvbGxlY3Rpb24gKi8NCitz > dGF0aWMgaW50IHRocmVzaG9sZDEgPSAxMDsgIC8qIGdlbmVyYXRpb24wIGNvbGxlY3Rpb25z > IGJlZm9yZSBjb2xsZWN0aW5nIDEgKi8NCitzdGF0aWMgaW50IHRocmVzaG9sZDIgPSAxMDsg > IC8qIGdlbmVyYXRpb24xIGNvbGxlY3Rpb25zIGJlZm9yZSBjb2xsZWN0aW5nIDIgKi8NCisN > CisvKiBuZXQgbmV3IG9iamVjdHMgYWxsb2NhdGVkIHNpbmNlIGxhc3QgY29sbGVjdGlvbiAq > Lw0KK3N0YXRpYyBpbnQgYWxsb2NhdGVkID0gMDsNCisNCisvKiBzZXQgZm9yIGRlYnVnZ2lu > ZyBpbmZvcm1hdGlvbiAqLw0KKyNkZWZpbmUgREVCVUdfU1RBVFMJCSgxPDwwKSAvKiBwcmlu > dCBjb2xsZWN0aW9uIHN0YXRpc3RpY3MgKi8NCisjZGVmaW5lIERFQlVHX0NPTExFQ1RBQkxF > CSgxPDwxKSAvKiBwcmludCBjb2xsZWN0YWJsZSBvYmplY3RzICovDQorI2RlZmluZSBERUJV > R19VTkNPTExFQ1RBQkxFCSgxPDwyKSAvKiBwcmludCB1bmNvbGxlY3RhYmxlIG9iamVjdHMg > Ki8NCisjZGVmaW5lIERFQlVHX0lOU1RBTkNFUwkJKDE8PDMpIC8qIHByaW50IGluc3RhbmNl > cyAqLw0KKyNkZWZpbmUgREVCVUdfT0JKRUNUUwkJKDE8PDQpIC8qIHByaW50IG90aGVyIG9i > amVjdHMgKi8NCisjZGVmaW5lIERFQlVHX0xFQUsJCURFQlVHX0NPTExFQ1RBQkxFIHwgXA0K > KwkJCQlERUJVR19VTkNPTExFQ1RBQkxFIHwgXA0KKwkJCQlERUJVR19JTlNUQU5DRVMgfCBc > DQorCQkJCURFQlVHX09CSkVDVFMNCitzdGF0aWMgaW50IGRlYnVnID0gREVCVUdfTEVBSzsN > CisNCisvKiBsaXN0IG9mIHVuY29sbGVjdGFibGUgb2JqZWN0cyAqLw0KK3N0YXRpYyBQeU9i > amVjdCAqZ2FyYmFnZSA9IE5VTEw7DQorDQorDQorLyoqKiBsaXN0IGZ1bmN0aW9ucyAoc2hv > dWxkIHByb2JhYmx5IGJlIG1hY3Jvcywgc3R1cGlkIGNvbXBpbGVycykgKioqLw0KKw0KK3N0 > YXRpYyB2b2lkDQorTElTVF9JTklUKFB5R0NJbmZvICpsaXN0KQ0KK3sNCisJbGlzdC0+Z2Nf > cHJldiA9IGxpc3Q7DQorCWxpc3QtPmdjX25leHQgPSBsaXN0Ow0KK30NCisNCitzdGF0aWMg > dm9pZA0KK0xJU1RfQVBQRU5EKFB5R0NJbmZvICpub2RlLCBQeUdDSW5mbyAqbGlzdCkNCit7 > DQorCW5vZGUtPmdjX25leHQgPSBsaXN0Ow0KKwlub2RlLT5nY19wcmV2ID0gbGlzdC0+Z2Nf > cHJldjsNCisJbm9kZS0+Z2NfcHJldi0+Z2NfbmV4dCA9IG5vZGU7DQorCWxpc3QtPmdjX3By > ZXYgPSBub2RlOw0KK30NCisNCitzdGF0aWMgdm9pZA0KK0xJU1RfUkVNT1ZFKFB5R0NJbmZv > ICpub2RlKQ0KK3sNCisJbm9kZS0+Z2NfcHJldi0+Z2NfbmV4dCA9IG5vZGUtPmdjX25leHQ7 > DQorCW5vZGUtPmdjX25leHQtPmdjX3ByZXYgPSBub2RlLT5nY19wcmV2Ow0KK30NCisNCitz > dGF0aWMgdm9pZCANCitMSVNUX01PVkUoUHlHQ0luZm8gKmZyb20sIFB5R0NJbmZvICp0bykN > Cit7DQorCWlmIChmcm9tLT5nY19uZXh0ID09IGZyb20pIHsNCisJCS8qIGVtcHR5IGZyb20g > bGlzdCAqLw0KKwkJTElTVF9JTklUKHRvKTsNCisJfSBlbHNlIHsNCisJCXRvLT5nY19uZXh0 > ID0gZnJvbS0+Z2NfbmV4dDsNCisJCXRvLT5nY19uZXh0LT5nY19wcmV2ID0gdG87DQorCQl0 > by0+Z2NfcHJldiA9IGZyb20tPmdjX3ByZXY7DQorCQl0by0+Z2NfcHJldi0+Z2NfbmV4dCA9 > IHRvOw0KKwl9DQorCUxJU1RfSU5JVChmcm9tKTsNCit9DQorDQorLyogYXBwZW5kIGEgbGlz > dCBvbnRvIGFub3RoZXIgbGlzdCAqLw0KK3N0YXRpYyB2b2lkDQorTElTVF9MQVBQRU5EKFB5 > R0NJbmZvICpmcm9tLCBQeUdDSW5mbyAqdG8pDQorew0KKwlQeUdDSW5mbyAqdGFpbDsNCisJ > aWYgKGZyb20tPmdjX25leHQgIT0gZnJvbSkgew0KKwkJdGFpbCA9IHRvLT5nY19wcmV2Ow0K > KwkJdGFpbC0+Z2NfbmV4dCA9IGZyb20tPmdjX25leHQ7DQorCQl0YWlsLT5nY19uZXh0LT5n > Y19wcmV2ID0gdGFpbDsNCisJCXRvLT5nY19wcmV2ID0gZnJvbS0+Z2NfcHJldjsNCisJCXRv > LT5nY19wcmV2LT5nY19uZXh0ID0gdG87DQorCX0NCisJTElTVF9JTklUKGZyb20pOw0KK30N > CisNCitzdGF0aWMgbG9uZw0KK0xJU1RfU0laRShQeUdDSW5mbyAqbGlzdCkNCit7DQorCVB5 > R0NJbmZvICpnYzsNCisJbG9uZyBuID0gMDsNCisJZm9yIChnYyA9IGxpc3QtPmdjX25leHQ7 > IGdjICE9IGxpc3Q7IGdjID0gZ2MtPmdjX25leHQpIHsNCisJCW4rKzsNCisJfQ0KKwlyZXR1 > cm4gbjsNCit9DQorDQorDQorI2lmZGVmIERFQlVHDQorc3RhdGljIHZvaWQNCitsaXN0X3By > aW50KFB5R0NJbmZvICpsaXN0KSB7DQorCVB5R0NJbmZvICpvcCA9IGxpc3Q7DQorCWRvIHsN > CisJCXByaW50ZigiJXggJXggJXggJWRcbiIsIChsb25nKW9wLCAobG9uZylvcC0+Z2NfcHJl > diwgDQorCQkJCShsb25nKW9wLT5nY19uZXh0LCAobG9uZylvcC0+Z2NfcmVmcyk7DQorDQor > CQlvcCA9IG9wLT5nY19uZXh0Ow0KKwl9IHdoaWxlIChvcCAhPSBsaXN0KTsNCit9DQorI2Vu > ZGlmDQorDQorLyoqKiBlbmQgb2YgbGlzdCBzdHVmZiAqKiovDQorDQorDQorLyogU2V0IGFs > bCBnY19yZWZzID0gb2JfcmVmY250ICovDQorc3RhdGljIHZvaWQNCit1cGRhdGVfcmVmcyhQ > eUdDSW5mbyAqY29udGFpbmVycykNCit7DQorCVB5R0NJbmZvICpnYyA9IGNvbnRhaW5lcnMt > PmdjX25leHQ7DQorCWZvciAoOyBnYyAhPSBjb250YWluZXJzOyBnYz1nYy0+Z2NfbmV4dCkg > ew0KKwkJZ2MtPmdjX3JlZnMgPSBQWV9HQ09CSihnYyktPm9iX3JlZmNudDsNCisJfQ0KK30N > CisNCitzdGF0aWMgaW50DQordmlzaXRfZGVjcmVmKFB5T2JqZWN0ICpvcCwgdm9pZCAqZGF0 > YSkNCit7DQorCWlmIChvcCAmJiBQWV9JU0dDKG9wKSkgew0KKwkJUFlfR0NJTkZPX1VOU0FG > RShvcCktPmdjX3JlZnMtLTsNCisJfQ0KKwlyZXR1cm4gMTsNCit9DQorDQorLyogU3VidHJh > Y3QgaW50ZXJuYWwgcmVmZXJlbmNlcyBmcm9tIGdjX3JlZnMgKi8NCitzdGF0aWMgdm9pZA0K > K3N1YnRyYWN0X3JlZnMoUHlHQ0luZm8gKmNvbnRhaW5lcnMpDQorew0KKwlyZWN1cnNlcHJv > YyByZWN1cnNlOw0KKwlQeUdDSW5mbyAqZ2MgPSBjb250YWluZXJzLT5nY19uZXh0Ow0KKwlm > b3IgKDsgZ2MgIT0gY29udGFpbmVyczsgZ2M9Z2MtPmdjX25leHQpIHsNCisJCXJlY3Vyc2Ug > PSBQWV9HQ09CSihnYyktPm9iX3R5cGUtPnRwX3JlY3Vyc2U7DQorCQkodm9pZCkgcmVjdXJz > ZShQWV9HQ09CSihnYyksDQorCQkJICAgICAgICh2aXNpdHByb2MpdmlzaXRfZGVjcmVmLA0K > KwkJCSAgICAgICBOVUxMKTsNCisJfQ0KK30NCisNCisvKiBBcHBlbmQgb2JqZWN0cyB3aXRo > IGdjX3JlZnMgPiAwIHRvIHJvb3RzIGxpc3QgKi8NCitzdGF0aWMgdm9pZA0KK21vdmVfcm9v > dHMoUHlHQ0luZm8gKmNvbnRhaW5lcnMsIFB5R0NJbmZvICpyb290cykNCit7DQorCVB5R0NJ > bmZvICpuZXh0Ow0KKwlQeUdDSW5mbyAqZ2MgPSBjb250YWluZXJzLT5nY19uZXh0Ow0KKwl3 > aGlsZSAoZ2MgIT0gY29udGFpbmVycykgew0KKwkJbmV4dCA9IGdjLT5nY19uZXh0Ow0KKwkJ > aWYgKGdjLT5nY19yZWZzID4gMCkgew0KKwkJCUxJU1RfUkVNT1ZFKGdjKTsNCisJCQlMSVNU > X0FQUEVORChnYywgcm9vdHMpOw0KKwkJCWdjLT5nY19yZWZzID0gR0NfTU9WRUQ7DQorCQl9 > DQorCQlnYyA9IG5leHQ7DQorCX0NCit9DQorDQorc3RhdGljIGludA0KK3Zpc2l0X3JlYWNo > YWJsZShQeU9iamVjdCAqb3AsIFB5R0NJbmZvICpyb290cykNCit7DQorCVB5R0NJbmZvICpn > YyA9IFBZX0dDSU5GTyhvcCk7DQorCWlmIChnYyAmJiBnYy0+Z2NfcmVmcyAhPSBHQ19NT1ZF > RCkgew0KKwkJTElTVF9SRU1PVkUoZ2MpOw0KKwkJTElTVF9BUFBFTkQoZ2MsIHJvb3RzKTsN > CisJCWdjLT5nY19yZWZzID0gR0NfTU9WRUQ7DQorCX0NCisJcmV0dXJuIDE7DQorfQ0KKw0K > Ky8qIE1vdmUgb2JqZWN0cyByZWZlcmVuY2VkIGZyb20gcmVhY2hhYmxlIHRvIHJlYWNoYWJs > ZSBzZXQuICovDQorc3RhdGljIHZvaWQNCittb3ZlX3Jvb3RfcmVhY2hhYmxlKFB5R0NJbmZv > ICpyZWFjaGFibGUpDQorew0KKwlyZWN1cnNlcHJvYyByZWN1cnNlOw0KKwlQeUdDSW5mbyAq > Z2MgPSByZWFjaGFibGUtPmdjX25leHQ7DQorCWZvciAoOyBnYyAhPSByZWFjaGFibGU7IGdj > PWdjLT5nY19uZXh0KSB7DQorCQkvKiBjYXJlZnVsLCByZWFjaGFibGUgbGlzdCBpcyBncm93 > aW5nIGhlcmUgKi8NCisJCVB5T2JqZWN0ICpvcCA9IFBZX0dDT0JKKGdjKTsNCisJCXJlY3Vy > c2UgPSBvcC0+b2JfdHlwZS0+dHBfcmVjdXJzZTsNCisJCSh2b2lkKSByZWN1cnNlKG9wLA0K > KwkJCSAgICAgICAodmlzaXRwcm9jKXZpc2l0X3JlYWNoYWJsZSwNCisJCQkgICAgICAgKHZv > aWQgKilyZWFjaGFibGUpOw0KKwl9DQorfQ0KKw0KKy8qIG1vdmUgYWxsIG9iamVjdHMgd2l0 > aCBmaW5hbGl6ZXJzIChpbnN0YW5jZXMgd2l0aCBfX2RlbF9fKSAqLw0KK3N0YXRpYyB2b2lk > DQorbW92ZV9maW5hbGl6ZXJzKFB5R0NJbmZvICp1bnJlYWNoYWJsZSwgUHlHQ0luZm8gKmZp > bmFsaXplcnMpDQorew0KKwlQeUdDSW5mbyAqbmV4dDsNCisJUHlHQ0luZm8gKmdjID0gdW5y > ZWFjaGFibGUtPmdjX25leHQ7DQorCXN0YXRpYyBQeU9iamVjdCAqZGVsc3RyOw0KKwlpZiAo > ZGVsc3RyID09IE5VTEwpIHsNCisJCWRlbHN0ciA9IFB5U3RyaW5nX0ludGVybkZyb21TdHJp > bmcoIl9fZGVsX18iKTsNCisJfQ0KKwlmb3IgKDsgZ2MgIT0gdW5yZWFjaGFibGU7IGdjPW5l > eHQpIHsNCisJCVB5T2JqZWN0ICpvcCA9IFBZX0dDT0JKKGdjKTsNCisJCW5leHQgPSBnYy0+ > Z2NfbmV4dDsNCisJCWlmIChQeUluc3RhbmNlX0NoZWNrKG9wKSAmJiBQeU9iamVjdF9IYXNB > dHRyKG9wLCBkZWxzdHIpKSB7DQorCQkJTElTVF9SRU1PVkUoZ2MpOw0KKwkJCUxJU1RfQVBQ > RU5EKGdjLCBmaW5hbGl6ZXJzKTsNCisJCX0NCisJfQ0KK30NCisNCisNCisvKiBjYWxsZWQg > YnkgdHBfcmVjdXJzZSAqLw0KK3N0YXRpYyBpbnQNCit2aXNpdF9maW5hbGl6ZXJfcmVhY2hh > YmxlKFB5T2JqZWN0ICpvcCwgUHlHQ0luZm8gKmZpbmFsaXplcnMpDQorew0KKwlQeUdDSW5m > byAqZ2MgPSBQWV9HQ0lORk8ob3ApOw0KKwlpZiAoZ2MgJiYgZ2MtPmdjX3JlZnMgIT0gR0Nf > TU9WRUQpIHsNCisJCUxJU1RfUkVNT1ZFKGdjKTsNCisJCUxJU1RfQVBQRU5EKGdjLCBmaW5h > bGl6ZXJzKTsNCisJCWdjLT5nY19yZWZzID0gR0NfTU9WRUQ7DQorCX0NCisJcmV0dXJuIDE7 > DQorfQ0KKw0KKy8qIE1vdmUgb2JqZWN0cyByZWZlcmVuY2VkIGZyb20gcm9vdHMgdG8gcm9v > dHMgKi8NCitzdGF0aWMgdm9pZA0KK21vdmVfZmluYWxpemVyX3JlYWNoYWJsZShQeUdDSW5m > byAqZmluYWxpemVycykNCit7DQorCXJlY3Vyc2Vwcm9jIHJlY3Vyc2U7DQorCVB5R0NJbmZv > ICpnYyA9IGZpbmFsaXplcnMtPmdjX25leHQ7DQorCWZvciAoOyBnYyAhPSBmaW5hbGl6ZXJz > OyBnYz1nYy0+Z2NfbmV4dCkgew0KKwkJLyogY2FyZWZ1bCwgZmluYWxpemVycyBsaXN0IGlz > IGdyb3dpbmcgaGVyZSAqLw0KKwkJcmVjdXJzZSA9IFBZX0dDT0JKKGdjKS0+b2JfdHlwZS0+ > dHBfcmVjdXJzZTsNCisJCSh2b2lkKSByZWN1cnNlKFBZX0dDT0JKKGdjKSwgDQorCQkJICAg > ICAgICh2aXNpdHByb2MpdmlzaXRfZmluYWxpemVyX3JlYWNoYWJsZSwNCisJCQkgICAgICAg > KHZvaWQgKilmaW5hbGl6ZXJzKTsNCisJfQ0KK30NCisNCitzdGF0aWMgdm9pZA0KK2RlYnVn > X2luc3RhbmNlKFB5T2JqZWN0ICpvdXRwdXQsIGNoYXIgKm1zZywgUHlJbnN0YW5jZU9iamVj > dCAqaW5zdCkNCit7DQorCWNoYXIgYnVmWzIwMF07DQorCWNoYXIgKmNuYW1lOw0KKwkvKiBi > ZSBjYXJlZnVsIG5vdCB0byBjcmVhdGUgbmV3IGRpY3Rpb25hcmllcyAqLw0KKwlQeU9iamVj > dCAqY2xhc3NuYW1lID0gaW5zdC0+aW5fY2xhc3MtPmNsX25hbWU7DQorCWlmIChjbGFzc25h > bWUgIT0gTlVMTCAmJiBQeVN0cmluZ19DaGVjayhjbGFzc25hbWUpKQ0KKwkJY25hbWUgPSBQ > eVN0cmluZ19Bc1N0cmluZyhjbGFzc25hbWUpOw0KKwllbHNlDQorCQljbmFtZSA9ICI/IjsN > CisJc3ByaW50ZihidWYsICJnYzogJXM8JS4xMDBzIGluc3RhbmNlIGF0ICVseD5cbiIsIA0K > KwkJCW1zZywgY25hbWUsIChsb25nKWluc3QpOw0KKwlQeUZpbGVfV3JpdGVTdHJpbmcoYnVm > LCBvdXRwdXQpOw0KK30NCisNCitzdGF0aWMgdm9pZA0KK2RlYnVnX2N5Y2xlKFB5T2JqZWN0 > ICpvdXRwdXQsIGNoYXIgKm1zZywgUHlPYmplY3QgKm9wKQ0KK3sNCisJaWYgKChkZWJ1ZyAm > IERFQlVHX0lOU1RBTkNFUykgJiYgUHlJbnN0YW5jZV9DaGVjayhvcCkpIHsNCisJCWRlYnVn > X2luc3RhbmNlKG91dHB1dCwgbXNnLCAoUHlJbnN0YW5jZU9iamVjdCAqKW9wKTsNCisJfSBl > bHNlIGlmIChkZWJ1ZyAmIERFQlVHX09CSkVDVFMpIHsNCisJCWNoYXIgYnVmWzIwMF07DQor > CQlzcHJpbnRmKGJ1ZiwgImdjOiAlczxPYmplY3QgMHgleD5cbiIsIG1zZywgKGxvbmcpb3Ap > Ow0KKwkJUHlGaWxlX1dyaXRlU3RyaW5nKGJ1Ziwgb3V0cHV0KTsNCisJfQ0KK30NCisNCisv > KiBIYW5kbGUgdW5jb2xsZWN0YWJsZSBnYXJiYWdlIChjeWNsZXMgd2l0aCBmaW5hbGl6ZXJz > KS4gKi8NCitzdGF0aWMgdm9pZA0KK2hhbmRsZV9maW5hbGl6ZXJzKFB5R0NJbmZvICpmaW5h > bGl6ZXJzLCBQeUdDSW5mbyAqb2xkKQ0KK3sNCisJUHlHQ0luZm8gKmdjOw0KKwlpZiAoZ2Fy > YmFnZSA9PSBOVUxMKSB7DQorCQlnYXJiYWdlID0gUHlMaXN0X05ldygwKTsNCisJfQ0KKwlm > b3IgKGdjID0gZmluYWxpemVycy0+Z2NfbmV4dDsgZ2MgIT0gZmluYWxpemVyczsNCisJCQln > YyA9IGZpbmFsaXplcnMtPmdjX25leHQpIHsNCisJCVB5T2JqZWN0ICpvcCA9IFBZX0dDT0JK > KGdjKTsNCisJCS8qIEFkZCBhbGwgaW5zdGFuY2VzIHRvIGEgUHl0aG9uIGFjY2Vzc2libGUg > bGlzdCBvZiBnYXJiYWdlICovDQorCQlpZiAoUHlJbnN0YW5jZV9DaGVjayhvcCkpIHsNCisJ > CQlQeUxpc3RfQXBwZW5kKGdhcmJhZ2UsIG9wKTsNCisJCX0NCisJCS8qIFdlIGFzc3VtZSB0 > aGF0IGFsbCBvYmplY3RzIGluIGZpbmFsaXplcnMgYXJlIHJlYWNoYWJsZSBmcm9tDQorCQkg > KiBpbnN0YW5jZXMuICBPbmNlIHdlIGFkZCB0aGUgaW5zdGFuY2VzIHRvIHRoZSBnYXJiYWdl > IGxpc3QNCisJCSAqIGV2ZXJ5dGhpbmcgaXMgcmVhY2hhYmxlIGZyb20gUHl0aG9uIGFnYWlu > LiAqLw0KKwkJTElTVF9SRU1PVkUoZ2MpOw0KKwkJTElTVF9BUFBFTkQoZ2MsIG9sZCk7DQor > CX0NCit9DQorDQorLyogQnJlYWsgcmVmZXJlbmNlIGN5Y2xlcyBieSBjbGVhcmluZyB0aGUg > Y29udGFpbmVycyBpbnZvbHZlZC4gIFRoaXMgaXMNCisgKiB0cmlja3kgYnVzaW5lc3MgYXMg > dGhlIGxpc3RzIGNhbiBiZSBjaGFuZ2luZyBhbmQgd2UgZG9uJ3Qga25vdyB3aGljaA0KKyAq > IG9iamVjdHMgbWF5IGJlIGZyZWVkLiAgSXQgaXMgcG9zc2libGUgSSBzY3Jld2VkIHNvbWV0 > aGluZyB1cCBoZXJlLiAqLw0KK3N0YXRpYyB2b2lkDQorZGVsZXRlX2dhcmJhZ2UoUHlHQ0lu > Zm8gKnVucmVhY2hhYmxlLCBQeUdDSW5mbyAqb2xkKQ0KK3sNCisJaW5xdWlyeSBjbGVhcjsN > CisNCisJd2hpbGUgKHVucmVhY2hhYmxlLT5nY19uZXh0ICE9IHVucmVhY2hhYmxlKSB7DQor > CQlQeUdDSW5mbyAqZ2MgPSB1bnJlYWNoYWJsZS0+Z2NfbmV4dDsNCisJCVB5T2JqZWN0ICpv > cCA9IFBZX0dDT0JKKGdjKTsNCisJCWlmICgoY2xlYXIgPSBvcC0+b2JfdHlwZS0+dHBfY2xl > YXIpICE9IE5VTEwpIHsNCisJCQlQeV9JTkNSRUYob3ApOw0KKwkJCWNsZWFyKChQeU9iamVj > dCAqKW9wKTsNCisJCQlQeV9ERUNSRUYob3ApOw0KKwkJfQ0KKwkJLyogb25seSB0cnkgdG8g > Y2FsbCB0cF9jbGVhciBvbmNlIGZvciBlYWNoIG9iamVjdCAqLw0KKwkJaWYgKHVucmVhY2hh > YmxlLT5nY19uZXh0ID09IGdjKSB7DQorCQkJLyogc3RpbGwgYWxpdmUsIG1vdmUgaXQsIGl0 > IG1heSBkaWUgbGF0ZXIgKi8NCisJCQlMSVNUX1JFTU9WRShnYyk7DQorCQkJTElTVF9BUFBF > TkQoZ2MsIG9sZCk7DQorCQl9DQorCX0NCit9DQorDQorLyogVGhpcyBpcyB0aGUgbWFpbiBm > dW5jdGlvbi4gIFJlYWQgdGhpcyB0byB1bmRlcnN0YW5kIGhvdyB0aGUNCisgKiBjb2xsZWN0 > aW9uIHByb2Nlc3Mgd29ya3MuICovDQorc3RhdGljIGxvbmcNCitjb2xsZWN0KFB5R0NJbmZv > ICp5b3VuZywgUHlHQ0luZm8gKm9sZCkNCit7DQorCWxvbmcgbiA9IDA7DQorCWxvbmcgbSA9 > IDA7DQorCVB5R0NJbmZvIHJlYWNoYWJsZTsNCisJUHlHQ0luZm8gdW5yZWFjaGFibGU7DQor > CVB5R0NJbmZvIGZpbmFsaXplcnM7DQorCVB5R0NJbmZvICpnYzsNCisJUHlPYmplY3QgKm91 > dHB1dCA9IE5VTEw7DQorDQorCWlmIChkZWJ1Zykgew0KKwkJb3V0cHV0ID0gUHlTeXNfR2V0 > T2JqZWN0KCJzdGRlcnIiKTsNCisJfQ0KKwlpZiAoZGVidWcgJiBERUJVR19TVEFUUykgew0K > KwkJY2hhciBidWZbMTAwXTsNCisJCXNwcmludGYoYnVmLCAiZ2M6IGNvbGxlY3RpbmcgZ2Vu > ZXJhdGlvbiAlZC4uLlxuIiwgZ2VuZXJhdGlvbik7DQorCQlQeUZpbGVfV3JpdGVTdHJpbmco > YnVmLG91dHB1dCk7DQorCQlzcHJpbnRmKGJ1ZiwgImdjOiBvYmplY3RzIGluIGVhY2ggZ2Vu > ZXJhdGlvbjogJWQgJWQgJWRcbiIsDQorCQkJTElTVF9TSVpFKCZnZW5lcmF0aW9uMCksDQor > CQkJTElTVF9TSVpFKCZnZW5lcmF0aW9uMSksDQorCQkJTElTVF9TSVpFKCZnZW5lcmF0aW9u > MikpOw0KKwkJUHlGaWxlX1dyaXRlU3RyaW5nKGJ1ZixvdXRwdXQpOw0KKwl9DQorDQorCS8q > IFVzaW5nIG9iX3JlZmNudCBhbmQgZ2NfcmVmcywgY2FsY3VsYXRlIHdoaWNoIG9iamVjdHMg > aW4gdGhlDQorCSAqIGNvbnRhaW5lciBzZXQgYXJlIHJlYWNoYWJsZSBmcm9tIG91dHNpZGUg > dGhlIHNldCAoaWUuIGhhdmUgYQ0KKwkgKiByZWZjb3VudCBncmVhdGVyIHRoYW4gMCB3aGVu > IGFsbCB0aGUgcmVmZXJlbmNlcyB3aXRoaW4gdGhlDQorCSAqIHNldCBhcmUgdGFrZW4gaW50 > byBhY2NvdW50ICovDQorCXVwZGF0ZV9yZWZzKHlvdW5nKTsNCisJc3VidHJhY3RfcmVmcyh5 > b3VuZyk7DQorDQorCS8qIE1vdmUgZXZlcnl0aGluZyByZWFjaGFibGUgZnJvbSBvdXRzaWRl > IHRoZSBzZXQgaW50byB0aGUNCisJICogcmVhY2hhYmxlIHNldCAoaWUuIGdjX3JlZnMgPiAw > KS4gIE5leHQsIG1vdmUgZXZlcnl0aGluZw0KKwkgKiByZWFjaGFibGUgZnJvbSBvYmplY3Rz > IGluIHRoZSByZWFjaGFibGUgc2V0LiAqLw0KKwlMSVNUX0lOSVQoJnJlYWNoYWJsZSk7DQor > CW1vdmVfcm9vdHMoeW91bmcsICZyZWFjaGFibGUpOw0KKwltb3ZlX3Jvb3RfcmVhY2hhYmxl > KCZyZWFjaGFibGUpOw0KKw0KKwkvKiBtb3ZlIHVucmVhY2hhYmxlIG9iamVjdHMgdG8gYSB0 > ZW1wb3JhcnkgbGlzdCwgbmV3IG9iamVjdHMgY2FuIGJlDQorCSAqIGFsbG9jYXRlZCBhZnRl > ciB0aGlzIHBvaW50ICovDQorCUxJU1RfSU5JVCgmdW5yZWFjaGFibGUpOw0KKwlMSVNUX01P > VkUoeW91bmcsICZ1bnJlYWNoYWJsZSk7DQorCS8vTElTVF9JTklUKHlvdW5nKTsNCisNCisJ > LyogbW92ZSByZWFjaGFibGUgb2JqZWN0cyB0byBuZXh0IGdlbmVyYXRpb24gKi8NCisJTElT > VF9MQVBQRU5EKCZyZWFjaGFibGUsIG9sZCk7DQorDQorCS8qIE1vdmUgb2JqZWN0cyByZWFj > aGFibGUgZnJvbSBmaW5hbGl6ZXJzLCB3ZSBjYW4ndCBzYWZlbHkgZGVsZXRlDQorCSAqIHRo > ZW0uICBQeXRob24gcHJvZ3JhbW1lcnMgc2hvdWxkIHRha2UgY2FyZSBub3QgdG8gY3JlYXRl > IHN1Y2gNCisJICogdGhpbmdzLiAgRm9yIFB5dGhvbiBmaW5hbGl6ZXJzIG1lYW5zIGluc3Rh > bmNlIG9iamVjdHMgd2l0aA0KKwkgKiBfX2RlbF9fIG1ldGhvZHMuICovDQorCUxJU1RfSU5J > VCgmZmluYWxpemVycyk7DQorCW1vdmVfZmluYWxpemVycygmdW5yZWFjaGFibGUsICZmaW5h > bGl6ZXJzKTsNCisJbW92ZV9maW5hbGl6ZXJfcmVhY2hhYmxlKCZmaW5hbGl6ZXJzKTsNCisN > CisJLyogQ29sbGVjdCBzdGF0aXN0aWNzIG9uIGNvbGxlY3RhYmxlIG9iamVjdHMgZm91bmQg > YW5kIHByaW50DQorCSAqIGRlYnVnZ2luZyBpbmZvcm1hdGlvbi4gKi8NCisJZm9yIChnYyA9 > IHVucmVhY2hhYmxlLmdjX25leHQ7IGdjICE9ICZ1bnJlYWNoYWJsZTsNCisJCQlnYyA9IGdj > LT5nY19uZXh0KSB7DQorCQltKys7DQorCQlpZiAob3V0cHV0ICE9IE5VTEwgJiYgKGRlYnVn > ICYgREVCVUdfQ09MTEVDVEFCTEUpKSB7DQorCQkJZGVidWdfY3ljbGUob3V0cHV0LCAiY29s > bGVjdGFibGUgIiwgUFlfR0NPQkooZ2MpKTsNCisJCX0NCisJfQ0KKwkvKiBjYWxsIHRwX2Ns > ZWFyIG9uIG9iamVjdHMgaW4gdGhlIGNvbGxlY3RhYmxlIHNldC4gIFRoaXMgd2lsbCBjYXVz > ZQ0KKwkgKiB0aGUgcmVmZXJlbmNlIGN5Y2xlcyB0byBiZSBicm9rZW4uIEl0IG1heSBhbHNv > IGNhdXNlIHNvbWUgb2JqZWN0cyBpbg0KKwkgKiBmaW5hbGl6ZXJzIHRvIGJlIGZyZWVkICov > DQorCWRlbGV0ZV9nYXJiYWdlKCZ1bnJlYWNoYWJsZSwgb2xkKTsNCisNCisJLyogQ29sbGVj > dCBzdGF0aXN0aWNzIG9uIHVuY29sbGVjdGFibGUgb2JqZWN0cyBmb3VuZCBhbmQgcHJpbnQN > CisJICogZGVidWdnaW5nIGluZm9ybWF0aW9uLiAqLw0KKwlmb3IgKGdjID0gZmluYWxpemVy > cy5nY19uZXh0OyBnYyAhPSAmZmluYWxpemVyczsNCisJCQlnYyA9IGdjLT5nY19uZXh0KSB7 > DQorCQluKys7DQorCQlpZiAob3V0cHV0ICE9IE5VTEwgJiYgKGRlYnVnICYgREVCVUdfVU5D > T0xMRUNUQUJMRSkpIHsNCisJCQlkZWJ1Z19jeWNsZShvdXRwdXQsICJ1bmNvbGxlY3RhYmxl > ICIsIFBZX0dDT0JKKGdjKSk7DQorCQl9DQorCX0NCisJaWYgKG91dHB1dCAhPSBOVUxMICYm > IChkZWJ1ZyAmIERFQlVHX1NUQVRTKSkgew0KKwkJaWYgKG0gPT0gMCAmJiBuID09IDApIHsN > CisJCQlQeUZpbGVfV3JpdGVTdHJpbmcoImdjOiBkb25lLlxuIiwgb3V0cHV0KTsNCisJCX0g > ZWxzZSB7DQorCQkJY2hhciBidWZbMjAwXTsNCisJCQlzcHJpbnRmKGJ1ZiwNCisJCQkJImdj > OiBkb25lLCAlZCB1bnJlYWNoYWJsZSwgJWQgdW5jb2xsZWN0YWJsZS5cbiIsDQorCQkJCW4r > bSwgbik7DQorCQkJUHlGaWxlX1dyaXRlU3RyaW5nKGJ1Ziwgb3V0cHV0KTsNCisJCX0NCisJ > fQ0KKw0KKwkvKiBBcHBlbmQgaW5zdGFuY2VzIGluIHRoZSB1bmNvbGxlY3RhYmxlIHNldCB0 > byBhIFB5dGhvbg0KKwkgKiByZWFjaGFibGUgbGlzdCBvZiBnYXJiYWdlLiAgVGhlIHByb2dy > YW1tZXIgaGFzIHRvIGRlYWwgd2l0aA0KKwkgKiB0aGlzIGlmIHRoZXkgaW5zaXN0IG9uIGNy > ZWF0aW5nIHRoaXMgdHlwZSBvZiBzdHJ1Y3R1cmUuICovDQorCWhhbmRsZV9maW5hbGl6ZXJz > KCZmaW5hbGl6ZXJzLCBvbGQpOw0KKw0KKwlhbGxvY2F0ZWQgPSAwOw0KKwlQeUVycl9DbGVh > cigpOyAvKiBpbiBjYXNlIHdyaXRpbmcgdG8gc3lzLnN0ZGVyciBmYWlsZWQgKi8NCisJcmV0 > dXJuIG4rbTsNCit9DQorDQorc3RhdGljIGxvbmcNCitjb2xsZWN0X2dlbmVyYXRpb25zKHZv > aWQpDQorew0KKwlzdGF0aWMgbG9uZyBjb2xsZWN0aW9uczAgPSAwOw0KKwlzdGF0aWMgbG9u > ZyBjb2xsZWN0aW9uczEgPSAwOw0KKwlsb25nIG47DQorDQorDQorCWlmIChjb2xsZWN0aW9u > czEgPiB0aHJlc2hvbGQyKSB7DQorCQlnZW5lcmF0aW9uID0gMjsNCisJCUxJU1RfTEFQUEVO > RCgmZ2VuZXJhdGlvbjAsICZnZW5lcmF0aW9uMik7DQorCQlMSVNUX0xBUFBFTkQoJmdlbmVy > YXRpb24xLCAmZ2VuZXJhdGlvbjIpOw0KKwkJaWYgKGdlbmVyYXRpb24yLmdjX25leHQgIT0g > JmdlbmVyYXRpb24yKSB7DQorCQkJbiA9IGNvbGxlY3QoJmdlbmVyYXRpb24yLCAmZ2VuZXJh > dGlvbjIpOw0KKwkJfQ0KKwkJY29sbGVjdGlvbnMxID0gMDsNCisJfSBlbHNlIGlmIChjb2xs > ZWN0aW9uczAgPiB0aHJlc2hvbGQxKSB7DQorCQlnZW5lcmF0aW9uID0gMTsNCisJCWNvbGxl > Y3Rpb25zMSsrOw0KKwkJTElTVF9MQVBQRU5EKCZnZW5lcmF0aW9uMCwgJmdlbmVyYXRpb24x > KTsNCisJCWlmIChnZW5lcmF0aW9uMS5nY19uZXh0ICE9ICZnZW5lcmF0aW9uMSkgew0KKwkJ > CW4gPSBjb2xsZWN0KCZnZW5lcmF0aW9uMSwgJmdlbmVyYXRpb24yKTsNCisJCX0NCisJCWNv > bGxlY3Rpb25zMCA9IDA7DQorCX0gZWxzZSB7DQorCQlnZW5lcmF0aW9uID0gMDsNCisJCWNv > bGxlY3Rpb25zMCsrOw0KKwkJaWYgKGdlbmVyYXRpb24wLmdjX25leHQgIT0gJmdlbmVyYXRp > b24wKSB7DQorCQkJbiA9IGNvbGxlY3QoJmdlbmVyYXRpb24wLCAmZ2VuZXJhdGlvbjEpOw0K > KwkJfQ0KKwl9DQorCXJldHVybiBuOw0KK30NCisNCit2b2lkDQorUHlHQ19JbnNlcnQoUHlP > YmplY3QgKm9wKQ0KK3sNCisJLyogY29sbGVjdGlvbiBsb2NrIHNpbmNlIGNvbGxlY3Rpbmcg > bWF5IGNhdXNlIGFsbG9jYXRpb25zICovDQorCXN0YXRpYyBpbnQgY29sbGVjdGluZyA9IDA7 > DQorDQorI2lmZGVmIERFQlVHDQorCS8qZnByaW50ZihzdGRlcnIsICJJbnNlcnQgMHgleFxu > Iiwgb3ApOyovDQorI2VuZGlmDQorCWlmICh0aHJlc2hvbGQwICYmIGFsbG9jYXRlZCA+IHRo > cmVzaG9sZDAgJiYgIWNvbGxlY3RpbmcpIHsNCisJCWNvbGxlY3RpbmcrKzsNCisJCWNvbGxl > Y3RfZ2VuZXJhdGlvbnMoKTsNCisJCWNvbGxlY3RpbmctLTsNCisJfQ0KKwlhbGxvY2F0ZWQr > KzsNCisJTElTVF9BUFBFTkQoUFlfR0NJTkZPKG9wKSwgJmdlbmVyYXRpb24wKTsNCit9DQor > DQordm9pZA0KK1B5R0NfUmVtb3ZlKFB5T2JqZWN0ICpvcCkNCit7DQorI2lmZGVmIERFQlVH > DQorCS8qZnByaW50ZihzdGRlcnIsICJSZW1vdmUgMHgleFxuIiwgb3ApOyovDQorI2VuZGlm > DQorCWlmIChhbGxvY2F0ZWQgPiAwKSB7DQorCQlhbGxvY2F0ZWQtLTsNCisJfQ0KKwlMSVNU > X1JFTU9WRShQWV9HQ0lORk8ob3ApKTsNCit9DQorDQorDQorc3RhdGljIGNoYXIgY29sbGVj > dF9fZG9jX19bXSA9DQorImNvbGxlY3QoKSAtPiBuXG4iDQorIlxuIg0KKyJSdW4gYSBmdWxs > IGNvbGxlY3Rpb24uICBUaGUgbnVtYmVyIG9mIHVucmVhY2hhYmxlIG9iamVjdHMgaXMgcmV0 > dXJuZWQuXG4iDQorOw0KKw0KK3N0YXRpYyBQeU9iamVjdCAqDQorUHlfY29sbGVjdChzZWxm > LCBhcmdzKQ0KKwlQeU9iamVjdCAqc2VsZjsNCisJUHlPYmplY3QgKmFyZ3M7DQorew0KKwls > b25nIG47DQorDQorCWlmKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICIiKSkJLyogY2hlY2sg > bm8gYXJncyAqLw0KKwkJcmV0dXJuIE5VTEw7DQorDQorCWdlbmVyYXRpb24gPSAyOw0KKwlM > SVNUX0xBUFBFTkQoJmdlbmVyYXRpb24wLCAmZ2VuZXJhdGlvbjIpOw0KKwlMSVNUX0xBUFBF > TkQoJmdlbmVyYXRpb24xLCAmZ2VuZXJhdGlvbjIpOw0KKwluID0gY29sbGVjdCgmZ2VuZXJh > dGlvbjIsICZnZW5lcmF0aW9uMik7DQorDQorCXJldHVybiBQeV9CdWlsZFZhbHVlKCJpIiwg > bik7DQorfQ0KKw0KK3N0YXRpYyBjaGFyIHNldF9kZWJ1Z19fZG9jX19bXSA9IA0KKyJzZXRf > ZGVidWcoZmxhZ3MpIC0+IE5vbmVcbiINCisiXG4iDQorIlNldCB0aGUgZ2FyYmFnZSBjb2xs > ZWN0aW9uIGRlYnVnZ2luZyBmbGFncy4gRGVidWdnaW5nIGluZm9ybWF0aW9uIGlzXG4iDQor > IndyaXR0ZW4gdG8gc3lzLnN0ZGVyci5cbiINCisiXG4iDQorImZsYWdzIGlzIGFuIGludGVn > ZXIgYW5kIGNhbiBoYXZlIHRoZSBmb2xsb3dpbmcgYml0cyB0dXJuZWQgb246XG4iDQorIlxu > Ig0KKyIgIERFQlVHX1NUQVRTIC0gUHJpbnQgc3RhdGlzdGljcyBkdXJpbmcgY29sbGVjdGlv > bi5cbiINCisiICBERUJVR19DT0xMRUNUQUJMRSAtIFByaW50IGNvbGxlY3RhYmxlIG9iamVj > dHMgZm91bmQuXG4iDQorIiAgREVCVUdfVU5DT0xMRUNUQUJMRSAtIFByaW50IHVucmVhY2hh > YmxlIGJ1dCB1bmNvbGxlY3RhYmxlIG9iamVjdHMgZm91bmQuXG4iDQorIiAgREVCVUdfSU5T > VEFOQ0VTIC0gUHJpbnQgaW5zdGFuY2Ugb2JqZWN0cy5cbiINCisiICBERUJVR19PQkpFQ1RT > IC0gUHJpbnQgb2JqZWN0cyBvdGhlciB0aGFuIGluc3RhbmNlcy5cbiINCisiICBERUJVR19M > RUFLIC0gRGVidWcgbGVha2luZyBwcm9ncmFtcyAoZXZlcnl0aGluZyBidXQgU1RBVFMpLlxu > Ig0KKzsNCisNCitzdGF0aWMgUHlPYmplY3QgKg0KK1B5X3NldF9kZWJ1ZyhzZWxmLCBhcmdz > KQ0KKwlQeU9iamVjdCAqc2VsZjsNCisJUHlPYmplY3QgKmFyZ3M7DQorew0KKwlpZiAoIVB5 > QXJnX1BhcnNlVHVwbGUoYXJncywgImwiLCAmZGVidWcpKQ0KKwkJcmV0dXJuIE5VTEw7DQor > DQorCVB5X0lOQ1JFRihQeV9Ob25lKTsNCisJcmV0dXJuIFB5X05vbmU7DQorfQ0KKw0KK3N0 > YXRpYyBjaGFyIGdldF9kZWJ1Z19fZG9jX19bXSA9IA0KKyJnZXRfZGVidWcoKSAtPiBmbGFn > c1xuIg0KKyJcbiINCisiR2V0IHRoZSBnYXJiYWdlIGNvbGxlY3Rpb24gZGVidWdnaW5nIGZs > YWdzLlxuIg0KKzsNCisNCitzdGF0aWMgUHlPYmplY3QgKg0KK1B5X2dldF9kZWJ1ZyhzZWxm > LCBhcmdzKQ0KKwlQeU9iamVjdCAqc2VsZjsNCisJUHlPYmplY3QgKmFyZ3M7DQorew0KKwlp > ZighUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiIikpCS8qIG5vIGFyZ3MgKi8NCisJCXJldHVy > biBOVUxMOw0KKw0KKwlyZXR1cm4gUHlfQnVpbGRWYWx1ZSgiaSIsIGRlYnVnKTsNCit9DQor > DQorc3RhdGljIGNoYXIgc2V0X3RocmVzaF9fZG9jX19bXSA9DQorInNldF90aHJlc2hvbGQo > dGhyZXNob2xkMCwgW3RocmVob2xkMSwgdGhyZXNob2xkMl0pIC0+IE5vbmVcbiINCisiXG4i > DQorIlNldHMgdGhlIGNvbGxlY3Rpb24gdGhyZXNob2xkcy4gIFNldHRpbmcgdGhyZXNob2xk > MCB0byB6ZXJvIGRpc2FibGVzXG4iDQorImNvbGxlY3Rpb24uXG4iDQorOw0KKw0KK3N0YXRp > YyBQeU9iamVjdCAqDQorUHlfc2V0X3RocmVzaChzZWxmLCBhcmdzKQ0KKwlQeU9iamVjdCAq > c2VsZjsNCisJUHlPYmplY3QgKmFyZ3M7DQorew0KKwlpZiAoIVB5QXJnX1BhcnNlVHVwbGUo > YXJncywgIml8aWkiLCAmdGhyZXNob2xkMCwgDQorCQkJCSZ0aHJlc2hvbGQxLCAmdGhyZXNo > b2xkMikpDQorCQlyZXR1cm4gTlVMTDsNCisNCisJUHlfSU5DUkVGKFB5X05vbmUpOw0KKwly > ZXR1cm4gUHlfTm9uZTsNCit9DQorDQorc3RhdGljIGNoYXIgZ2V0X3RocmVzaF9fZG9jX19b > XSA9DQorImdldF90cmVzaG9sZCgpIC0+ICh0aHJlc2hvbGQwLCB0aHJlc2hvbGQxLCB0aHJl > c2hvbGQyKVxuIg0KKyJcbiINCisiUmV0dXJuIHRoZSBjdXJyZW50IGNvbGxlY3Rpb24gdGhy > ZXNob2xkc1xuIg0KKzsNCisNCitzdGF0aWMgUHlPYmplY3QgKg0KK1B5X2dldF90aHJlc2go > c2VsZiwgYXJncykNCisJUHlPYmplY3QgKnNlbGY7DQorCVB5T2JqZWN0ICphcmdzOw0KK3sN > CisJaWYoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIiIpKQkvKiBubyBhcmdzICovDQorCQly > ZXR1cm4gTlVMTDsNCisNCisJcmV0dXJuIFB5X0J1aWxkVmFsdWUoIihpaWkpIiwgdGhyZXNo > b2xkMCwgdGhyZXNob2xkMSwgdGhyZXNob2xkMik7DQorfQ0KKw0KKw0KK3N0YXRpYyBjaGFy > IGdjX19kb2NfXyBbXSA9DQorIlRoaXMgbW9kdWxlIHByb3ZpZGVzIGFjY2VzcyB0byB0aGUg > Z2FyYmFnZSBjb2xsZWN0b3IgZm9yIHJlZmVyZW5jZSBjeWNsZXMuXG4iDQorIlxuIg0KKyJj > b2xsZWN0KCkgLS0gRG8gYSBmdWxsIGNvbGxlY3Rpb24gcmlnaHQgbm93LlxuIg0KKyJzZXRf > ZGVidWcoKSAtLSBTZXQgZGVidWdnaW5nIGZsYWdzLlxuIg0KKyJnZXRfZGVidWcoKSAtLSBH > ZXQgZGVidWdnaW5nIGZsYWdzLlxuIg0KKyJzZXRfdGhyZXNob2xkKCkgLS0gU2V0IHRoZSBj > b2xsZWN0aW9uIHRocmVzaG9sZHMuXG4iDQorImdldF90aHJlc2hvbGQoKSAtLSBSZXR1cm4g > dGhlIGN1cnJlbnQgdGhlIGNvbGxlY3Rpb24gdGhyZXNob2xkcy5cbiINCis7DQorDQorc3Rh > dGljIFB5TWV0aG9kRGVmIEdjTWV0aG9kc1tdID0gew0KKwl7InNldF9kZWJ1ZyIsCQlQeV9z > ZXRfZGVidWcsICBNRVRIX1ZBUkFSR1MsIHNldF9kZWJ1Z19fZG9jX199LA0KKwl7ImdldF9k > ZWJ1ZyIsCQlQeV9nZXRfZGVidWcsICBNRVRIX1ZBUkFSR1MsIGdldF9kZWJ1Z19fZG9jX199 > LA0KKwl7InNldF90aHJlc2hvbGQiLAlQeV9zZXRfdGhyZXNoLCBNRVRIX1ZBUkFSR1MsIHNl > dF90aHJlc2hfX2RvY19ffSwNCisJeyJnZXRfdGhyZXNob2xkIiwJUHlfZ2V0X3RocmVzaCwg > TUVUSF9WQVJBUkdTLCBnZXRfdGhyZXNoX19kb2NfX30sDQorCXsiY29sbGVjdCIsCQlQeV9j > b2xsZWN0LCAgICBNRVRIX1ZBUkFSR1MsIGNvbGxlY3RfX2RvY19ffSwNCisJe05VTEwsCU5V > TEx9CQkvKiBTZW50aW5lbCAqLw0KK307DQorDQordm9pZA0KK2luaXRnYyh2b2lkKQ0KK3sN > CisJUHlPYmplY3QgKm07DQorCVB5T2JqZWN0ICpkOw0KKw0KKwltID0gUHlfSW5pdE1vZHVs > ZTQoImdjIiwNCisJCQkgICAgICBHY01ldGhvZHMsDQorCQkJICAgICAgZ2NfX2RvY19fLA0K > KwkJCSAgICAgIE5VTEwsDQorCQkJICAgICAgUFlUSE9OX0FQSV9WRVJTSU9OKTsNCisJZCA9 > IFB5TW9kdWxlX0dldERpY3QobSk7DQorCWlmIChnYXJiYWdlID09IE5VTEwpIHsNCisJCWdh > cmJhZ2UgPSBQeUxpc3RfTmV3KDApOw0KKwl9DQorCVB5RGljdF9TZXRJdGVtU3RyaW5nKGQs > ICJnYXJiYWdlIiwgZ2FyYmFnZSk7DQorCVB5RGljdF9TZXRJdGVtU3RyaW5nKGQsICJERUJV > R19TVEFUUyIsDQorCQkJUHlJbnRfRnJvbUxvbmcoREVCVUdfU1RBVFMpKTsNCisJUHlEaWN0 > X1NldEl0ZW1TdHJpbmcoZCwgIkRFQlVHX0NPTExFQ1RBQkxFIiwNCisJCQlQeUludF9Gcm9t > TG9uZyhERUJVR19DT0xMRUNUQUJMRSkpOw0KKwlQeURpY3RfU2V0SXRlbVN0cmluZyhkLCAi > REVCVUdfVU5DT0xMRUNUQUJMRSIsDQorCQkJUHlJbnRfRnJvbUxvbmcoREVCVUdfVU5DT0xM > RUNUQUJMRSkpOw0KKwlQeURpY3RfU2V0SXRlbVN0cmluZyhkLCAiREVCVUdfSU5TVEFOQ0VT > IiwNCisJCQlQeUludF9Gcm9tTG9uZyhERUJVR19JTlNUQU5DRVMpKTsNCisJUHlEaWN0X1Nl > dEl0ZW1TdHJpbmcoZCwgIkRFQlVHX09CSkVDVFMiLA0KKwkJCVB5SW50X0Zyb21Mb25nKERF > QlVHX09CSkVDVFMpKTsNCisJUHlEaWN0X1NldEl0ZW1TdHJpbmcoZCwgIkRFQlVHX0xFQUsi > LA0KKwkJCVB5SW50X0Zyb21Mb25nKERFQlVHX0xFQUspKTsNCit9DQorDQotLS0gUHl0aG9u > LWN2cy9PYmplY3RzL2NsYXNzb2JqZWN0LmMJVHVlIEZlYiAyOSAxNDo1NToxNSAyMDAwDQor > KysgUHl0aG9uLWdjL09iamVjdHMvY2xhc3NvYmplY3QuYwlNb24gQXByIDI0IDIxOjE5OjE4 > IDIwMDANCkBAIC0xMTAsNyArMTEwLDcgQEANCiAJCX0NCiAJCVB5X0lOQ1JFRihiYXNlcyk7 > DQogCX0NCi0Jb3AgPSBQeU9iamVjdF9ORVcoUHlDbGFzc09iamVjdCwgJlB5Q2xhc3NfVHlw > ZSk7DQorCW9wID0gUHlPYmplY3RfTmV3KFB5Q2xhc3NPYmplY3QsICZQeUNsYXNzX1R5cGUp > Ow0KIAlpZiAob3AgPT0gTlVMTCkgew0KIAkJUHlfREVDUkVGKGJhc2VzKTsNCiAJCXJldHVy > biBOVUxMOw0KQEAgLTEzMSw2ICsxMzEsOSBAQA0KIAlQeV9YSU5DUkVGKG9wLT5jbF9nZXRh > dHRyKTsNCiAJUHlfWElOQ1JFRihvcC0+Y2xfc2V0YXR0cik7DQogCVB5X1hJTkNSRUYob3At > PmNsX2RlbGF0dHIpOw0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDDQorCVB5R0NfSW5zZXJ0KChQ > eU9iamVjdCAqKW9wKTsNCisjZW5kaWYNCiAJcmV0dXJuIChQeU9iamVjdCAqKSBvcDsNCiB9 > DQogDQpAQCAtMTQwLDEzICsxNDMsMTYgQEANCiBjbGFzc19kZWFsbG9jKG9wKQ0KIAlQeUNs > YXNzT2JqZWN0ICpvcDsNCiB7DQorI2lmZGVmIFdJVEhfQ1lDTEVfR0MNCisJUHlHQ19SZW1v > dmUoKFB5T2JqZWN0ICopb3ApOw0KKyNlbmRpZg0KIAlQeV9ERUNSRUYob3AtPmNsX2Jhc2Vz > KTsNCiAJUHlfREVDUkVGKG9wLT5jbF9kaWN0KTsNCiAJUHlfWERFQ1JFRihvcC0+Y2xfbmFt > ZSk7DQogCVB5X1hERUNSRUYob3AtPmNsX2dldGF0dHIpOw0KIAlQeV9YREVDUkVGKG9wLT5j > bF9zZXRhdHRyKTsNCiAJUHlfWERFQ1JFRihvcC0+Y2xfZGVsYXR0cik7DQotCWZyZWUoKEFO > WSAqKW9wKTsNCisJUHlPYmplY3RfRGVsKChQeU9iamVjdCAqKW9wKTsNCiB9DQogDQogc3Rh > dGljIFB5T2JqZWN0ICoNCkBAIC0zODYsNiArMzkyLDIxIEBADQogCXJldHVybiByZXM7DQog > fQ0KIA0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDDQorc3RhdGljIGludA0KK2NsYXNzX3JlY3Vy > c2UoUHlDbGFzc09iamVjdCAqbywgdmlzaXRwcm9jIHZpc2l0LCB2b2lkICpjbG9zdXJlKQ0K > K3sNCisJaWYgKG8tPmNsX2Jhc2VzKSB2aXNpdChvLT5jbF9iYXNlcywgY2xvc3VyZSk7DQor > CWlmIChvLT5jbF9kaWN0KSB2aXNpdChvLT5jbF9kaWN0LCBjbG9zdXJlKTsNCisJaWYgKG8t > PmNsX25hbWUpIHZpc2l0KG8tPmNsX25hbWUsIGNsb3N1cmUpOw0KKwlpZiAoby0+Y2xfZ2V0 > YXR0cikgdmlzaXQoby0+Y2xfZ2V0YXR0ciwgY2xvc3VyZSk7DQorCWlmIChvLT5jbF9zZXRh > dHRyKSB2aXNpdChvLT5jbF9zZXRhdHRyLCBjbG9zdXJlKTsNCisJaWYgKG8tPmNsX2RlbGF0 > dHIpIHZpc2l0KG8tPmNsX2RlbGF0dHIsIGNsb3N1cmUpOw0KKwlyZXR1cm4gMTsNCit9DQor > I2VuZGlmIC8qIFdJVEhfQ1lDTEVfR0MgKi8NCisNCisNCiBQeVR5cGVPYmplY3QgUHlDbGFz > c19UeXBlID0gew0KIAlQeU9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlKQ0KIAkwLA0K > QEAgLTQwNiw2ICs0MjcsMTIgQEANCiAJKHJlcHJmdW5jKWNsYXNzX3N0ciwgLyp0cF9zdHIq > Lw0KIAkoZ2V0YXR0cm9mdW5jKWNsYXNzX2dldGF0dHIsIC8qdHBfZ2V0YXR0cm8qLw0KIAko > c2V0YXR0cm9mdW5jKWNsYXNzX3NldGF0dHIsIC8qdHBfc2V0YXR0cm8qLw0KKyNpZmRlZiBX > SVRIX0NZQ0xFX0dDDQorCTAsCQkvKiB0cF9hc19idWZmZXIgKi8NCisJUHlfVFBGTEFHU19E > RUZBVUxUIHwgUHlfVFBGTEFHU19IQVZFX0dDSU5GTywgLyp0cF9mbGFncyovDQorCTAsCQkv > KiB0cF9kb2MgKi8NCisJKHJlY3Vyc2Vwcm9jKWNsYXNzX3JlY3Vyc2UsCS8qIHRwX3JlY3Vy > c2UgKi8NCisjZW5kaWYNCiB9Ow0KIA0KIGludA0KQEAgLTQ0NCwxMiArNDcxLDE1IEBADQog > CQlQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsNCiAJCXJldHVybiBOVUxMOw0KIAl9DQotCWlu > c3QgPSBQeU9iamVjdF9ORVcoUHlJbnN0YW5jZU9iamVjdCwgJlB5SW5zdGFuY2VfVHlwZSk7 > DQorCWluc3QgPSBQeU9iamVjdF9OZXcoUHlJbnN0YW5jZU9iamVjdCwgJlB5SW5zdGFuY2Vf > VHlwZSk7DQogCWlmIChpbnN0ID09IE5VTEwpDQogCQlyZXR1cm4gTlVMTDsNCiAJUHlfSU5D > UkVGKGNsYXNzKTsNCiAJaW5zdC0+aW5fY2xhc3MgPSAoUHlDbGFzc09iamVjdCAqKWNsYXNz > Ow0KIAlpbnN0LT5pbl9kaWN0ID0gUHlEaWN0X05ldygpOw0KKyNpZmRlZiBXSVRIX0NZQ0xF > X0dDDQorCVB5R0NfSW5zZXJ0KChQeU9iamVjdCAqKWluc3QpOw0KKyNlbmRpZg0KIAlpZiAo > aW5zdC0+aW5fZGljdCA9PSBOVUxMKSB7DQogCQlQeV9ERUNSRUYoaW5zdCk7DQogCQlyZXR1 > cm4gTlVMTDsNCkBAIC00OTgsMTEgKzUyOCwxNCBAQA0KIAlQeU9iamVjdCAqZXJyb3JfdHlw > ZSwgKmVycm9yX3ZhbHVlLCAqZXJyb3JfdHJhY2ViYWNrOw0KIAlQeU9iamVjdCAqZGVsOw0K > IAlzdGF0aWMgUHlPYmplY3QgKmRlbHN0cjsNCisJZXh0ZXJuIGxvbmcgX1B5X1JlZlRvdGFs > Ow0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDDQorCVB5R0NfUmVtb3ZlKChQeU9iamVjdCAqKWlu > c3QpOw0KKyNlbmRpZg0KIAkvKiBDYWxsIHRoZSBfX2RlbF9fIG1ldGhvZCBpZiBpdCBleGlz > dHMuICBGaXJzdCB0ZW1wb3JhcmlseQ0KIAkgICByZXZpdmUgdGhlIG9iamVjdCBhbmQgc2F2 > ZSB0aGUgY3VycmVudCBleGNlcHRpb24sIGlmIGFueS4gKi8NCiAjaWZkZWYgUHlfVFJBQ0Vf > UkVGUw0KIAkvKiBtdWNoIHRvbyBjb21wbGljYXRlZCBpZiBQeV9UUkFDRV9SRUZTIGRlZmlu > ZWQgKi8NCi0JZXh0ZXJuIGxvbmcgX1B5X1JlZlRvdGFsOw0KIAlpbnN0LT5vYl90eXBlID0g > JlB5SW5zdGFuY2VfVHlwZTsNCiAJX1B5X05ld1JlZmVyZW5jZSgoUHlPYmplY3QgKilpbnN0 > KTsNCiAJX1B5X1JlZlRvdGFsLS07CQkvKiBjb21wZW5zYXRlIGZvciBpbmNyZW1lbnQgaW4g > TkVXUkVGICovDQpAQCAtNTUwLDYgKzU4Myw5IEBADQogI2lmZGVmIENPVU5UX0FMTE9DUw0K > IAkJaW5zdC0+b2JfdHlwZS0+dHBfZnJlZS0tOw0KICNlbmRpZg0KKyNpZmRlZiBXSVRIX0NZ > Q0xFX0dDDQorCQlQeUdDX0luc2VydCgoUHlPYmplY3QgKilpbnN0KTsNCisjZW5kaWYNCiAJ > CXJldHVybjsgLyogX19kZWxfXyBhZGRlZCBhIHJlZmVyZW5jZTsgZG9uJ3QgZGVsZXRlIG5v > dyAqLw0KIAl9DQogI2lmZGVmIFB5X1RSQUNFX1JFRlMNCkBAIC01NTcsMTEgKzU5MywxMCBA > QA0KIAlpbnN0LT5vYl90eXBlLT50cF9mcmVlLS07CS8qIGNvbXBlbnNhdGUgZm9yIGluY3Jl > bWVudCBpbiBVTlJFRiAqLw0KICNlbmRpZg0KIAlfUHlfRm9yZ2V0UmVmZXJlbmNlKChQeU9i > amVjdCAqKWluc3QpOw0KLQlpbnN0LT5vYl90eXBlID0gTlVMTDsNCiAjZW5kaWYgLyogUHlf > VFJBQ0VfUkVGUyAqLw0KIAlQeV9ERUNSRUYoaW5zdC0+aW5fY2xhc3MpOw0KIAlQeV9YREVD > UkVGKGluc3QtPmluX2RpY3QpOw0KLQlmcmVlKChBTlkgKilpbnN0KTsNCisJUHlPYmplY3Rf > RGVsKChQeU9iamVjdCAqKWluc3QpOw0KIH0NCiANCiBzdGF0aWMgUHlPYmplY3QgKg0KQEAg > LTg0MCw2ICs4NzUsMTYgQEANCiAJcmV0dXJuIG91dGNvbWU7DQogfQ0KIA0KKyNpZmRlZiBX > SVRIX0NZQ0xFX0dDDQorc3RhdGljIGludA0KK2luc3RhbmNlX3JlY3Vyc2UoUHlJbnN0YW5j > ZU9iamVjdCAqbywgdmlzaXRwcm9jIHZpc2l0LCB2b2lkICpjbG9zdXJlKQ0KK3sNCisJaWYg > KG8tPmluX2NsYXNzKSB2aXNpdCgoUHlPYmplY3QgKikoby0+aW5fY2xhc3MpLCBjbG9zdXJl > KTsNCisJaWYgKG8tPmluX2RpY3QpIHZpc2l0KG8tPmluX2RpY3QsIGNsb3N1cmUpOw0KKwly > ZXR1cm4gMTsNCit9DQorI2VuZGlmIC8qIFdJVEhfQ1lDTEVfR0MgKi8NCisNCiBzdGF0aWMg > UHlPYmplY3QgKmdldGl0ZW1zdHIsICpzZXRpdGVtc3RyLCAqZGVsaXRlbXN0ciwgKmxlbnN0 > cjsNCiANCiBzdGF0aWMgaW50DQpAQCAtMTQ2Myw3ICsxNTA4LDExIEBADQogCShnZXRhdHRy > b2Z1bmMpaW5zdGFuY2VfZ2V0YXR0ciwgLyp0cF9nZXRhdHRybyovDQogCShzZXRhdHRyb2Z1 > bmMpaW5zdGFuY2Vfc2V0YXR0ciwgLyp0cF9zZXRhdHRybyovDQogICAgICAgICAwLCAvKiB0 > cF9hc19idWZmZXIgKi8NCi0JUHlfVFBGTEFHU19ERUZBVUxULCAvKnRwX2ZsYWdzICovDQor > CVB5X1RQRkxBR1NfREVGQVVMVCB8IFB5X1RQRkxBR1NfSEFWRV9HQ0lORk8sIC8qdHBfZmxh > Z3MqLw0KKwkwLAkJLyogdHBfZG9jICovDQorI2lmZGVmIFdJVEhfQ1lDTEVfR0MNCisJKHJl > Y3Vyc2Vwcm9jKWluc3RhbmNlX3JlY3Vyc2UsCS8qIHRwX3JlY3Vyc2UgKi8NCisjZW5kaWYN > CiB9Ow0KIA0KIA0KQEAgLTE0OTMsNyArMTU0Miw3IEBADQogCQlfUHlfTmV3UmVmZXJlbmNl > KChQeU9iamVjdCAqKWltKTsNCiAJfQ0KIAllbHNlIHsNCi0JCWltID0gUHlPYmplY3RfTkVX > KFB5TWV0aG9kT2JqZWN0LCAmUHlNZXRob2RfVHlwZSk7DQorCQlpbSA9IFB5T2JqZWN0X05l > dyhQeU1ldGhvZE9iamVjdCwgJlB5TWV0aG9kX1R5cGUpOw0KIAkJaWYgKGltID09IE5VTEwp > DQogCQkJcmV0dXJuIE5VTEw7DQogCX0NCi0tLSBQeXRob24tY3ZzL09iamVjdHMvZGljdG9i > amVjdC5jCVRodSBNYXIgMzAgMjI6MDI6NTIgMjAwMA0KKysrIFB5dGhvbi1nYy9PYmplY3Rz > L2RpY3RvYmplY3QuYwlTYXQgQXByICA4IDAyOjA5OjU5IDIwMDANCkBAIC0xMjEsNyArMTIx > LDcgQEANCiAJCWlmIChkdW1teSA9PSBOVUxMKQ0KIAkJCXJldHVybiBOVUxMOw0KIAl9DQot > CW1wID0gUHlPYmplY3RfTkVXKGRpY3RvYmplY3QsICZQeURpY3RfVHlwZSk7DQorCW1wID0g > UHlPYmplY3RfTmV3KGRpY3RvYmplY3QsICZQeURpY3RfVHlwZSk7DQogCWlmIChtcCA9PSBO > VUxMKQ0KIAkJcmV0dXJuIE5VTEw7DQogCW1wLT5tYV9zaXplID0gMDsNCkBAIC0xMjksNiAr > MTI5LDkgQEANCiAJbXAtPm1hX3RhYmxlID0gTlVMTDsNCiAJbXAtPm1hX2ZpbGwgPSAwOw0K > IAltcC0+bWFfdXNlZCA9IDA7DQorI2lmZGVmIFdJVEhfQ1lDTEVfR0MNCisJUHlHQ19JbnNl > cnQoKFB5T2JqZWN0ICopbXApOw0KKyNlbmRpZg0KIAlyZXR1cm4gKFB5T2JqZWN0ICopbXA7 > DQogfQ0KIA0KQEAgLTQ4MCw2ICs0ODMsOSBAQA0KIAlyZWdpc3RlciBpbnQgaTsNCiAJcmVn > aXN0ZXIgZGljdGVudHJ5ICplcDsNCiAJUHlfVFJBU0hDQU5fU0FGRV9CRUdJTihtcCkNCisj > aWZkZWYgV0lUSF9DWUNMRV9HQw0KKwlQeUdDX1JlbW92ZSgoUHlPYmplY3QgKiltcCk7DQor > I2VuZGlmDQogCWZvciAoaSA9IDAsIGVwID0gbXAtPm1hX3RhYmxlOyBpIDwgbXAtPm1hX3Np > emU7IGkrKywgZXArKykgew0KIAkJaWYgKGVwLT5tZV9rZXkgIT0gTlVMTCkgew0KIAkJCVB5 > X0RFQ1JFRihlcC0+bWVfa2V5KTsNCkBAIC00ODksNyArNDk1LDcgQEANCiAJCX0NCiAJfQ0K > IAlQeU1lbV9YREVMKG1wLT5tYV90YWJsZSk7DQotCVB5TWVtX0RFTChtcCk7DQorCVB5T2Jq > ZWN0X0RlbCgoUHlPYmplY3QgKiltcCk7DQogCVB5X1RSQVNIQ0FOX1NBRkVfRU5EKG1wKQ0K > IH0NCiANCkBAIC0xMDM2LDYgKzEwNDIsMzMgQEANCiAJcmV0dXJuIFB5X05vbmU7DQogfQ0K > IA0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDDQorc3RhdGljIGludA0KK2RpY3RfcmVjdXJzZShQ > eU9iamVjdCAqb3AsIHZpc2l0cHJvYyB2aXNpdCwgdm9pZCAqY2xvc3VyZSkNCit7DQorCWlu > dCBpID0gMDsNCisJUHlPYmplY3QgKnBrOw0KKwlQeU9iamVjdCAqcHY7DQorDQorCXdoaWxl > IChQeURpY3RfTmV4dChvcCwgJmksICZwaywgJnB2KSkgew0KKwkJaWYgKCF2aXNpdChwaywg > Y2xvc3VyZSkpIHsNCisJCQlyZXR1cm4gMDsNCisJCX0NCisJCWlmICghdmlzaXQocHYsIGNs > b3N1cmUpKSB7DQorCQkJcmV0dXJuIDA7DQorCQl9DQorCX0NCisJcmV0dXJuIDE7DQorfQ0K > Kw0KK3N0YXRpYyBpbnQNCitkaWN0X2djX2NsZWFyKFB5T2JqZWN0ICpvcCkNCit7DQorCVB5 > RGljdF9DbGVhcihvcCk7DQorCXJldHVybiAwOw0KK30NCisjZW5kaWYgLyogV0lUSF9DWUNM > RV9HQyAqLw0KKw0KIHN0YXRpYyBQeU1ldGhvZERlZiBtYXBwX21ldGhvZHNbXSA9IHsNCiAJ > eyJoYXNfa2V5IiwJKFB5Q0Z1bmN0aW9uKWRpY3RfaGFzX2tleSwgICAgICBNRVRIX1ZBUkFS > R1N9LA0KIAl7ImtleXMiLAkoUHlDRnVuY3Rpb24pZGljdF9rZXlzfSwNCkBAIC0xMDcxLDYg > KzExMDQsMTggQEANCiAJMCwJCQkvKnRwX2FzX251bWJlciovDQogCTAsCQkJLyp0cF9hc19z > ZXF1ZW5jZSovDQogCSZkaWN0X2FzX21hcHBpbmcsCS8qdHBfYXNfbWFwcGluZyovDQorI2lm > ZGVmIFdJVEhfQ1lDTEVfR0MNCisJMCwJCS8qIHRwX2hhc2ggKi8NCisJMCwJCS8qIHRwX2Nh > bGwgKi8NCisJMCwJCS8qIHRwX3N0ciAqLw0KKwkwLAkJLyogdHBfZ2V0YXR0cm8gKi8NCisJ > MCwJCS8qIHRwX3NldGF0dHJvICovDQorCTAsCQkvKiB0cF9hc19idWZmZXIgKi8NCisJUHlf > VFBGTEFHU19ERUZBVUxUIHwgUHlfVFBGTEFHU19IQVZFX0dDSU5GTywgLyp0cF9mbGFncyov > DQorCTAsCQkvKiB0cF9kb2MgKi8NCisJKHJlY3Vyc2Vwcm9jKWRpY3RfcmVjdXJzZSwJLyog > dHBfcmVjdXJzZSAqLw0KKwkoaW5xdWlyeSlkaWN0X2djX2NsZWFyLAkJLyogdHBfY2xlYXIg > Ki8NCisjZW5kaWYNCiB9Ow0KIA0KIC8qIEZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5IHdp > dGggb2xkIGRpY3Rpb25hcnkgaW50ZXJmYWNlICovDQotLS0gUHl0aG9uLWN2cy9PYmplY3Rz > L2Z1bmNvYmplY3QuYwlUaHUgTWF5IDIxIDE4OjU1OjM0IDE5OTgNCisrKyBQeXRob24tZ2Mv > T2JqZWN0cy9mdW5jb2JqZWN0LmMJU2F0IEFwciAgOCAwMjowOTo1MCAyMDAwDQpAQCAtNDAs > NyArNDAsNyBAQA0KIAlQeU9iamVjdCAqY29kZTsNCiAJUHlPYmplY3QgKmdsb2JhbHM7DQog > ew0KLQlQeUZ1bmN0aW9uT2JqZWN0ICpvcCA9IFB5T2JqZWN0X05FVyhQeUZ1bmN0aW9uT2Jq > ZWN0LA0KKwlQeUZ1bmN0aW9uT2JqZWN0ICpvcCA9IFB5T2JqZWN0X05ldyhQeUZ1bmN0aW9u > T2JqZWN0LA0KIAkJCQkJICAgICZQeUZ1bmN0aW9uX1R5cGUpOw0KIAlpZiAob3AgIT0gTlVM > TCkgew0KIAkJUHlPYmplY3QgKmRvYzsNCkBAIC02Myw2ICs2Myw5IEBADQogCQlQeV9JTkNS > RUYoZG9jKTsNCiAJCW9wLT5mdW5jX2RvYyA9IGRvYzsNCiAJfQ0KKyNpZmRlZiBXSVRIX0NZ > Q0xFX0dDDQorCVB5R0NfSW5zZXJ0KChQeU9iamVjdCAqKW9wKTsNCisjZW5kaWYNCiAJcmV0 > dXJuIChQeU9iamVjdCAqKW9wOw0KIH0NCiANCkBAIC0xODYsMTIgKzE4OSwxNSBAQA0KIGZ1 > bmNfZGVhbGxvYyhvcCkNCiAJUHlGdW5jdGlvbk9iamVjdCAqb3A7DQogew0KKyNpZmRlZiBX > SVRIX0NZQ0xFX0dDDQorCVB5R0NfUmVtb3ZlKChQeU9iamVjdCAqKW9wKTsNCisjZW5kaWYN > CiAJUHlfREVDUkVGKG9wLT5mdW5jX2NvZGUpOw0KIAlQeV9ERUNSRUYob3AtPmZ1bmNfZ2xv > YmFscyk7DQogCVB5X0RFQ1JFRihvcC0+ZnVuY19uYW1lKTsNCiAJUHlfWERFQ1JFRihvcC0+ > ZnVuY19kZWZhdWx0cyk7DQogCVB5X1hERUNSRUYob3AtPmZ1bmNfZG9jKTsNCi0JUHlNZW1f > REVMKG9wKTsNCisJUHlPYmplY3RfRGVsKChQeU9iamVjdCAqKW9wKTsNCiB9DQogDQogc3Rh > dGljIFB5T2JqZWN0Kg0KQEAgLTIzOSw2ICsyNDUsMTkgQEANCiAJcmV0dXJuIGg7DQogfQ0K > IA0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDDQorc3RhdGljIGludA0KK2Z1bmNfcmVjdXJzZShQ > eUZ1bmN0aW9uT2JqZWN0ICpmLCB2aXNpdHByb2MgdmlzaXQsIHZvaWQgKmNsb3N1cmUpDQor > ew0KKwlpZiAoZi0+ZnVuY19jb2RlKSB2aXNpdChmLT5mdW5jX2NvZGUsIGNsb3N1cmUpOw0K > KwlpZiAoZi0+ZnVuY19nbG9iYWxzKSB2aXNpdChmLT5mdW5jX2dsb2JhbHMsIGNsb3N1cmUp > Ow0KKwlpZiAoZi0+ZnVuY19kZWZhdWx0cykgdmlzaXQoZi0+ZnVuY19kZWZhdWx0cywgY2xv > c3VyZSk7DQorCWlmIChmLT5mdW5jX2RvYykgdmlzaXQoZi0+ZnVuY19kb2MsIGNsb3N1cmUp > Ow0KKwlpZiAoZi0+ZnVuY19uYW1lKSB2aXNpdChmLT5mdW5jX25hbWUsIGNsb3N1cmUpOw0K > KwlyZXR1cm4gMTsNCit9DQorI2VuZGlmIC8qIFdJVEhfQ1lDTEVfR0MgKi8NCisNCiBQeVR5 > cGVPYmplY3QgUHlGdW5jdGlvbl9UeXBlID0gew0KIAlQeU9iamVjdF9IRUFEX0lOSVQoJlB5 > VHlwZV9UeXBlKQ0KIAkwLA0KQEAgLTI1NSw0ICsyNzQsMTQgQEANCiAJMCwJCS8qdHBfYXNf > c2VxdWVuY2UqLw0KIAkwLAkJLyp0cF9hc19tYXBwaW5nKi8NCiAJKGhhc2hmdW5jKWZ1bmNf > aGFzaCwgLyp0cF9oYXNoKi8NCisjaWZkZWYgV0lUSF9DWUNMRV9HQw0KKwkwLAkJLyp0cF9j > YWxsKi8NCisJMCwJCS8qdHBfc3RyKi8NCisJMCwJCS8qdHBfZ2V0YXR0cm8qLw0KKwkwLAkJ > Lyp0cF9zZXRhdHRybyovDQorCTAsCQkvKiB0cF9hc19idWZmZXIgKi8NCisJUHlfVFBGTEFH > U19ERUZBVUxUIHwgUHlfVFBGTEFHU19IQVZFX0dDSU5GTywgLyp0cF9mbGFncyovDQorCTAs > CQkvKiB0cF9kb2MgKi8NCisJKHJlY3Vyc2Vwcm9jKWZ1bmNfcmVjdXJzZSwJLyogdHBfcmVj > dXJzZSAqLw0KKyNlbmRpZg0KIH07DQotLS0gUHl0aG9uLWN2cy9PYmplY3RzL2xpc3RvYmpl > Y3QuYwlGcmkgTWFyIDI0IDIyOjMyOjMwIDIwMDANCisrKyBQeXRob24tZ2MvT2JqZWN0cy9s > aXN0b2JqZWN0LmMJTW9uIEFwciAyNCAyMToxNDo0MiAyMDAwDQpAQCAtNjEsMzQgKzYxLDM3 > IEBADQogCWludCBpOw0KIAlQeUxpc3RPYmplY3QgKm9wOw0KIAlzaXplX3QgbmJ5dGVzOw0K > KwlQeU9iamVjdCAqKml0ZW07DQorDQogCWlmIChzaXplIDwgMCkgew0KIAkJUHlFcnJfQmFk > SW50ZXJuYWxDYWxsKCk7DQogCQlyZXR1cm4gTlVMTDsNCiAJfQ0KLQluYnl0ZXMgPSBzaXpl > ICogc2l6ZW9mKFB5T2JqZWN0ICopOw0KLQkvKiBDaGVjayBmb3Igb3ZlcmZsb3cgKi8NCi0J > aWYgKG5ieXRlcyAvIHNpemVvZihQeU9iamVjdCAqKSAhPSAoc2l6ZV90KXNpemUpIHsNCi0J > CXJldHVybiBQeUVycl9Ob01lbW9yeSgpOw0KLQl9DQotCW9wID0gKFB5TGlzdE9iamVjdCAq > KSBtYWxsb2Moc2l6ZW9mKFB5TGlzdE9iamVjdCkpOw0KLQlpZiAob3AgPT0gTlVMTCkgew0K > LQkJcmV0dXJuIFB5RXJyX05vTWVtb3J5KCk7DQotCX0NCi0JaWYgKHNpemUgPD0gMCkgew0K > LQkJb3AtPm9iX2l0ZW0gPSBOVUxMOw0KLQl9DQorCWlmIChzaXplID09IDApDQorCQlpdGVt > ID0gTlVMTDsNCiAJZWxzZSB7DQotCQlvcC0+b2JfaXRlbSA9IChQeU9iamVjdCAqKikgbWFs > bG9jKG5ieXRlcyk7DQotCQlpZiAob3AtPm9iX2l0ZW0gPT0gTlVMTCkgew0KLQkJCWZyZWUo > KEFOWSAqKW9wKTsNCisJCW5ieXRlcyA9IHNpemUgKiBzaXplb2YoUHlPYmplY3QgKik7DQor > CQkvKiBDaGVjayBmb3Igb3ZlcmZsb3cgKi8NCisJCWlmIChuYnl0ZXMgLyBzaXplb2YoUHlP > YmplY3QgKikgIT0gKHNpemVfdClzaXplKSB7DQogCQkJcmV0dXJuIFB5RXJyX05vTWVtb3J5 > KCk7DQogCQl9DQorCQlpdGVtID0gKFB5T2JqZWN0ICoqKSBtYWxsb2MobmJ5dGVzKTsNCisJ > CWlmIChpdGVtID09IE5VTEwpDQorCQkJcmV0dXJuIFB5RXJyX05vTWVtb3J5KCk7DQorCX0N > CisJb3AgPSBQeU9iamVjdF9OZXcoUHlMaXN0T2JqZWN0LCAmUHlMaXN0X1R5cGUpOw0KKwlp > ZiAob3AgPT0gTlVMTCkgew0KKwkJaWYgKGl0ZW0gIT0gTlVMTCkNCisJCQlmcmVlKChBTlkg > KilpdGVtKTsNCisJCXJldHVybiBQeUVycl9Ob01lbW9yeSgpOw0KIAl9DQotCW9wLT5vYl90 > eXBlID0gJlB5TGlzdF9UeXBlOw0KIAlvcC0+b2Jfc2l6ZSA9IHNpemU7DQorCW9wLT5vYl9p > dGVtID0gaXRlbTsNCiAJZm9yIChpID0gMDsgaSA8IHNpemU7IGkrKykNCiAJCW9wLT5vYl9p > dGVtW2ldID0gTlVMTDsNCi0JX1B5X05ld1JlZmVyZW5jZSgoUHlPYmplY3QgKilvcCk7DQor > I2lmZGVmIFdJVEhfQ1lDTEVfR0MNCisJUHlHQ19JbnNlcnQoKFB5T2JqZWN0ICopb3ApOw0K > KyNlbmRpZg0KIAlyZXR1cm4gKFB5T2JqZWN0ICopIG9wOw0KIH0NCiANCkBAIC0yMTYsNiAr > MjE5LDkgQEANCiB7DQogCWludCBpOw0KIAlQeV9UUkFTSENBTl9TQUZFX0JFR0lOKG9wKQ0K > KyNpZmRlZiBXSVRIX0NZQ0xFX0dDDQorCVB5R0NfUmVtb3ZlKChQeU9iamVjdCAqKW9wKTsN > CisjZW5kaWYNCiAJaWYgKG9wLT5vYl9pdGVtICE9IE5VTEwpIHsNCiAJCS8qIERvIGl0IGJh > Y2t3YXJkcywgZm9yIENocmlzdGlhbiBUaXNtZXIuDQogCQkgICBUaGVyZSdzIGEgc2ltcGxl > IHRlc3QgY2FzZSB3aGVyZSBzb21laG93IHRoaXMgcmVkdWNlcw0KQEAgLTIyNyw3ICsyMzMs > NyBAQA0KIAkJfQ0KIAkJZnJlZSgoQU5ZICopb3AtPm9iX2l0ZW0pOw0KIAl9DQotCWZyZWUo > KEFOWSAqKW9wKTsNCisJUHlPYmplY3RfRGVsKChQeU9iamVjdCAqKW9wKTsNCiAJUHlfVFJB > U0hDQU5fU0FGRV9FTkQob3ApDQogfQ0KIA0KQEAgLTEzOTksNiArMTQwNSwyOSBAQA0KIAly > ZXR1cm4gTlVMTDsNCiB9DQogDQorI2lmZGVmIFdJVEhfQ1lDTEVfR0MNCitzdGF0aWMgaW50 > DQorbGlzdF9yZWN1cnNlKFB5TGlzdE9iamVjdCAqbywgdmlzaXRwcm9jIHZpc2l0LCB2b2lk > ICpjbG9zdXJlKQ0KK3sNCisJaW50IGk7DQorCVB5T2JqZWN0ICp4Ow0KKw0KKwlmb3IgKGkg > PSBvLT5vYl9zaXplOyAtLWkgPj0gMDsgKSB7DQorCQl4ID0gby0+b2JfaXRlbVtpXTsNCisJ > CWlmICh4ICE9IE5VTEwgJiYgIXZpc2l0KHgsIGNsb3N1cmUpKQ0KKwkJCXJldHVybiAwOw0K > Kwl9DQorCXJldHVybiAxOw0KK30NCisNCitzdGF0aWMgaW50DQorbGlzdF9jbGVhcihQeUxp > c3RPYmplY3QgKmxwKQ0KK3sNCisJKHZvaWQpIFB5TGlzdF9TZXRTbGljZSgoUHlPYmplY3Qg > KilscCwgMCwgbHAtPm9iX3NpemUsIDApOw0KKwlyZXR1cm4gMDsNCit9DQorI2VuZGlmIC8q > IFdJVEhfQ1lDTEVfR0MgKi8NCisNCiBzdGF0aWMgY2hhciBhcHBlbmRfZG9jW10gPQ0KICJM > LmFwcGVuZChvYmplY3QpIC0tIGFwcGVuZCBvYmplY3QgdG8gZW5kIjsNCiBzdGF0aWMgY2hh > ciBleHRlbmRfZG9jW10gPQ0KQEAgLTE0NjQsNiArMTQ5MywxOCBAQA0KIAkwLAkJLyp0cF9h > c19udW1iZXIqLw0KIAkmbGlzdF9hc19zZXF1ZW5jZSwJLyp0cF9hc19zZXF1ZW5jZSovDQog > CTAsCQkvKnRwX2FzX21hcHBpbmcqLw0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDDQorCTAsCQkv > KiB0cF9oYXNoICovDQorCTAsCQkvKiB0cF9jYWxsICovDQorCTAsCQkvKiB0cF9zdHIgKi8N > CisJMCwJCS8qIHRwX2dldGF0dHJvICovDQorCTAsCQkvKiB0cF9zZXRhdHRybyAqLw0KKwkw > LAkJLyogdHBfYXNfYnVmZmVyICovDQorCVB5X1RQRkxBR1NfREVGQVVMVCB8IFB5X1RQRkxB > R1NfSEFWRV9HQ0lORk8sCS8qIHRwX2ZsYWdzICovDQorCTAsCQkvKiB0cF9kb2MgKi8NCisJ > KHJlY3Vyc2Vwcm9jKWxpc3RfcmVjdXJzZSwJLyogdHBfcmVjdXJzZSAqLw0KKwkoaW5xdWly > eSlsaXN0X2NsZWFyLAkvKiB0cF9jbGVhciAqLw0KKyNlbmRpZg0KIH07DQogDQogDQpAQCAt > MTUzMiw1ICsxNTczLDE2IEBADQogCTAsCQkvKnRwX2FzX251bWJlciovDQogCSZpbW11dGFi > bGVfbGlzdF9hc19zZXF1ZW5jZSwJLyp0cF9hc19zZXF1ZW5jZSovDQogCTAsCQkvKnRwX2Fz > X21hcHBpbmcqLw0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDDQorCTAsCQkvKiB0cF9oYXNoICov > DQorCTAsCQkvKiB0cF9jYWxsICovDQorCTAsCQkvKiB0cF9zdHIgKi8NCisJMCwJCS8qIHRw > X2dldGF0dHJvICovDQorCTAsCQkvKiB0cF9zZXRhdHRybyAqLw0KKwkwLAkJLyogdHBfYXNf > YnVmZmVyICovDQorCVB5X1RQRkxBR1NfREVGQVVMVCwJLyogdHBfZmxhZ3MgKi8NCisJMCwJ > CS8qIHRwX2RvYyAqLw0KKwkocmVjdXJzZXByb2MpbGlzdF9yZWN1cnNlLAkvKiB0cF9yZWN1 > cnNlICovDQorI2VuZGlmDQogfTsNCiANCi0tLSBQeXRob24tY3ZzL09iamVjdHMvb2JqZWN0 > LmMJVHVlIE1hciAyOCAwODoxMTowOSAyMDAwDQorKysgUHl0aG9uLWdjL09iamVjdHMvb2Jq > ZWN0LmMJU2F0IEFwciAgOCAwMjoxMDowNiAyMDAwDQpAQCAtMTA3LDIwICsxMDcsMTIgQEAN > CiB9DQogI2VuZGlmDQogDQotI2lmbmRlZiBNU19DT1JFRExMDQotUHlPYmplY3QgKg0KLV9Q > eU9iamVjdF9OZXcodHApDQotCVB5VHlwZU9iamVjdCAqdHA7DQotI2Vsc2UNCisNCiBQeU9i > amVjdCAqDQotX1B5T2JqZWN0X05ldyh0cCxvcCkNCitfUHlPYmplY3RfRnJvbVR5cGUodHAs > b3ApDQogCVB5VHlwZU9iamVjdCAqdHA7DQogCVB5T2JqZWN0ICpvcDsNCi0jZW5kaWYNCiB7 > DQotI2lmbmRlZiBNU19DT1JFRExMDQotCVB5T2JqZWN0ICpvcCA9IChQeU9iamVjdCAqKSBt > YWxsb2ModHAtPnRwX2Jhc2ljc2l6ZSk7DQotI2VuZGlmDQogCWlmIChvcCA9PSBOVUxMKQ0K > IAkJcmV0dXJuIFB5RXJyX05vTWVtb3J5KCk7DQogCW9wLT5vYl90eXBlID0gdHA7DQpAQCAt > MTI4LDI5ICsxMjAsNzggQEANCiAJcmV0dXJuIG9wOw0KIH0NCiANCi0jaWZuZGVmIE1TX0NP > UkVETEwNCi1QeVZhck9iamVjdCAqDQotX1B5T2JqZWN0X05ld1Zhcih0cCwgc2l6ZSkNCi0J > UHlUeXBlT2JqZWN0ICp0cDsNCi0JaW50IHNpemU7DQotI2Vsc2UNCiBQeVZhck9iamVjdCAq > DQotX1B5T2JqZWN0X05ld1Zhcih0cCwgc2l6ZSwgb3ApDQorX1B5T2JqZWN0X1ZhckZyb21U > eXBlKHRwLCBzaXplLCBvcCkNCiAJUHlUeXBlT2JqZWN0ICp0cDsNCiAJaW50IHNpemU7DQog > CVB5VmFyT2JqZWN0ICpvcDsNCi0jZW5kaWYNCiB7DQotI2lmbmRlZiBNU19DT1JFRExMDQot > CVB5VmFyT2JqZWN0ICpvcCA9IChQeVZhck9iamVjdCAqKQ0KLQkJbWFsbG9jKHRwLT50cF9i > YXNpY3NpemUgKyBzaXplICogdHAtPnRwX2l0ZW1zaXplKTsNCi0jZW5kaWYNCiAJaWYgKG9w > ID09IE5VTEwpDQogCQlyZXR1cm4gKFB5VmFyT2JqZWN0ICopUHlFcnJfTm9NZW1vcnkoKTsN > CiAJb3AtPm9iX3R5cGUgPSB0cDsNCiAJb3AtPm9iX3NpemUgPSBzaXplOw0KIAlfUHlfTmV3 > UmVmZXJlbmNlKChQeU9iamVjdCAqKW9wKTsNCiAJcmV0dXJuIG9wOw0KK30NCisNCitQeU9i > amVjdCAqDQorX1B5T2JqZWN0X05ldyh0cCkNCisJUHlUeXBlT2JqZWN0ICp0cDsNCit7DQor > CVB5T2JqZWN0ICpvcDsNCisjaWZkZWYgV0lUSF9DWUNMRV9HQw0KKwlpZiAoUFlfVFlQRUlT > R0ModHApKSB7DQorCQlQeUdDSW5mbyAqZzsNCisJCWcgPSAoUHlHQ0luZm8gKikgbWFsbG9j > KHNpemVvZigqZykgKyB0cC0+dHBfYmFzaWNzaXplKTsNCisJCWlmIChnID09IE5VTEwpIHsN > CisJCQlvcCA9IE5VTEw7DQorCQl9IGVsc2Ugew0KKwkJCW9wID0gUFlfR0NPQkooZyk7DQor > CQl9DQorCX0gZWxzZQ0KKyNlbmRpZiAvKiBXSVRIX0NZQ0xFX0dDICovDQorCXsNCisJCW9w > ID0gKFB5T2JqZWN0ICopIG1hbGxvYyh0cC0+dHBfYmFzaWNzaXplKTsNCisJfQ0KKwlyZXR1 > cm4gX1B5T2JqZWN0X0Zyb21UeXBlKHRwLCBvcCk7DQorfQ0KKw0KK1B5VmFyT2JqZWN0ICoN > CitfUHlPYmplY3RfTmV3VmFyKHRwLCBzaXplKQ0KKwlQeVR5cGVPYmplY3QgKnRwOw0KKwlp > bnQgc2l6ZTsNCit7DQorCVB5VmFyT2JqZWN0ICpvcDsNCisjaWZkZWYgV0lUSF9DWUNMRV9H > Qw0KKwlpZiAoUFlfVFlQRUlTR0ModHApKSB7DQorCQlQeUdDSW5mbyAqZzsNCisJCWcgPSAo > UHlHQ0luZm8gKikgbWFsbG9jKHNpemVvZigqZykgKyANCisJCQkJCXRwLT50cF9iYXNpY3Np > emUgKw0KKwkJCQkJc2l6ZSAqIHRwLT50cF9pdGVtc2l6ZSk7DQorCQlpZiAoZyA9PSBOVUxM > KSB7DQorCQkJb3AgPSBOVUxMOw0KKwkJfSBlbHNlIHsNCisJCQlvcCA9IChQeVZhck9iamVj > dCAqKVBZX0dDT0JKKGcpOw0KKwkJfQ0KKwl9IGVsc2UNCisjZW5kaWYgLyogV0lUSF9DWUNM > RV9HQyAqLw0KKwl7DQorCQlvcCA9IChQeVZhck9iamVjdCAqKQ0KKwkJCW1hbGxvYyh0cC0+ > dHBfYmFzaWNzaXplICsgc2l6ZSAqIHRwLT50cF9pdGVtc2l6ZSk7DQorCX0NCisJcmV0dXJu > IF9QeU9iamVjdF9WYXJGcm9tVHlwZSh0cCwgc2l6ZSwgb3ApOw0KK30NCisNCit2b2lkDQor > UHlPYmplY3RfRGVsKG9wKQ0KKwlQeU9iamVjdCAqb3A7DQorew0KKyNpZmRlZiBXSVRIX0NZ > Q0xFX0dDDQorCWlmIChQWV9JU0dDKG9wKSkgew0KKwkJb3AgPSAoUHlPYmplY3QgKilQWV9H > Q0lORk9fVU5TQUZFKG9wKTsNCisJfQ0KKyNlbmRpZg0KKwlmcmVlKG9wKTsNCiB9DQogDQog > aW50DQotLS0gUHl0aG9uLWN2cy9PYmplY3RzL3R1cGxlb2JqZWN0LmMJRnJpIE1hciAyNCAy > MjozMjozMCAyMDAwDQorKysgUHl0aG9uLWdjL09iamVjdHMvdHVwbGVvYmplY3QuYwlNb24g > QXByIDI0IDIxOjIxOjU5IDIwMDANCkBAIC04Miw4ICs4Miw4IEBADQogI2VuZGlmDQogI2lm > ZGVmIFB5X1RSQUNFX1JFRlMNCiAJCW9wLT5vYl90eXBlID0gJlB5VHVwbGVfVHlwZTsNCi0J > CW9wLT5vYl9zaXplID0gc2l6ZTsNCiAjZW5kaWYNCisJCV9QeV9OZXdSZWZlcmVuY2UoKFB5 > T2JqZWN0ICopb3ApOw0KIAl9DQogCWVsc2UNCiAjZW5kaWYNCkBAIC05NywyMyArOTcsMjMg > QEANCiAJCQlyZXR1cm4gUHlFcnJfTm9NZW1vcnkoKTsNCiAJCX0NCiAJCTsNCi0JCW9wID0g > KFB5VHVwbGVPYmplY3QgKikgbWFsbG9jKG5ieXRlcyk7DQorCQlvcCA9IFB5T2JqZWN0X05l > d1ZhcihQeVR1cGxlT2JqZWN0LCAmUHlUdXBsZV9UeXBlLCBzaXplKTsNCiAJCWlmIChvcCA9 > PSBOVUxMKQ0KIAkJCXJldHVybiBQeUVycl9Ob01lbW9yeSgpOw0KIA0KLQkJb3AtPm9iX3R5 > cGUgPSAmUHlUdXBsZV9UeXBlOw0KLQkJb3AtPm9iX3NpemUgPSBzaXplOw0KIAl9DQogCWZv > ciAoaSA9IDA7IGkgPCBzaXplOyBpKyspDQogCQlvcC0+b2JfaXRlbVtpXSA9IE5VTEw7DQot > CV9QeV9OZXdSZWZlcmVuY2UoKFB5T2JqZWN0ICopb3ApOw0KKw0KICNpZiBNQVhTQVZFU0la > RSA+IDANCiAJaWYgKHNpemUgPT0gMCkgew0KIAkJZnJlZV90dXBsZXNbMF0gPSBvcDsNCi0J > CSsrbnVtX2ZyZWVfdHVwbGVzWzBdOw0KIAkJUHlfSU5DUkVGKG9wKTsJLyogZXh0cmEgSU5D > UkVGIHNvIHRoYXQgdGhpcyBpcyBuZXZlciBmcmVlZCAqLw0KIAl9DQogI2VuZGlmDQorI2lm > ZGVmIFdJVEhfQ1lDTEVfR0MNCisJUHlHQ19JbnNlcnQoKFB5T2JqZWN0ICopb3ApOw0KKyNl > bmRpZg0KIAlyZXR1cm4gKFB5T2JqZWN0ICopIG9wOw0KIH0NCiANCkBAIC0xODAsNiArMTgw > LDkgQEANCiAJcmVnaXN0ZXIgaW50IGk7DQogCXJlZ2lzdGVyIGludCBsZW4gPSAgb3AtPm9i > X3NpemU7DQogCVB5X1RSQVNIQ0FOX1NBRkVfQkVHSU4ob3ApDQorI2lmZGVmIFdJVEhfQ1lD > TEVfR0MNCisJUHlHQ19SZW1vdmUoKFB5T2JqZWN0ICopb3ApOw0KKyNlbmRpZg0KIAlpZiAo > bGVuID4gMCkgew0KIAkJaSA9IGxlbjsNCiAJCXdoaWxlICgtLWkgPj0gMCkNCkBAIC0xOTMs > NyArMTk2LDcgQEANCiAJCX0NCiAjZW5kaWYNCiAJfQ0KLQlmcmVlKChBTlkgKilvcCk7DQor > CVB5T2JqZWN0X0RlbCgoUHlPYmplY3QgKilvcCk7DQogZG9uZToNCiAJUHlfVFJBU0hDQU5f > U0FGRV9FTkQob3ApDQogfQ0KQEAgLTQwMSw2ICs0MDQsMjIgQEANCiAJcmV0dXJuIChQeU9i > amVjdCAqKSBucDsNCiB9DQogDQorI2lmZGVmIFdJVEhfQ1lDTEVfR0MNCitzdGF0aWMgaW50 > DQordHVwbGVyZWN1cnNlKFB5VHVwbGVPYmplY3QgKm8sIHZpc2l0cHJvYyB2aXNpdCwgdm9p > ZCAqY2xvc3VyZSkNCit7DQorCWludCBpOw0KKwlQeU9iamVjdCAqeDsNCisNCisJZm9yIChp > ID0gby0+b2Jfc2l6ZTsgLS1pID49IDA7ICkgew0KKwkJeCA9IG8tPm9iX2l0ZW1baV07DQor > CQlpZiAoeCAhPSBOVUxMICYmICF2aXNpdCh4LCBjbG9zdXJlKSkNCisJCQlyZXR1cm4gMDsN > CisJfQ0KKwlyZXR1cm4gMTsNCit9DQorI2VuZGlmIC8qIFdJVEhfQ1lDTEVfR0MgKi8NCisN > CiBzdGF0aWMgUHlTZXF1ZW5jZU1ldGhvZHMgdHVwbGVfYXNfc2VxdWVuY2UgPSB7DQogCShp > bnF1aXJ5KXR1cGxlbGVuZ3RoLCAvKnNxX2xlbmd0aCovDQogCShiaW5hcnlmdW5jKXR1cGxl > Y29uY2F0LCAvKnNxX2NvbmNhdCovDQpAQCAtNDI3LDYgKzQ0NiwxNiBAQA0KIAkmdHVwbGVf > YXNfc2VxdWVuY2UsCS8qdHBfYXNfc2VxdWVuY2UqLw0KIAkwLAkJLyp0cF9hc19tYXBwaW5n > Ki8NCiAJKGhhc2hmdW5jKXR1cGxlaGFzaCwgLyp0cF9oYXNoKi8NCisjaWZkZWYgV0lUSF9D > WUNMRV9HQw0KKwkwLAkJLyogdHBfY2FsbCAqLw0KKwkwLAkJLyogdHBfc3RyICovDQorCTAs > CQkvKiB0cF9nZXRhdHRybyAqLw0KKwkwLAkJLyogdHBfc2V0YXR0cm8gKi8NCisJMCwJCS8q > IHRwX2FzX2J1ZmZlciAqLw0KKwlQeV9UUEZMQUdTX0RFRkFVTFQgfCBQeV9UUEZMQUdTX0hB > VkVfR0NJTkZPLAkvKiB0cF9mbGFncyAqLw0KKwkwLAkJLyogdHBfZG9jICovDQorCShyZWN1 > cnNlcHJvYyl0dXBsZXJlY3Vyc2UsCS8qIHRwX3JlY3Vyc2UgKi8NCisjZW5kaWYNCiB9Ow0K > IA0KIC8qIFRoZSBmb2xsb3dpbmcgZnVuY3Rpb24gYnJlYWtzIHRoZSBub3Rpb24gdGhhdCB0 > dXBsZXMgYXJlIGltbXV0YWJsZToNCkBAIC00NDksNiArNDc4LDkgQEANCiAJaW50IGk7DQog > CWludCBzaXplZGlmZjsNCiANCisjaWZkZWYgV0lUSF9DWUNMRV9HQw0KKwlQeUdDSW5mbyAq > ZyA9IFBZX0dDSU5GTygqcHYpOyANCisjZW5kaWYNCiAJdiA9IChQeVR1cGxlT2JqZWN0ICop > ICpwdjsNCiAJaWYgKHYgPT0gTlVMTCB8fCAhUHlUdXBsZV9DaGVjayh2KSB8fCB2LT5vYl9y > ZWZjbnQgIT0gMSkgew0KIAkJKnB2ID0gMDsNCkBAIC00NzksNyArNTExLDYgQEANCiAJfQ0K > ICNpZiBNQVhTQVZFU0laRSA+IDANCiAJaWYgKG5ld3NpemUgPT0gMCAmJiBmcmVlX3R1cGxl > c1swXSkgew0KLQkJbnVtX2ZyZWVfdHVwbGVzWzBdLS07DQogCQlzdiA9IGZyZWVfdHVwbGVz > WzBdOw0KIAkJc3YtPm9iX3NpemUgPSAwOw0KIAkJUHlfSU5DUkVGKHN2KTsNCkBAIC01MTEs > OSArNTQyLDIyIEBADQogCX0gZWxzZSANCiAjZW5kaWYJCQ0KIAl7DQorI2lmZGVmIFdJVEhf > Q1lDTEVfR0MNCisJCVB5R0NfUmVtb3ZlKChQeU9iamVjdCAqKXYpOw0KKw0KKwkJZyA9IChQ > eUdDSW5mbyAqKSByZWFsbG9jKChjaGFyICopZywgc2l6ZW9mKCpnKSArIA0KKwkJCQlzaXpl > b2YoUHlUdXBsZU9iamVjdCkgKyANCisJCQkJbmV3c2l6ZSAqIHNpemVvZihQeU9iamVjdCAq > KSk7DQorCQlpZiAoZyA9PSBOVUxMKSB7DQorCQkJc3YgPT0gTlVMTDsNCisJCX0gZWxzZSB7 > DQorCQkJc3YgPSAoUHlUdXBsZU9iamVjdCAqKSBQWV9HQ09CSihnKTsNCisJCX0NCisjZWxz > ZQ0KIAkJc3YgPSAoUHlUdXBsZU9iamVjdCAqKQ0KIAkJCXJlYWxsb2MoKGNoYXIgKil2LA0K > IAkJCQlzaXplb2YoUHlUdXBsZU9iamVjdCkgKyBuZXdzaXplICogc2l6ZW9mKFB5T2JqZWN0 > ICopKTsNCisjZW5kaWYNCiAJCSpwdiA9IChQeU9iamVjdCAqKSBzdjsNCiAJCWlmIChzdiA9 > PSBOVUxMKSB7DQogCQkJUHlNZW1fREVMKHYpOw0KQEAgLTUyMiw2ICs1NjYsOSBAQA0KIAkJ > fQ0KIAl9DQogCV9QeV9OZXdSZWZlcmVuY2UoKFB5T2JqZWN0ICopc3YpOw0KKyNpZmRlZiBX > SVRIX0NZQ0xFX0dDDQorCVB5R0NfSW5zZXJ0KChQeU9iamVjdCAqKXN2KTsNCisjZW5kaWYN > CiAJZm9yIChpID0gc3YtPm9iX3NpemU7IGkgPCBuZXdzaXplOyBpKyspDQogCQlzdi0+b2Jf > aXRlbVtpXSA9IE5VTEw7DQogCWlmIChsYXN0X2lzX3N0aWNreSAmJiBzaXplZGlmZiA+IDAp > IHsNCkBAIC01NTEsNyArNTk4LDExIEBADQogCQl3aGlsZSAocCkgew0KIAkJCXEgPSBwOw0K > IAkJCXAgPSAoUHlUdXBsZU9iamVjdCAqKShwLT5vYl9pdGVtWzBdKTsNCi0JCQlQeU1lbV9E > RUwocSk7DQorI2lmZGVmIFB5X1RSQUNFX1JFRlMNCisJCQlxLT5vYl90eXBlID0gICZQeVR1 > cGxlX1R5cGU7DQorI2VuZGlmDQorCQkJUHlPYmplY3RfRGVsKChQeU9iamVjdCAqKXEpOw0K > KwkJCQ0KIAkJfQ0KIAl9DQogI2VuZGlmDQotLS0gUHl0aG9uLWN2cy9QQy9jb25maWcuYwlG > cmkgQXByICA3IDE1OjI3OjA0IDIwMDANCisrKyBQeXRob24tZ2MvUEMvY29uZmlnLmMJU2F0 > IEFwciAgOCAwMzoxMjo1OCAyMDAwDQpAQCAtNDEsNiArNDEsOSBAQA0KIGV4dGVybiB2b2lk > IGluaXRiaW5hc2NpaSgpOw0KIGV4dGVybiB2b2lkIGluaXRjbWF0aCgpOw0KIGV4dGVybiB2 > b2lkIGluaXRlcnJubygpOw0KKyNpZmRlZiBXSVRIX0NZQ0xFX0dDDQorZXh0ZXJuIHZvaWQg > aW5pdGdjKCk7DQorI2VuZGlmDQogZXh0ZXJuIHZvaWQgaW5pdGltYWdlb3AoKTsNCiBleHRl > cm4gdm9pZCBpbml0bWF0aCgpOw0KIGV4dGVybiB2b2lkIGluaXRtZDUoKTsNCkBAIC04MCw2 > ICs4Myw5IEBADQogICAgICAgICB7ImJpbmFzY2lpIiwgaW5pdGJpbmFzY2lpfSwNCiAgICAg > ICAgIHsiY21hdGgiLCBpbml0Y21hdGh9LA0KICAgICAgICAgeyJlcnJubyIsIGluaXRlcnJu > b30sDQorI2lmZGVmIFdJVEhfQ1lDTEVfR0MNCisgICAgICAgIHsiZ2MiLCBpbml0Z2N9LA0K > KyNlbmRpZg0KICAgICAgICAgeyJpbWFnZW9wIiwgaW5pdGltYWdlb3B9LA0KICAgICAgICAg > eyJtYXRoIiwgaW5pdG1hdGh9LA0KICAgICAgICAgeyJtZDUiLCBpbml0bWQ1fSwNCi0tLSBQ > eXRob24tY3ZzL1BDL2NvbmZpZy5oCVRodSBNYXIgMzAgMjI6MDI6NTMgMjAwMA0KKysrIFB5 > dGhvbi1nYy9QQy9jb25maWcuaAlTYXQgQXByICA4IDAyOjI0OjAwIDIwMDANCkBAIC0zODEs > NiArMzgxLDkgQEANCiAvKiBEZWZpbmUgaWYgeW91IHdhbnQgdG8gdXNlIHRoZSBHTlUgcmVh > ZGxpbmUgbGlicmFyeSAqLw0KIC8qICNkZWZpbmUgV0lUSF9SRUFETElORSAxICovDQogDQor > LyogRGVmaW5lIGlmIHlvdSB3YW50IGN5Y2xlIGdhcmJhZ2UgY29sbGVjdGlvbiAqLw0KKyNk > ZWZpbmUgV0lUSF9DWUNMRV9HQyAxDQorDQogLyogRGVmaW5lIGlmIHlvdSBoYXZlIGNsb2Nr > LiAgKi8NCiAvKiAjZGVmaW5lIEhBVkVfQ0xPQ0sgKi8NCiANCi0tLSBQeXRob24tY3ZzL01h > a2VmaWxlLmluCVN1biBBcHIgIDIgMjI6NTY6MjUgMjAwMA0KKysrIFB5dGhvbi1nYy9NYWtl > ZmlsZS5pbglTYXQgQXByICA4IDAxOjM4OjI1IDIwMDANCkBAIC00MDEsNyArNDAxLDcgQEAN > CiAJCSQoSU5TVEFMTF9EQVRBKSBNb2R1bGVzL01ha2VmaWxlICQoTElCUEwpL01ha2VmaWxl > DQogCQkkKElOU1RBTExfREFUQSkgTW9kdWxlcy9TZXR1cCAkKExJQlBMKS9TZXR1cA0KIAkJ > JChJTlNUQUxMX0RBVEEpIE1vZHVsZXMvU2V0dXAubG9jYWwgJChMSUJQTCkvU2V0dXAubG9j > YWwNCi0JCSQoSU5TVEFMTF9EQVRBKSBNb2R1bGVzL1NldHVwLnRocmVhZCAkKExJQlBMKS9T > ZXR1cC50aHJlYWQNCisJCSQoSU5TVEFMTF9EQVRBKSBNb2R1bGVzL1NldHVwLmF1dG8gJChM > SUJQTCkvU2V0dXAuYXV0bw0KIAkJJChJTlNUQUxMX1BST0dSQU0pICQoc3JjZGlyKS9Nb2R1 > bGVzL21ha2VzZXR1cCAkKExJQlBMKS9tYWtlc2V0dXANCiAJCSQoSU5TVEFMTF9QUk9HUkFN > KSAkKHNyY2RpcikvaW5zdGFsbC1zaCAkKExJQlBMKS9pbnN0YWxsLXNoDQogCQkkKElOU1RB > TExfREFUQSkgJChzcmNkaXIpL01pc2MvTWFrZWZpbGUucHJlLmluICQoTElCUEwpL01ha2Vm > aWxlLnByZS5pbg0KLS0tIFB5dGhvbi1jdnMvY29uZmlnLmguaW4JRnJpIE1hciAyNCAyMjoz > MTo0MiAyMDAwDQorKysgUHl0aG9uLWdjL2NvbmZpZy5oLmluCVNhdCBBcHIgIDggMDE6Mzg6 > MjUgMjAwMA0KQEAgLTIwNCw2ICsyMDQsOSBAQA0KICAgIChzaGFyZWQgbGlicmFyeSBwbHVz > IGFjY2Vzc29yeSBmaWxlcykuICovDQogI3VuZGVmIFdJVEhfTkVYVF9GUkFNRVdPUksNCiAN > CisvKiBEZWZpbmUgaWYgeW91IHdhbnQgY3ljbGUgZ2FyYmFnZSBjb2xsZWN0aW9uICovDQor > I3VuZGVmIFdJVEhfQ1lDTEVfR0MNCisNCiAvKiBUaGUgbnVtYmVyIG9mIGJ5dGVzIGluIGFu > IG9mZl90LiAqLw0KICN1bmRlZiBTSVpFT0ZfT0ZGX1QNCiANCi0tLSBQeXRob24tY3ZzL2Nv > bmZpZ3VyZS5pbglTdW4gQXByICAyIDIyOjU2OjI1IDIwMDANCisrKyBQeXRob24tZ2MvY29u > ZmlndXJlLmluCVNhdCBBcHIgIDggMDE6Mzg6MjUgMjAwMA0KQEAgLTEwNjksMTAgKzEwNjks > MjEgQEANCiBmaV0sDQogW0FDX01TR19SRVNVTFQobm8pXSkNCiANCitBQ19TVUJTVChVU0Vf > R0NfTU9EVUxFKQ0KK1VTRV9HQ19NT0RVTEU9IiMiDQorDQorQUNfTVNHX0NIRUNLSU5HKGZv > ciAtLXdpdGgtY3ljbGUtZ2MpDQorQUNfQVJHX1dJVEgoY3ljbGUtZ2MsIFstLXdpdGgtY3lj > bGUtZ2MgICAgICAgICAgIGVuYWJsZSBnYXJiYWdlIGNvbGxlY3Rpb25dLCBbDQorQUNfTVNH > X1JFU1VMVCgkd2l0aHZhbCkNCitBQ19ERUZJTkUoV0lUSF9DWUNMRV9HQykNCitVU0VfR0Nf > TU9EVUxFPQ0KK10sDQorQUNfTVNHX1JFU1VMVChubykpDQorDQogIyBnZW5lcmF0ZSBvdXRw > dXQgZmlsZXMNCiBBQ19PVVRQVVQoTWFrZWZpbGUgXA0KICBPYmplY3RzL01ha2VmaWxlIFwN > CiAgUGFyc2VyL01ha2VmaWxlIFwNCiAgUHl0aG9uL01ha2VmaWxlIFwNCiAgTW9kdWxlcy9N > YWtlZmlsZS5wcmUgXA0KLSBNb2R1bGVzL1NldHVwLnRocmVhZCkNCisgTW9kdWxlcy9TZXR1 > cC5hdXRvKQ0KLS0tIFB5dGhvbi1jdnMvTWlzYy9NYWtlZmlsZS5wcmUuaW4JV2VkIERlYyAg > OSAxMDowNTozMyAxOTk4DQorKysgUHl0aG9uLWdjL01pc2MvTWFrZWZpbGUucHJlLmluCVNh > dCBBcHIgIDggMDE6Mzg6MjUgMjAwMA0KQEAgLTE2OCw3ICsxNjgsNyBAQA0KIE1BS0VGSUxF > PQkkKExJQlBMKS9NYWtlZmlsZQ0KIENPTkZJR0M9CSQoTElCUEwpL2NvbmZpZy5jDQogQ09O > RklHQ0lOPQkkKExJQlBMKS9jb25maWcuYy5pbg0KLVNFVFVQPQkJJChMSUJQTCkvU2V0dXAu > dGhyZWFkICQoTElCUEwpL1NldHVwLmxvY2FsICQoTElCUEwpL1NldHVwDQorU0VUVVA9CQkk > KExJQlBMKS9TZXR1cC5hdXRvICQoTElCUEwpL1NldHVwLmxvY2FsICQoTElCUEwpL1NldHVw > DQogDQogU1lTTElCUz0JJChMSUJNKSAkKExJQkMpDQogDQotLS0gUHl0aG9uLWN2cy9Nb2R1 > bGVzL01ha2VmaWxlLnByZS5pbglGcmkgTWFyIDI0IDIyOjMyOjI1IDIwMDANCisrKyBQeXRo > b24tZ2MvTW9kdWxlcy9NYWtlZmlsZS5wcmUuaW4JU2F0IEFwciAgOCAwMTozODoyNSAyMDAw > DQpAQCAtMTQ3LDEwICsxNDcsMTAgQEANCiAjIGdldHMgcmVtYWRlIGZyb20gc2NyYXRjaDsg > dGhpcyBlbnN1cmVzIHRvIHJlbW92ZSBtb2R1bGVzIHRoYXQgYXJlIG5vDQogIyBsb25nZXIg > cGVydGluZW50IChidXQgdGhhdCB3ZXJlIGluIGEgcHJldmlvdXMgY29uZmlndXJhdGlvbiku > DQogY29uZmlnLmMgTWFrZWZpbGU6IE1ha2VmaWxlLnByZSBjb25maWcuYy5pbiAkKE1BS0VT > RVRVUCkNCi1jb25maWcuYyBNYWtlZmlsZTogU2V0dXAudGhyZWFkIFNldHVwIFNldHVwLmxv > Y2FsDQorY29uZmlnLmMgTWFrZWZpbGU6IFNldHVwLmF1dG8gU2V0dXAgU2V0dXAubG9jYWwN > CiBjb25maWcuYyBNYWtlZmlsZToNCiAJCS1ybSAtZiAkKExJQlJBUlkpDQotCQkkKFNIRUxM > KSAkKE1BS0VTRVRVUCkgU2V0dXAudGhyZWFkIFNldHVwLmxvY2FsIFNldHVwDQorCQkkKFNI > RUxMKSAkKE1BS0VTRVRVUCkgU2V0dXAuYXV0byBTZXR1cC5sb2NhbCBTZXR1cA0KIA0KIGhh > c3NpZ25hbDoNCiAJCS1ybSAtZiBoYXNzaWduYWwNCi0tLSBQeXRob24tY3ZzL01vZHVsZXMv > U2V0dXAuaW4JU3VuIEFwciAgMiAyMjo1NjozNyAyMDAwDQorKysgUHl0aG9uLWdjL01vZHVs > ZXMvU2V0dXAuaW4JU2F0IEFwciAgOCAwMTozODoyNSAyMDAwDQpAQCAtMTAwLDcgKzEwMCw3 > IEBADQogR0xIQUNLPS1EY2xlYXI9X19HTGNsZWFyDQogI2dsIGdsbW9kdWxlLmMgY2dlbnN1 > cHBvcnQuYyAtSSQoc3JjZGlyKSAkKEdMSEFDSykgLWxnbCAtbFgxMQ0KIA0KLSMgVGhlIHRo > cmVhZCBtb2R1bGUgaXMgbm93IGF1dG9tYXRpY2FsbHkgZW5hYmxlZCwgc2VlIFNldHVwLnRo > cmVhZC4NCisjIFRoZSB0aHJlYWQgbW9kdWxlIGlzIG5vdyBhdXRvbWF0aWNhbGx5IGVuYWJs > ZWQsIHNlZSBTZXR1cC5hdXRvLg0KIA0KICMgUHVyZSBtb2R1bGUuICBDYW5ub3QgYmUgbGlu > a2VkIGR5bmFtaWNhbGx5Lg0KICMgLURXSVRIX1FVQU5USUZZLCAtRFdJVEhfUFVSSUZZLCBv > ciAtRFdJVEhfQUxMX1BVUkUNCi0tLSBQeXRob24tY3ZzL01vZHVsZXMvU2V0dXAuYXV0by5p > bg0KKysrIFB5dGhvbi1nYy9Nb2R1bGVzL1NldHVwLmF1dG8uaW4JU2F0IEFwciAgOCAwMToz > ODoyNSAyMDAwDQpAQCAtMCwwICsxLDE2IEBADQorIyBUaGlzIGZpbGUgaXMgdHJhbnNtb2dy > aWZpZWQgaW50byBTZXR1cC5hdXRvIGJ5IGNvbmZpZy5zdGF0dXMuICBJdHMNCisjIHB1cnBv > c2UgaXMgdG8gYXV0b21hdGljYWxseSBlbmFibGUgbW9kdWxlcyBnaXZlbiB3aGVuIGNlcnRh > aW4NCisjIGFyZ3VtZW50cyBhcmUgZ2l2ZW4gdG8gdGhlIGNvbmZpZ3VyZSBzY3JpcHQuICBJ > dCByZXBsYWNlcyB0aGUgb2xkDQorIyBTZXR1cC50aHJlYWQuaW4gZmlsZS4NCisNCisjIElu > Y2x1ZGUgdGhlIHRocmVhZCBtb2R1bGUgd2hlbiB0aGUgLS13aXRoLXRocmVhZCBhcmd1bWVu > dCBpcyBnaXZlbiB0bw0KKyMgdGhlIGNvbmZpZ3VyZSBzY3JpcHQuDQorIw0KKyMgKk5PVEUq > OiBpZiB0aGUgY29uZmlndXJlIHNjcmlwdCBkZWNpZGVzIGl0IGNhbid0IHN1cHBvcnQgdGhy > ZWFkcywgdGhlDQorIyB0aHJlYWQgbW9kdWxlIHdpbGwgc3RpbGwgYmUgZW5hYmxlZCBhbmQg > Y2F1c2UgY29tcGlsZSBlcnJvcnMuICBUaGUNCisjIHNvbHV0aW9uIGlzIG5vdCB0byB1c2Ug > LS13aXRoLXRocmVhZCBvbiBwbGF0Zm9ybXMgdGhhdCBkb24ndCBzdXBwb3J0DQorIyB0aHJl > YWRzLg0KK0BVU0VfVEhSRUFEX01PRFVMRUB0aHJlYWQgdGhyZWFkbW9kdWxlLmMNCisNCisj > IEdhcmJhZ2UgY29sbGVjdGlvbiBlbmFibGVkIHdpdGggLS13aXRoLWN5Y2xlLWdjDQorQFVT > RV9HQ19NT0RVTEVAZ2MgZ2Ntb2R1bGUuYw0KLS0tIFB5dGhvbi1jdnMvTGliL3Rlc3QvdGVz > dF9nYy5weQ0KKysrIFB5dGhvbi1nYy9MaWIvdGVzdC90ZXN0X2djLnB5CVNhdCBBcHIgIDgg > MDM6MjU6MjUgMjAwMA0KQEAgLTAsMCArMSw5MCBAQA0KK2ltcG9ydCBnYw0KKw0KK2RlZiB0 > ZXN0X2xpc3QoKToNCisgICAgbCA9IFtdDQorICAgIGwuYXBwZW5kKGwpDQorICAgIHByaW50 > ICdsaXN0IDB4JXgnICUgaWQobCkNCisgICAgZ2MuY29sbGVjdCgpDQorICAgIGRlbCBsDQor > ICAgIGFzc2VydCBnYy5jb2xsZWN0KCkgPT0gMQ0KKw0KK2RlZiB0ZXN0X2RpY3QoKToNCisg > ICAgZCA9IHt9DQorICAgIGRbMV0gPSBkDQorICAgIHByaW50ICdkaWN0IDB4JXgnICUgaWQo > ZCkNCisgICAgZ2MuY29sbGVjdCgpDQorICAgIGRlbCBkDQorICAgIGFzc2VydCBnYy5jb2xs > ZWN0KCkgPT0gMQ0KKw0KK2RlZiB0ZXN0X3R1cGxlKCk6DQorICAgIGwgPSBbXQ0KKyAgICB0 > ID0gKGwsKQ0KKyAgICBsLmFwcGVuZCh0KQ0KKyAgICBwcmludCAnbGlzdCAweCV4JyAlIGlk > KGwpDQorICAgIHByaW50ICd0dXBsZSAweCV4JyAlIGlkKHQpDQorICAgIGdjLmNvbGxlY3Qo > KQ0KKyAgICBkZWwgdA0KKyAgICBkZWwgbA0KKyAgICBhc3NlcnQgZ2MuY29sbGVjdCgpID09 > IDINCisNCitkZWYgdGVzdF9jbGFzcygpOg0KKyAgICBjbGFzcyBBOg0KKyAgICAgICAgcGFz > cw0KKyAgICBBLmEgPSBBDQorICAgIHByaW50ICdjbGFzcyAweCV4JyAlIGlkKEEpDQorICAg > IGdjLmNvbGxlY3QoKQ0KKyAgICBkZWwgQQ0KKyAgICBhc3NlcnQgZ2MuY29sbGVjdCgpID09 > IDINCisNCitkZWYgdGVzdF9pbnN0YW5jZSgpOg0KKyAgICBjbGFzcyBBOg0KKyAgICAgICAg > cGFzcw0KKyAgICBhID0gQSgpDQorICAgIGEuYSA9IGENCisgICAgcHJpbnQgcmVwcihhKQ0K > KyAgICBnYy5jb2xsZWN0KCkNCisgICAgZGVsIGENCisgICAgYXNzZXJ0IGdjLmNvbGxlY3Qo > KSA9PSAyDQorDQorZGVmIHRlc3RfZmluYWxpemVyKCk6DQorICAgIGNsYXNzIEE6DQorICAg > ICAgICBkZWYgX19kZWxfXyhzZWxmKTogcGFzcw0KKyAgICBjbGFzcyBCOg0KKyAgICAgICAg > cGFzcw0KKyAgICBhID0gQSgpDQorICAgIGEuYSA9IGENCisgICAgaWRfYSA9IGlkKGEpDQor > ICAgIGIgPSBCKCkNCisgICAgYi5iID0gYg0KKyAgICBwcmludCAnYScsIHJlcHIoYSkNCisg > ICAgcHJpbnQgJ2InLCByZXByKGIpDQorICAgIGdjLmNvbGxlY3QoKQ0KKyAgICBnYy5nYXJi > YWdlWzpdID0gW10NCisgICAgZGVsIGENCisgICAgZGVsIGINCisgICAgYXNzZXJ0IGdjLmNv > bGxlY3QoKSA9PSA0DQorICAgIGFzc2VydCBpZChnYy5nYXJiYWdlWzBdKSA9PSBpZF9hDQor > DQorZGVmIHRlc3RfZnVuY3Rpb24oKToNCisgICAgZCA9IHt9DQorICAgIGV4ZWMoImRlZiBm > KCk6IHBhc3NcbiIpIGluIGQNCisgICAgcHJpbnQgJ2RpY3QgMHgleCcgJSBpZChkKQ0KKyAg > ICBwcmludCAnZnVuYyAweCV4JyAlIGlkKGRbJ2YnXSkNCisgICAgZ2MuY29sbGVjdCgpDQor > ICAgIGRlbCBkDQorICAgIGFzc2VydCBnYy5jb2xsZWN0KCkgPT0gMg0KKw0KKw0KK2RlZiB0 > ZXN0X2FsbCgpOg0KKyAgICBkZWJ1ZyA9IGdjLmdldF9kZWJ1ZygpDQorICAgIGdjLnNldF9k > ZWJ1ZyhnYy5ERUJVR19MRUFLIHwgZ2MuREVCVUdfU1RBVFMpDQorICAgIHRlc3RfbGlzdCgp > DQorICAgIHRlc3RfZGljdCgpDQorICAgIHRlc3RfdHVwbGUoKQ0KKyAgICB0ZXN0X2NsYXNz > KCkNCisgICAgdGVzdF9pbnN0YW5jZSgpDQorICAgIHRlc3RfZmluYWxpemVyKCkNCisgICAg > dGVzdF9mdW5jdGlvbigpDQorICAgIGdjLnNldF9kZWJ1ZyhkZWJ1ZykNCisNCit0ZXN0X2Fs > bCgpDQotLS0gUHl0aG9uLWN2cy9QQ2J1aWxkL3B5dGhvbjE2LmRzcAlGcmkgQXByICA3IDE1 > OjI3OjA0IDIwMDANCisrKyBQeXRob24tZ2MvUENidWlsZC9weXRob24xNi5kc3AJU2F0IEFw > ciAgOCAwMjoyMjo0OCAyMDAwDQpAQCAtNjQ1LDYgKzY0NSwyMSBAQA0KICMgRW5kIFNvdXJj > ZSBGaWxlDQ0KICMgQmVnaW4gU291cmNlIEZpbGUNDQogDQ0KK1NPVVJDRT0uLlxNb2R1bGVz > XGdjbW9kdWxlLmMNDQorDQ0KKyFJRiAgIiQoQ0ZHKSIgPT0gInB5dGhvbjE2IC0gV2luMzIg > UmVsZWFzZSINDQorDQ0KKyFFTFNFSUYgICIkKENGRykiID09ICJweXRob24xNiAtIFdpbjMy > IERlYnVnIg0NCisNDQorIUVMU0VJRiAgIiQoQ0ZHKSIgPT0gInB5dGhvbjE2IC0gV2luMzIg > QWxwaGEgRGVidWciDQ0KKw0NCishRUxTRUlGICAiJChDRkcpIiA9PSAicHl0aG9uMTYgLSBX > aW4zMiBBbHBoYSBSZWxlYXNlIg0NCisNDQorIUVORElGIA0NCisNDQorIyBFbmQgU291cmNl > IEZpbGUNDQorIyBCZWdpbiBTb3VyY2UgRmlsZQ0NCisNDQogU09VUkNFPS4uXFB5dGhvblxn > ZXRhcmdzLmMNDQogDQ0KICFJRiAgIiQoQ0ZHKSIgPT0gInB5dGhvbjE2IC0gV2luMzIgUmVs > ZWFzZSIN > > > > > --__--__-- > > _______________________________________________ > Patches mailing list > Patches@python.org > http://www.python.org/mailman/listinfo/patches > > > End of Patches Digest_______________________________________________ > Patches mailing list > Patches@python.org > http://www.python.org/mailman/listinfo/patches From nascheme@enme.ucalgary.ca Tue Apr 25 17:58:29 2000 From: nascheme@enme.ucalgary.ca (Neil Schemenauer) Date: Tue, 25 Apr 2000 10:58:29 -0600 Subject: [Patches] why not just apply Garbage Collection patch? In-Reply-To: <14596.41644.182242.918286@buffalo.fnal.gov>; from cgw@fnal.gov on Mon, Apr 24, 2000 at 02:38:20PM -0500 References: <14596.41644.182242.918286@buffalo.fnal.gov> Message-ID: <20000425105829.A27743@acs.ucalgary.ca> On Mon, Apr 24, 2000 at 02:38:20PM -0500, Charles G Waldman wrote: > Unfortunately, with my recent changes to tupleobject.c and Christian's > recent changes to the Trashcan, the gc patch no longer applies > cleanly I'll fix that today. > Everything is already protected with "#ifdef > WITH_CYCLE_GC" anyhow, right? Unfortunately not. I had to change the way objects are allocated in order to make GC Python binary compatible with GC-disabled Python. PyObject_NEW* cannot be macros which expand to malloc() (which they do currently on Windows). GC Python must allocate extra memory for container objects. I think Vladimir's malloc patch will fix this problem. Either his patch should be applied first or at least the part that makes this change. Neil -- "God, root, what is difference?" - Pitr "God is more forgiving." - Dave Aronson From nascheme@enme.ucalgary.ca Tue Apr 25 18:05:06 2000 From: nascheme@enme.ucalgary.ca (Neil Schemenauer) Date: Tue, 25 Apr 2000 11:05:06 -0600 Subject: [Patches] why not just apply Garbage Collection patch? In-Reply-To: <200004242013.QAA29938@eric.cnri.reston.va.us>; from guido@python.org on Mon, Apr 24, 2000 at 04:13:08PM -0400 References: <14596.41644.182242.918286@buffalo.fnal.gov> <200004242013.QAA29938@eric.cnri.reston.va.us> Message-ID: <20000425110506.B27743@acs.ucalgary.ca> On Mon, Apr 24, 2000 at 04:13:08PM -0400, Guido van Rossum wrote: > Thanks. I haven't looked at it lately. What do you think of binary > compatibility? Could an extension built before this was patched in > get in trouble because of changed object lay-out? Yes. The way PyObject_NEW works on Windows is a problem. > Plus, I owe Vladimir Marangozov a green light to generate a new > version of his memory management patches; that will also interfere > with the GC patches (and make a few things easier, I believe). > Vladimir's patches should preferably be applied before Neil's. Yes. Vladimir can then get the blame for breaking already compiled extensions. :) Neil -- "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off." -- Bjarne Stroustrup, Inventor of C++ From cgw@fnal.gov Tue Apr 25 20:17:26 2000 From: cgw@fnal.gov (Charles G Waldman) Date: Tue, 25 Apr 2000 14:17:26 -0500 Subject: [Patches] Trashcan vs. GC vs. TRACE_REFS Message-ID: <200004251917.OAA20467@buffalo.fnal.gov> Hi Christian et al. Well, I said there was nothing wrong with Trashcan, but I spoke a little too soon ;-) With the current gc-cycle patch and Py_TRACE_REFS set, we get a core dump. The culprit is this little piece of code in object.c void _Py_Dealloc(op) PyObject *op; { destructor dealloc = op->ob_type->tp_dealloc; _Py_ForgetReference(op); *** if (_PyTrash_delete_nesting < PyTrash_UNWIND_LEVEL-1) *** op->ob_type = NULL; (*dealloc)(op); } I'd really love to understand what those lines marked "***" are for. If you set ob_type to NULL before doing a dealloc, you get into trouble, because the new GC dealloc functions need to check ob_type to decide if the object being deleted has GC info. By setting type to NULL you are breaking this. But what really seems odd to me is that the _Py_Dealloc function above is only used when Py_TRACE_REFS is set. Normally the following macro definition is used instead (see object.h) ifndef Py_TRACE_REFS ... #define _Py_Dealloc(op) (*(op)->ob_type->tp_dealloc)((PyObject *)(op)) ... #endif /* !Py_TRACE_REFS */ So, what is the point of worrying about _PyTrash_UNWIND_LEVEL only in a function which is only used in special builds? If this is really important, I'd think you'd be doing it in the _Py_Dealloc macro as well. But, of course, you can't be clobbering ob_type at all, because the gc dealloc functions *need* that ob_type. As far as I can tell, building with Py_TRACE_REFS is not too widely done. But I'm finding it incredibly useful for tracking down those reference leaks which still remain even with Neil's GC patches in place. From tismer@tismer.com Tue Apr 25 20:35:26 2000 From: tismer@tismer.com (Christian Tismer) Date: Tue, 25 Apr 2000 21:35:26 +0200 Subject: [Patches] Re: Trashcan vs. GC vs. TRACE_REFS References: <200004251917.OAA20467@buffalo.fnal.gov> Message-ID: <3905F37E.3DB3AA9B@tismer.com> Charles G Waldman wrote: > > Hi Christian et al. > > Well, I said there was nothing wrong with Trashcan, but I spoke a > little too soon ;-) > > With the current gc-cycle patch and Py_TRACE_REFS set, we get a core > dump. Ok, that may be. I just inserted what's needed to make MHammond happy when debugging. Maybe we need some more. (But I'm glad that it doesn't crash in the release build!) ((ha, even more glad: It isn't my error at all. hee hee)) > The culprit is this little piece of code in object.c > > void > _Py_Dealloc(op) > PyObject *op; > { > destructor dealloc = op->ob_type->tp_dealloc; > _Py_ForgetReference(op); > *** if (_PyTrash_delete_nesting < PyTrash_UNWIND_LEVEL-1) > *** op->ob_type = NULL; > (*dealloc)(op); > } > > I'd really love to understand what those lines marked "***" are for. This is so: Guido wipes the type field, in order to provoke a core dump when you are using a dead object. The code looked before like so: > void > _Py_Dealloc(op) > PyObject *op; > { > destructor dealloc = op->ob_type->tp_dealloc; > _Py_ForgetReference(op); > op->ob_type = NULL; > (*dealloc)(op); > } That means, Neil's code would crash anyway in this mode. What I do here is: I allow to wipe the type field if and only if I'm sure that I don't need it. This is on final destruction, which will happen only if _PyTrash_delete_nesting < PyTrash_UNWIND_LEVEL-1 . > If you set ob_type to NULL before doing a dealloc, you get into > trouble, because the new GC dealloc functions need to check ob_type to > decide if the object being deleted has GC info. By setting type to > NULL you are breaking this. Agreed, but it's not me. I guess we should remove this piece of code for Neil, let's embrace it in a #ifdef. > But what really seems odd to me is that the _Py_Dealloc function above > is only used when Py_TRACE_REFS is set. Normally the following macro > definition is used instead (see object.h) > > ifndef Py_TRACE_REFS > ... > #define _Py_Dealloc(op) (*(op)->ob_type->tp_dealloc)((PyObject *)(op)) > ... > #endif /* !Py_TRACE_REFS */ > > So, what is the point of worrying about _PyTrash_UNWIND_LEVEL only in > a function which is only used in special builds? If this is really > important, I'd think you'd be doing it in the _Py_Dealloc macro as > well. But, of course, you can't be clobbering ob_type at all, because > the gc dealloc functions *need* that ob_type. It is only there to allow Guido (or whoever wrote this debug piece) to allow to clear the type if it doesn't hurt *me*. When I have to delay destruction, I must have the type alive. Neil probably needs it always? > As far as I can tell, building with Py_TRACE_REFS is not too widely > done. But I'm finding it incredibly useful for tracking down those > reference leaks which still remain even with Neil's GC patches in > place. Ok, all clear now? Well, my lovely little trashcan pet is really strong. Brave pet, brave pet :-)) ciao - chris -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaunstr. 26 : *Starship* http://starship.python.net 14163 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF where do you want to jump today? http://www.stackless.com From tismer@tismer.com Tue Apr 25 20:47:40 2000 From: tismer@tismer.com (Christian Tismer) Date: Tue, 25 Apr 2000 21:47:40 +0200 Subject: [Patches] Re: Trashcan vs. GC vs. TRACE_REFS References: <200004251917.OAA20467@buffalo.fnal.gov> <3905F37E.3DB3AA9B@tismer.com> Message-ID: <3905F65C.873B0B26@tismer.com> One more on this: If ob_type has to be cleared when tracing refs, and if Neil's code is touching the object the last time, shouldn't he then clear the type, right before the thing gets doomed into the everblacks? The situation is a bit hairy: We cannot do it after the dealloc is done. I tried that before, but I crashed, since after the dealloc the memory might already be in use again, as a side effect of the debug code. That means: We need to decide here wether the thingy will go through Neil's code, and then also not clear the type. Quit bad, this needs another if..else if.. cascade to check the type. Guido? How urgent do you think is to wipe the type code? It seems to become a hair with GC. ciao - chris -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaunstr. 26 : *Starship* http://starship.python.net 14163 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF where do you want to jump today? http://www.stackless.com From brian@garage.co.jp Tue Apr 25 21:37:31 2000 From: brian@garage.co.jp (Brian Hooper) Date: Tue, 25 Apr 2000 20:37:31 GMT Subject: [Patches] slightly expanded Unicode supported Py_BuildValue Message-ID: <20000425203731.80051.qmail@hotmail.com> This is a multi-part message in MIME format. ------=_NextPart_000_119635c0_742cd712$5a06bf89 Content-Type: text/plain; format=flowed Hi again, Here's a patch which changes modsupport to add 'U' and 'U#', to support building Unicode objects from a null-terminated Py_UNICODE *, and a Py_UNICODE * with length, respectively. If this is acceptable, then I'll submit a patch for the corresponding documentation also. --Brian I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. ________________________________________________________________________ Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com ------=_NextPart_000_119635c0_742cd712$5a06bf89 Content-Type: application/x-unknown-content-type-Excel.DIF; name="Modsupport2.diff.dif" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="Modsupport2.diff.dif" KioqIFB5dGhvbi5vbGQvbW9kc3VwcG9ydC5jCU1vbiBKYW4gMjUgMTM6NDg6 NTYgMTk5OQotLS0gUHl0aG9uL21vZHN1cHBvcnQuYwlUdWUgQXByIDI1IDEy OjIyOjE2IDIwMDAKKioqKioqKioqKioqKioqCioqKiAyMzIsMjM3ICoqKioK LS0tIDIzMiwyNDUgLS0tLQogIAlyZXR1cm4gdjsKICB9CiAgCisgc3RhdGlj IGludAorIF91c3RybGVuKFB5X1VOSUNPREUgKnUpIHsKKyAJaW50IGkgPSAw OworIAlQeV9VTklDT0RFICp2ID0gdTsKKyAJd2hpbGUgKCp2ICE9IDApIHsg aSsrOyB2Kys7IH0gCisgCXJldHVybiBpOworIH0KKyAgCiAgc3RhdGljIFB5 T2JqZWN0ICoKICBkb19ta3R1cGxlKHBfZm9ybWF0LCBwX3ZhLCBlbmRjaGFy LCBuKQogIAljaGFyICoqcF9mb3JtYXQ7CioqKioqKioqKioqKioqKgoqKiog Mjk1LDMwMSAqKioqCiAgCQljYXNlICdMJzoKICAJCQlyZXR1cm4gUHlMb25n X0Zyb21Mb25nTG9uZygoTE9OR19MT05HKXZhX2FyZygqcF92YSwgTE9OR19M T05HKSk7CiAgI2VuZGlmCiEgCiAgCQljYXNlICdmJzoKICAJCWNhc2UgJ2Qn OgogIAkJCXJldHVybiBQeUZsb2F0X0Zyb21Eb3VibGUoCi0tLSAzMDMsMzMw IC0tLS0KICAJCWNhc2UgJ0wnOgogIAkJCXJldHVybiBQeUxvbmdfRnJvbUxv bmdMb25nKChMT05HX0xPTkcpdmFfYXJnKCpwX3ZhLCBMT05HX0xPTkcpKTsK ICAjZW5kaWYKISAJCWNhc2UgJ1UnOgohIAkJewohIAkJCVB5T2JqZWN0ICp2 OwohIAkJCVB5X1VOSUNPREUgKnUgPSB2YV9hcmcoKnBfdmEsIFB5X1VOSUNP REUgKik7CiEgCQkJaW50IG47CiEgCQkJaWYgKCoqcF9mb3JtYXQgPT0gJyMn KSB7CiEgCQkJCSsrKnBfZm9ybWF0OwohIAkJCQluID0gdmFfYXJnKCpwX3Zh LCBpbnQpOwohIAkJCX0KISAJCQllbHNlCiEgCQkJCW4gPSAtMTsKISAJCQlp ZiAodSA9PSBOVUxMKSB7CiEgCQkJCXYgPSBQeV9Ob25lOwohIAkJCQlQeV9J TkNSRUYodik7CiEgCQkJfQohIAkJCWVsc2UgewohIAkJCQlpZiAobiA8IDAp CiEgCQkJCQluID0gX3VzdHJsZW4odSk7CiEgCQkJCXYgPSBQeVVuaWNvZGVf RnJvbVVuaWNvZGUodSwgbik7CiEgCQkJfQohIAkJCXJldHVybiB2OwohIAkJ fQogIAkJY2FzZSAnZic6CiAgCQljYXNlICdkJzoKICAJCQlyZXR1cm4gUHlG bG9hdF9Gcm9tRG91YmxlKAo= ------=_NextPart_000_119635c0_742cd712$5a06bf89-- From cgw@fnal.gov Tue Apr 25 22:32:17 2000 From: cgw@fnal.gov (Charles G Waldman) Date: Tue, 25 Apr 2000 16:32:17 -0500 (CDT) Subject: [Patches] tiny patch for socketmodule.c Message-ID: <14598.3809.919559.931801@buffalo.fnal.gov> This patch does two things: 1) Adds MSG_DONTWAIT if defined (I needed this) 2) Spells "coreectly" correctly ;-) Disclaimer: http://www.python.org/patches/bugrelease.html Index: Modules/socketmodule.c =================================================================== RCS file: /projects/cvsroot/python/dist/src/Modules/socketmodule.c,v retrieving revision 1.104 diff -c -r1.104 socketmodule.c *** socketmodule.c 2000/04/24 15:16:03 1.104 --- socketmodule.c 2000/04/25 21:30:55 *************** *** 524,530 **** } #ifdef __BEOS__ ! /* XXX: BeOS version of accept() doesn't set family coreectly */ addr->sa_family = AF_INET; #endif --- 524,530 ---- } #ifdef __BEOS__ ! /* XXX: BeOS version of accept() doesn't set family correctly */ addr->sa_family = AF_INET; #endif *************** *** 2525,2530 **** --- 2525,2533 ---- #endif #ifdef MSG_DONTROUTE insint(d, "MSG_DONTROUTE", MSG_DONTROUTE); + #endif + #ifdef MSG_DONTWAIT + insint(d, "MSG_DONWAIT", MSG_DONTWAIT); #endif #ifdef MSG_EOR insint(d, "MSG_EOR", MSG_EOR); From guido@python.org Tue Apr 25 22:57:03 2000 From: guido@python.org (Guido van Rossum) Date: Tue, 25 Apr 2000 17:57:03 -0400 Subject: [Patches] Re: Trashcan vs. GC vs. TRACE_REFS In-Reply-To: Your message of "Tue, 25 Apr 2000 21:47:40 +0200." <3905F65C.873B0B26@tismer.com> References: <200004251917.OAA20467@buffalo.fnal.gov> <3905F37E.3DB3AA9B@tismer.com> <3905F65C.873B0B26@tismer.com> Message-ID: <200004252157.RAA02365@eric.cnri.reston.va.us> > Guido? How urgent do you think is to wipe the > type code? It seems to become a hair with GC. I'll deal with GC later. I think it's an important debugging feature since it traps any use of the object after it has been deallocated immediately. --Guido van Rossum (home page: http://www.python.org/~guido/) From skip@mojam.com (Skip Montanaro) Tue Apr 25 23:02:36 2000 From: skip@mojam.com (Skip Montanaro) (Skip Montanaro) Date: Tue, 25 Apr 2000 17:02:36 -0500 (CDT) Subject: [Patches] Re: Trashcan vs. GC vs. TRACE_REFS In-Reply-To: <200004252157.RAA02365@eric.cnri.reston.va.us> References: <200004251917.OAA20467@buffalo.fnal.gov> <3905F37E.3DB3AA9B@tismer.com> <3905F65C.873B0B26@tismer.com> <200004252157.RAA02365@eric.cnri.reston.va.us> Message-ID: <14598.5628.536367.666435@beluga.mojam.com> >> Guido? How urgent do you think is to wipe the type code? It seems to >> become a hair with GC. Guido> I'll deal with GC later. I think it's an important debugging Guido> feature since it traps any use of the object after it has been Guido> deallocated immediately. Isn't this a problem because the ob_type field is effectively being used for two competing purposes (I haven't been following *real* closely for fear of someone slamming on the brakes...)? Is there some way to split those two functions into two separate fields, at least when Py_TRACE_REFS is defined? -- Skip Montanaro | http://www.mojam.com/ skip@mojam.com | http://www.musi-cal.com/ From gstein@lyra.org Tue Apr 25 23:14:29 2000 From: gstein@lyra.org (Greg Stein) Date: Tue, 25 Apr 2000 15:14:29 -0700 (PDT) Subject: [Patches] tiny patch for socketmodule.c In-Reply-To: <14598.3809.919559.931801@buffalo.fnal.gov> Message-ID: On Tue, 25 Apr 2000, Charles G Waldman wrote: >... > *** 2525,2530 **** > --- 2525,2533 ---- > #endif > #ifdef MSG_DONTROUTE > insint(d, "MSG_DONTROUTE", MSG_DONTROUTE); > + #endif > + #ifdef MSG_DONTWAIT > + insint(d, "MSG_DONWAIT", MSG_DONTWAIT); > #endif > #ifdef MSG_EOR > insint(d, "MSG_EOR", MSG_EOR); You may want to spell the Python symbol correctly... :-) -- Greg Stein, http://www.lyra.org/ From cgw@fnal.gov Tue Apr 25 23:09:28 2000 From: cgw@fnal.gov (Charles G Waldman) Date: Tue, 25 Apr 2000 17:09:28 -0500 (CDT) Subject: [Patches] tiny patch for socketmodule.c In-Reply-To: References: <14598.3809.919559.931801@buffalo.fnal.gov> Message-ID: <14598.6040.389251.942676@buffalo.fnal.gov> Greg Stein writes: > > You may want to spell the Python symbol correctly... > > :-) Geez, I feel stupid!!! From mal@lemburg.com Tue Apr 25 23:16:02 2000 From: mal@lemburg.com (M.-A. Lemburg) Date: Wed, 26 Apr 2000 00:16:02 +0200 Subject: [Patches] slightly expanded Unicode supported Py_BuildValue References: <20000425203731.80051.qmail@hotmail.com> Message-ID: <39061922.F627F85D@lemburg.com> Brian Hooper wrote: > > Hi again, > > Here's a patch which changes modsupport to add 'U' and 'U#', > to support building Unicode objects from a null-terminated > Py_UNICODE *, and a Py_UNICODE * with length, respectively. If you would change the 'U' (capital U) to 'u' (lowercase u) the patch would be perfect :-) BTW, why do you support converting a NULL pointer to None ? I think this would probably only mask programming errors instead of doing any good. > If this is acceptable, then I'll submit a patch for the > corresponding documentation also. >--- > Name: Modsupport2.diff.dif > Modsupport2.diff.dif Type: application/x-unknown-content-type-Excel.DIF > Encoding: base64 Your mailer seems to have gotten the content type wrong; I'd suggest to use .patch as extension for the file. -- Marc-Andre Lemburg ______________________________________________________________________ Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ From nascheme@enme.ucalgary.ca Wed Apr 26 02:03:10 2000 From: nascheme@enme.ucalgary.ca (Neil Schemenauer) Date: Tue, 25 Apr 2000 19:03:10 -0600 Subject: [Patches] Re: Trashcan vs. GC vs. TRACE_REFS In-Reply-To: <200004252157.RAA02365@eric.cnri.reston.va.us>; from guido@python.org on Tue, Apr 25, 2000 at 05:57:03PM -0400 References: <200004251917.OAA20467@buffalo.fnal.gov> <3905F37E.3DB3AA9B@tismer.com> <3905F65C.873B0B26@tismer.com> <200004252157.RAA02365@eric.cnri.reston.va.us> Message-ID: <20000425190310.B25863@acs.ucalgary.ca> On Tue, Apr 25, 2000 at 05:57:03PM -0400, Guido van Rossum wrote: > I think it's an important debugging feature since it traps any > use of the object after it has been deallocated immediately. That feature works with GC now. I have changed my patch to minimize the impact on the rest of the Python code. Almost all the details are now hidden in the gc module. I no longer need Vladimir's malloc cleanup to be applied first. The patch is here: http://www.enme.ucalgary.ca/~nascheme/python/gc-cycle.diff Guido, when you talk about not breaking extension modules what exactly do you mean? With my current patch, extension types that are involved with GC must match the interpreter (GC vs. no-GC). Other extensions do not have to be recompiled (even ones compiled before applying the patch). Is this sufficient? If not, it is possible to fix it so extensions that implement GC will be okay too. Neil From mhammond@skippinet.com.au Wed Apr 26 02:39:00 2000 From: mhammond@skippinet.com.au (Mark Hammond) Date: Wed, 26 Apr 2000 11:39:00 +1000 Subject: [Patches] Re: Trashcan vs. GC vs. TRACE_REFS In-Reply-To: <20000425190310.B25863@acs.ucalgary.ca> Message-ID: > With my current patch, extension types that > are involved with GC must match the interpreter (GC vs. no-GC). What exactly does "involved in" mean? (Obviously, I havent looked at = the patches). Must an extension module actually "opt in" for GC, or do = a module's inherent properties (eg, implements a new extension type) = force it to become involved? > Is this sufficient? If not, it is possible to fix it so=20 > extensions > that implement GC will be okay too. That would certainly be ideal, especially on Windows where people often = dont have the tools to build all their own binaries. It would certainly = help people on Windows experiment with this feature if they did not have = to rebuild their world (or even parts of their world) to use it. But I guess its importance (to me) will be determined by the answer to = my first question... Mark. From nascheme@enme.ucalgary.ca Wed Apr 26 02:52:20 2000 From: nascheme@enme.ucalgary.ca (Neil Schemenauer) Date: Tue, 25 Apr 2000 19:52:20 -0600 Subject: [Patches] Re: Trashcan vs. GC vs. TRACE_REFS In-Reply-To: ; from mhammond@skippinet.com.au on Wed, Apr 26, 2000 at 11:39:00AM +1000 References: <20000425190310.B25863@acs.ucalgary.ca> Message-ID: <20000425195220.A26364@acs.ucalgary.ca> On Wed, Apr 26, 2000 at 11:39:00AM +1000, Mark Hammond wrote: > > With my current patch, extension types that > > are involved with GC must match the interpreter (GC vs. no-GC). > > What exactly does "involved in" mean? Extension types that can create reference cycles and want to support GC. There are currently none of these unless someone quickly implemented one. > > Is this sufficient? If not, it is possible to fix it so > > extensions that implement GC will be okay too. > > That would certainly be ideal, especially on Windows where > people often dont have the tools to build all their own > binaries. It would certainly help people on Windows experiment > with this feature if they did not have to rebuild their world > (or even parts of their world) to use it. To achieve this, GC-disabled Python would have to be a little slower than current Python (some extra function calls). With my current patch they should be very nearly the same speed. Neil -- Real Life? I played that game. The plot sucks but the graphics are awesome. From tismer@tismer.com Wed Apr 26 01:56:32 2000 From: tismer@tismer.com (Christian Tismer) Date: Wed, 26 Apr 2000 02:56:32 +0200 Subject: [Patches] Re: Trashcan vs. GC vs. TRACE_REFS References: <200004251917.OAA20467@buffalo.fnal.gov> <3905F37E.3DB3AA9B@tismer.com> <3905F65C.873B0B26@tismer.com> <200004252157.RAA02365@eric.cnri.reston.va.us> <20000425190310.B25863@acs.ucalgary.ca> Message-ID: <39063EC0.23174B81@tismer.com> Neil Schemenauer wrote: > Guido, when you talk about not breaking extension modules what > exactly do you mean? I guess he is meaning this: Does an extension have to be recompiled for your GC. > With my current patch, extension types that > are involved with GC must match the interpreter (GC vs. no-GC). > Other extensions do not have to be recompiled (even ones compiled > before applying the patch). That's important -- I can replace python16.dll, and the win32 extensions will not break -- ok? ciao - chris -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaunstr. 26 : *Starship* http://starship.python.net 14163 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF where do you want to jump today? http://www.stackless.com From mhammond@skippinet.com.au Wed Apr 26 02:56:59 2000 From: mhammond@skippinet.com.au (Mark Hammond) Date: Wed, 26 Apr 2000 11:56:59 +1000 Subject: [Patches] Re: Trashcan vs. GC vs. TRACE_REFS In-Reply-To: <20000425195220.A26364@acs.ucalgary.ca> Message-ID: > On Wed, Apr 26, 2000 at 11:39:00AM +1000, Mark Hammond wrote: > > > With my current patch, extension types that > > > are involved with GC must match the interpreter (GC=20 > vs. no-GC). > >=20 > > What exactly does "involved in" mean? >=20 > Extension types that can create reference cycles and want to > support GC. There are currently none of these unless someone > quickly implemented one. If you are saying that there are no (known) extension types that could = possibly be affected, and that any written in the future must match = Python's GC mode - then it sounds perfect, and a bridge to cross when we = come to it (by which time of course the patch will prove so wonderful = that it is made standard :-) That's-one-long-sentence-ly, Mark. From tismer@tismer.com Wed Apr 26 02:00:42 2000 From: tismer@tismer.com (Christian Tismer) Date: Wed, 26 Apr 2000 03:00:42 +0200 Subject: [Patches] Re: Trashcan vs. GC vs. TRACE_REFS References: <200004251917.OAA20467@buffalo.fnal.gov> <3905F37E.3DB3AA9B@tismer.com> <3905F65C.873B0B26@tismer.com> <200004252157.RAA02365@eric.cnri.reston.va.us> Message-ID: <39063FBA.592A42F@tismer.com> Guido van Rossum wrote: > > > Guido? How urgent do you think is to wipe the > > type code? It seems to become a hair with GC. > > I'll deal with GC later. I think it's an important debugging feature > since it traps any use of the object after it has been deallocated > immediately. hehee, how good that this isn't my problem since I'mnot in charge... -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaunstr. 26 : *Starship* http://starship.python.net 14163 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF where do you want to jump today? http://www.stackless.com From nascheme@enme.ucalgary.ca Wed Apr 26 03:11:31 2000 From: nascheme@enme.ucalgary.ca (Neil Schemenauer) Date: Tue, 25 Apr 2000 20:11:31 -0600 Subject: [Patches] Re: Trashcan vs. GC vs. TRACE_REFS In-Reply-To: ; from mhammond@skippinet.com.au on Wed, Apr 26, 2000 at 11:56:59AM +1000 References: <20000425195220.A26364@acs.ucalgary.ca> Message-ID: <20000425201131.A26520@acs.ucalgary.ca> On Wed, Apr 26, 2000 at 11:56:59AM +1000, Mark Hammond wrote: > If you are saying that there are no (known) extension types > that could possibly be affected, and that any written in the > future must match Python's GC mode - then it sounds perfect, > and a bridge to cross when we come to it (by which time of > course the patch will prove so wonderful that it is made > standard :-) That's what I'm saying. Types that want to "be involved in GC" must: Use PyGC_NEW* instead of PyObject_NEW*. Use PyGC_Del to free the object structure. Call PyGC_Insert and PyGC_Remove appropriately. Objects should only be included in the GC set when they are valid. Implement tp_recurse. Add the feature bit Py_TPFLAGS_HAVE_GCINFO. Types which don't "op-in" for GC are safe. > That's-one-long-sentence-ly, Especially when its on one line. :) Neil From guido@python.org Wed Apr 26 03:15:08 2000 From: guido@python.org (Guido van Rossum) Date: Tue, 25 Apr 2000 22:15:08 -0400 Subject: [Patches] Re: Trashcan vs. GC vs. TRACE_REFS In-Reply-To: Your message of "Wed, 26 Apr 2000 02:56:32 +0200." <39063EC0.23174B81@tismer.com> References: <200004251917.OAA20467@buffalo.fnal.gov> <3905F37E.3DB3AA9B@tismer.com> <3905F65C.873B0B26@tismer.com> <200004252157.RAA02365@eric.cnri.reston.va.us> <20000425190310.B25863@acs.ucalgary.ca> <39063EC0.23174B81@tismer.com> Message-ID: <200004260215.WAA06150@eric.cnri.reston.va.us> > > With my current patch, extension types that > > are involved with GC must match the interpreter (GC vs. no-GC). > > Other extensions do not have to be recompiled (even ones compiled > > before applying the patch). > > That's important -- I can replace python16.dll, and the win32 > extensions will not break -- ok? One concern (I also haven't seen Neil's recent patches). If an extension uses MACROS to access tuple or list items, then if the GC code changes the header size for those objects those extensions are in deep doodoo. My own version avoided this by allocating the special fields *before* the standard header (playing pointer tricks) but there are problems with that approach too... --Guido van Rossum (home page: http://www.python.org/~guido/) From nascheme@enme.ucalgary.ca Wed Apr 26 03:18:10 2000 From: nascheme@enme.ucalgary.ca (Neil Schemenauer) Date: Tue, 25 Apr 2000 20:18:10 -0600 Subject: [Patches] Re: Trashcan vs. GC vs. TRACE_REFS In-Reply-To: <200004260215.WAA06150@eric.cnri.reston.va.us>; from guido@python.org on Tue, Apr 25, 2000 at 10:15:08PM -0400 References: <200004251917.OAA20467@buffalo.fnal.gov> <3905F37E.3DB3AA9B@tismer.com> <3905F65C.873B0B26@tismer.com> <200004252157.RAA02365@eric.cnri.reston.va.us> <20000425190310.B25863@acs.ucalgary.ca> <39063EC0.23174B81@tismer.com> <200004260215.WAA06150@eric.cnri.reston.va.us> Message-ID: <20000425201810.A26682@acs.ucalgary.ca> On Tue, Apr 25, 2000 at 10:15:08PM -0400, Guido van Rossum wrote: > My own version avoided this by allocating the special fields *before* > the standard header (playing pointer tricks) but there are problems > with that approach too... I use the same (ugly) trick. What were your problems? Neil -- "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off." -- Bjarne Stroustrup, Inventor of C++ From guido@python.org Wed Apr 26 04:12:27 2000 From: guido@python.org (Guido van Rossum) Date: Tue, 25 Apr 2000 23:12:27 -0400 Subject: [Patches] Re: Trashcan vs. GC vs. TRACE_REFS In-Reply-To: Your message of "Tue, 25 Apr 2000 20:18:10 MDT." <20000425201810.A26682@acs.ucalgary.ca> References: <200004251917.OAA20467@buffalo.fnal.gov> <3905F37E.3DB3AA9B@tismer.com> <3905F65C.873B0B26@tismer.com> <200004252157.RAA02365@eric.cnri.reston.va.us> <20000425190310.B25863@acs.ucalgary.ca> <39063EC0.23174B81@tismer.com> <200004260215.WAA06150@eric.cnri.reston.va.us> <20000425201810.A26682@acs.ucalgary.ca> Message-ID: <200004260312.XAA06255@eric.cnri.reston.va.us> [me] > > My own version avoided this by allocating the special fields *before* > > the standard header (playing pointer tricks) but there are problems > > with that approach too... [Neil] > I use the same (ugly) trick. What were your problems? Mostly just to get all the details right (e.g. I never got _PyResize_Tuple done, and Charles seems to have had problems integrating that with his own patches to that piece of code...). Since you've got it done, and since it's the only way to be binary compatible, it's best to keep it this way. --Guido van Rossum (home page: http://www.python.org/~guido/) From mwh21@cam.ac.uk Wed Apr 26 11:10:13 2000 From: mwh21@cam.ac.uk (Michael Hudson) Date: Wed, 26 Apr 2000 11:10:13 +0100 (BST) Subject: [Patches] Better error handling for posix.execv Message-ID: This patch changes posixmodule.c:execv to a) check for zero length args (does this to execve, too), raising ValueError. b) raises more rational exceptions for various flavours of duff arguments. I *hate* TypeError: "illegal argument type for built-in operation" It has to be one of the most frustrating error messages ever. Also, isn't the docstring for spawnv just wrong? (about replacing the current process). Another patch, maybe. Cheers, Michael I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. Index: posixmodule.c =================================================================== RCS file: /projects/cvsroot/python/dist/src/Modules/posixmodule.c,v retrieving revision 2.131 diff -u -r2.131 posixmodule.c --- posixmodule.c 2000/04/21 18:54:45 2.131 +++ posixmodule.c 2000/04/26 10:07:42 @@ -1343,8 +1343,13 @@ getitem = PyTuple_GetItem; } else { - badarg: - PyErr_BadArgument(); + PyErr_SetString(PyExc_TypeError, "argv must be tuple or list"); + return NULL; + } + + if (argc == 0) { + PyErr_SetString(PyExc_ValueError, + "empty argument list"); return NULL; } @@ -1354,7 +1359,10 @@ for (i = 0; i < argc; i++) { if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) { PyMem_DEL(argvlist); - goto badarg; + PyErr_SetString(PyExc_TypeError, + "all arguments must be strings"); + return NULL; + } } argvlist[argc] = NULL; @@ -1413,6 +1421,12 @@ } if (!PyMapping_Check(env)) { PyErr_SetString(PyExc_TypeError, "env must be mapping object"); + return NULL; + } + + if (argc == 0) { + PyErr_SetString(PyExc_ValueError, + "empty argument list"); return NULL; } From mwh21@cam.ac.uk Wed Apr 26 11:45:20 2000 From: mwh21@cam.ac.uk (Michael Hudson) Date: Wed, 26 Apr 2000 11:45:20 +0100 (BST) Subject: [Patches] accompaniment to patch to posixmodule.c Message-ID: Thanks heavens for test suites; my last patch broke os.exec[vl]p*, which broke popen3 ... in some circumstances. Anyway, this patch sorts that out. Cheers, M. I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. Index: os.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Lib/os.py,v retrieving revision 1.33 diff -u -r1.33 os.py --- os.py 2000/04/25 10:53:22 1.33 +++ os.py 2000/04/26 10:44:54 @@ -252,7 +252,7 @@ if not _notfound: import tempfile # Exec a file that is guaranteed not to exist - try: execv(tempfile.mktemp(), ()) + try: execv(tempfile.mktemp(), ('blah',)) except error, _notfound: pass exc, arg = error, _notfound for dir in PATH: From tismer@tismer.com Wed Apr 26 12:52:32 2000 From: tismer@tismer.com (Christian Tismer) Date: Wed, 26 Apr 2000 13:52:32 +0200 Subject: [Patches] Re: Trashcan vs. GC vs. TRACE_REFS References: <200004251917.OAA20467@buffalo.fnal.gov> <3905F37E.3DB3AA9B@tismer.com> <3905F65C.873B0B26@tismer.com> <200004252157.RAA02365@eric.cnri.reston.va.us> <14598.5628.536367.666435@beluga.mojam.com> Message-ID: <3906D880.4324BB52@tismer.com> Skip Montanaro wrote: ... > Isn't this a problem because the ob_type field is effectively being used for > two competing purposes (I haven't been following *real* closely for fear of > someone slamming on the brakes...)? Is there some way to split those two > functions into two separate fields, at least when Py_TRACE_REFS is defined? Aahh - that sounds good. Proposal: (given Py_TRACE_REFS) - allow ob_type to be wiped as it is done today - add ob_typebak and save the type there - in Neil's code refer to ob_typebak yes these were in fact competing purposes - ciao - chris -- Christian Tismer :^) Applied Biometrics GmbH : Have a break! Take a ride on Python's Kaunstr. 26 : *Starship* http://starship.python.net 14163 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF where do you want to jump today? http://www.stackless.com From gstein@lyra.org Wed Apr 26 13:38:11 2000 From: gstein@lyra.org (Greg Stein) Date: Wed, 26 Apr 2000 05:38:11 -0700 (PDT) Subject: [Patches] Sightly clean-up cycle-gc patch In-Reply-To: <14597.49537.611625.343576@buffalo.fnal.gov> Message-ID: On Tue, 25 Apr 2000, Charles G Waldman wrote: >... > --- Python-cvs/Include/object.h Fri Mar 24 22:32:16 2000 > +++ Python-gc/Include/object.h Sat Apr 8 01:38:25 2000 > @@ -145,6 +145,10 @@ > typedef int (*getsegcountproc) Py_PROTO((PyObject *, int *)); > typedef int (*getcharbufferproc) Py_PROTO((PyObject *, int, const char **)); > typedef int (*objobjproc) Py_PROTO((PyObject *, PyObject *)); > +#ifdef WITH_CYCLE_GC > +typedef int (*visitproc) Py_PROTO((PyObject *, void *)); > +typedef int (*recurseproc) Py_PROTO((PyObject *, visitproc, void *)); > +#endif > > typedef struct { > binaryfunc nb_add; > @@ -243,9 +247,18 @@ > > char *tp_doc; /* Documentation string */ > > - /* More spares */ > +#ifdef WITH_CYCLE_GC > + /* call function for all accessible objects */ > + recurseproc tp_recurse; > + > + /* delete references to contained objects */ > + inquiry tp_clear; > +#else > long tp_xxx5; > long tp_xxx6; > +#endif Just rename those spares. I don't see that we could truly use them for something else -- if somebody defined WITH_CYCLE_GC, then there would be a conflict. This also implies the typedefs further above would not be protected by the macro. >... > --- Python-cvs/Include/objimpl.h Thu Mar 2 17:02:23 2000 > +++ Python-gc/Include/objimpl.h Sat Apr 8 03:18:22 2000 > @@ -38,8 +38,42 @@ > /* > Additional macros for modules that implement new object types. > You must first include "object.h". > +*/ > + > +#ifdef WITH_CYCLE_GC > + > +/* Structure *prefixed* to container objects participating in GC */ > +typedef struct _gcinfo { > + struct _gcinfo *gc_next; > + struct _gcinfo *gc_prev; > + int gc_refs; > +} PyGCInfo; > + > +/* Test if a type has GC info */ > +#define PY_TYPEISGC(t) PyType_HasFeature((t), Py_TPFLAGS_HAVE_GCINFO) > + > +/* Test if an object has GC info */ > +#define PY_ISGC(o) PY_TYPEISGC((o)->ob_type) > + > +/* Get an object's GC info -- NULL if the object has none */ > +#define PY_GCINFO(o) (PY_ISGC(o) ? ((PyGCInfo *)(o)-1) : NULL) > + > +/* Unsafe version of PY_GCINFO() -- only call if PY_ISGC(p) is true */ > +#define PY_GCINFO_UNSAFE(o) ((PyGCInfo *)(o)-1) > + > +/* Get the object given the PyGCInfo */ > +#define PY_GCOBJ(g) ((PyObject *)((g)+1)) IMO, if it doesn't change the Python functionality, then don't protect this stuff with WITH_CYCLE_GC. These macros should also be named Py_* rather than PY_*. I'm not away of anything using the PY_ prefix. > -PyObject_NEW(type, typeobj) allocates memory for a new object of the given > +/* Add the object into the container set */ > +extern DL_IMPORT(void) PyGC_Insert Py_PROTO((PyObject *)); > + > +/* Remove the object from the container set */ > +extern DL_IMPORT(void) PyGC_Remove Py_PROTO((PyObject *)); These functions probably need to be protected. Seems like I recall a linker that will look for them if an "extern" is found anywhere in the program (even if no call is made to it). >... > --- Python-cvs/Modules/newmodule.c Tue Feb 29 14:55:09 2000 > +++ Python-gc/Modules/newmodule.c Sat Apr 8 02:13:26 2000 > @@ -49,13 +49,16 @@ > &PyClass_Type, &klass, > &PyDict_Type, &dict)) > return NULL; > - inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type); > + inst = PyObject_New(PyInstanceObject, &PyInstance_Type); > if (inst == NULL) > return NULL; > Py_INCREF(klass); > Py_INCREF(dict); > inst->in_class = (PyClassObject *)klass; > inst->in_dict = dict; > +#ifdef WITH_CYCLE_GC > + PyGC_Insert((PyObject *)inst); > +#endif This would be MUCH cleaner if PyGC_Insert() evaluated to a no-op in the non-GC case. >... > +/*** list functions (should probably be macros, stupid compilers) ***/ > + > +static void > +LIST_INIT(PyGCInfo *list) But since they are not macros, the upper case is "wierd." I'd recommend making them lower case, like the rest of Python functions. >... > @@ -498,11 +528,14 @@ > PyObject *error_type, *error_value, *error_traceback; > PyObject *del; > static PyObject *delstr; > + extern long _Py_RefTotal; > +#ifdef WITH_CYCLE_GC > + PyGC_Remove((PyObject *)inst); > +#endif Same on PyGC_Remove() ... make it a no-op macro when WITH_CYCLE_GC is not defined. >... > - im = PyObject_NEW(PyMethodObject, &PyMethod_Type); > + im = PyObject_New(PyMethodObject, &PyMethod_Type); Can these changes be broken out into a separate patch? I'm guessing that this can be done *regardless* of the GC work, and that it would be an improvement to things. If that is the case, then let's see a separate patch for JUST this and get it applied ASAP. Could reduce Vladimir's patch size, too. I'm a big fan of avoiding comingling of patch concepts... >... > @@ -489,7 +495,7 @@ > } > } > PyMem_XDEL(mp->ma_table); > - PyMem_DEL(mp); > + PyObject_Del((PyObject *)mp); > Py_TRASHCAN_SAFE_END(mp) > } Same logic applies here. Let's see this change in a basic patch that the GC patches can THEN build upon. By getting small pieces, each individually reviewable, each individually applicable, then we have a larger hope of a successful review of these patches. As it is, I'm only doing a cursory review over this stuff because the dumb thing is so big... >... > --- Python-cvs/Objects/object.c Tue Mar 28 08:11:09 2000 > +++ Python-gc/Objects/object.c Sat Apr 8 02:10:06 2000 > @@ -107,20 +107,12 @@ > } > #endif > > -#ifndef MS_COREDLL > -PyObject * > -_PyObject_New(tp) > - PyTypeObject *tp; > -#else > + > PyObject * > -_PyObject_New(tp,op) > +_PyObject_FromType(tp,op) > PyTypeObject *tp; > PyObject *op; > -#endif > { > -#ifndef MS_COREDLL > - PyObject *op = (PyObject *) malloc(tp->tp_basicsize); > -#endif > if (op == NULL) > return PyErr_NoMemory(); > op->ob_type = tp; > @@ -128,29 +120,78 @@ > return op; > } > > -#ifndef MS_COREDLL > -PyVarObject * > -_PyObject_NewVar(tp, size) > - PyTypeObject *tp; > - int size; > -#else > PyVarObject * > -_PyObject_NewVar(tp, size, op) > +_PyObject_VarFromType(tp, size, op) > PyTypeObject *tp; > int size; > PyVarObject *op; > -#endif > { > -#ifndef MS_COREDLL > - PyVarObject *op = (PyVarObject *) > - malloc(tp->tp_basicsize + size * tp->tp_itemsize); > -#endif Umm.... what is this stuff with removing MS_COREDLL? Is that right? Is this part of the PyObject_New thing? Should it go into the separate patch? >... > #if MAXSAVESIZE > 0 > if (size == 0) { > free_tuples[0] = op; > - ++num_free_tuples[0]; Woah! Did you start with an old version of this file? Maybe you should do a "cvs update" before generating your diff, to make sure that CVS changes are integrated into your local source. >... > #if MAXSAVESIZE > 0 > if (newsize == 0 && free_tuples[0]) { > - num_free_tuples[0]--; > sv = free_tuples[0]; > sv->ob_size = 0; Another one here. Cheers, -g -- Greg Stein, http://www.lyra.org/ From cgw@fnal.gov Wed Apr 26 15:07:11 2000 From: cgw@fnal.gov (Charles G Waldman) Date: Wed, 26 Apr 2000 09:07:11 -0500 (CDT) Subject: [Patches] Sightly clean-up cycle-gc patch In-Reply-To: References: <14597.49537.611625.343576@buffalo.fnal.gov> Message-ID: <14598.63503.871276.183817@buffalo.fnal.gov> Greg Stein writes: > > >... > > #if MAXSAVESIZE > 0 > > if (size == 0) { > > free_tuples[0] = op; > > - ++num_free_tuples[0]; > > Woah! Did you start with an old version of this file? Maybe you should do > a "cvs update" before generating your diff, to make sure that CVS changes > are integrated into your local source. > > if (newsize == 0 && free_tuples[0]) { > > - num_free_tuples[0]--; > > sv = free_tuples[0]; > > sv->ob_size = 0; > > Another one here. The changes above were intentional, when I was generating my update of Neil's patch I picked up this tiny change to tupleobject.c that I had made in my local workspace. I should have submitted just this change as a separate patch, to avoid confusion. Sorry. But I realized that the code that was handling num_free_tuples[0] was both (A) wrong and (B) unneccessary. For the free_tuples list, size=0 is a special case, there is a unique empty tuple and although we keep handing out references to it we never remove it from the free list. So num_free_tuples[0]-- is not correct. In fact we don't need to keep track of num_free_tuples[0] at all. My apologies for mixing this change in with something unrelated (Neil's GC). I agree with the other points made in your posting, just wanted to clear up this small detail. > Cheers, > -g Your watchful and observant eye is much appreciated! From nascheme@enme.ucalgary.ca Wed Apr 26 16:51:37 2000 From: nascheme@enme.ucalgary.ca (Neil Schemenauer) Date: Wed, 26 Apr 2000 09:51:37 -0600 Subject: [Patches] Sightly clean-up cycle-gc patch In-Reply-To: ; from gstein@lyra.org on Wed, Apr 26, 2000 at 05:38:11AM -0700 References: <14597.49537.611625.343576@buffalo.fnal.gov> Message-ID: <20000426095137.B13009@acs.ucalgary.ca> Thanks for the comments Greg. I had already made most of the changes you suggested. As per your suggestions, I have renamed the macros from PY_* to Py_* and lowercased the list function names. The latest version is attached. Neil Index: 0.3/Makefile.in *** 0.3/Makefile.in Tue, 25 Apr 2000 17:33:19 -0600 nas (python/0_Makefile.i 1.1 644) --- gc.6(w)/Makefile.in Tue, 25 Apr 2000 17:59:00 -0600 nas (python/0_Makefile.i 1.1.1.1 644) *************** *** 401,407 **** $(INSTALL_DATA) Modules/Makefile $(LIBPL)/Makefile $(INSTALL_DATA) Modules/Setup $(LIBPL)/Setup $(INSTALL_DATA) Modules/Setup.local $(LIBPL)/Setup.local ! $(INSTALL_DATA) Modules/Setup.thread $(LIBPL)/Setup.thread $(INSTALL_PROGRAM) $(srcdir)/Modules/makesetup $(LIBPL)/makesetup $(INSTALL_PROGRAM) $(srcdir)/install-sh $(LIBPL)/install-sh $(INSTALL_DATA) $(srcdir)/Misc/Makefile.pre.in $(LIBPL)/Makefile.pre.in --- 401,407 ---- $(INSTALL_DATA) Modules/Makefile $(LIBPL)/Makefile $(INSTALL_DATA) Modules/Setup $(LIBPL)/Setup $(INSTALL_DATA) Modules/Setup.local $(LIBPL)/Setup.local ! $(INSTALL_DATA) Modules/Setup.auto $(LIBPL)/Setup.auto $(INSTALL_PROGRAM) $(srcdir)/Modules/makesetup $(LIBPL)/makesetup $(INSTALL_PROGRAM) $(srcdir)/install-sh $(LIBPL)/install-sh $(INSTALL_DATA) $(srcdir)/Misc/Makefile.pre.in $(LIBPL)/Makefile.pre.in Index: 0.3/config.h.in *** 0.3/config.h.in Tue, 25 Apr 2000 17:33:19 -0600 nas (python/3_config.h.i 1.1 644) --- gc.6(w)/config.h.in Tue, 25 Apr 2000 17:59:00 -0600 nas (python/3_config.h.i 1.1.1.1 644) *************** *** 207,212 **** --- 207,215 ---- (shared library plus accessory files). */ #undef WITH_NEXT_FRAMEWORK + /* Define if you want cycle garbage collection */ + #undef WITH_CYCLE_GC + /* The number of bytes in an off_t. */ #undef SIZEOF_OFF_T Index: 0.3/configure.in *** 0.3/configure.in Tue, 25 Apr 2000 17:33:19 -0600 nas (python/5_configure. 1.1 644) --- gc.6(w)/configure.in Tue, 25 Apr 2000 17:59:00 -0600 nas (python/5_configure. 1.1.1.1 644) *************** *** 1070,1079 **** fi], [AC_MSG_RESULT(no)]) # generate output files AC_OUTPUT(Makefile \ Objects/Makefile \ Parser/Makefile \ Python/Makefile \ Modules/Makefile.pre \ ! Modules/Setup.thread) --- 1070,1090 ---- fi], [AC_MSG_RESULT(no)]) + AC_SUBST(USE_GC_MODULE) + USE_GC_MODULE="#" + + AC_MSG_CHECKING(for --with-cycle-gc) + AC_ARG_WITH(cycle-gc, [--with-cycle-gc enable garbage collection], [ + AC_MSG_RESULT($withval) + AC_DEFINE(WITH_CYCLE_GC) + USE_GC_MODULE= + ], + AC_MSG_RESULT(no)) + # generate output files AC_OUTPUT(Makefile \ Objects/Makefile \ Parser/Makefile \ Python/Makefile \ Modules/Makefile.pre \ ! Modules/Setup.auto) Index: 0.3/Include/object.h *** 0.3/Include/object.h Tue, 25 Apr 2000 17:33:19 -0600 nas (python/o/18_object.h 1.1 644) --- gc.6(w)/Include/object.h Tue, 25 Apr 2000 17:59:00 -0600 nas (python/o/18_object.h 1.1.1.1 644) *************** *** 145,150 **** --- 145,152 ---- typedef int (*getsegcountproc) Py_PROTO((PyObject *, int *)); typedef int (*getcharbufferproc) Py_PROTO((PyObject *, int, const char **)); typedef int (*objobjproc) Py_PROTO((PyObject *, PyObject *)); + typedef int (*visitproc) Py_PROTO((PyObject *, void *)); + typedef int (*recurseproc) Py_PROTO((PyObject *, visitproc, void *)); typedef struct { binaryfunc nb_add; *************** *** 243,251 **** char *tp_doc; /* Documentation string */ /* More spares */ - long tp_xxx5; - long tp_xxx6; long tp_xxx7; long tp_xxx8; --- 245,257 ---- char *tp_doc; /* Documentation string */ + /* call function for all accessible objects */ + recurseproc tp_recurse; + + /* delete references to contained objects */ + inquiry tp_clear; + /* More spares */ long tp_xxx7; long tp_xxx8; *************** *** 318,323 **** --- 324,332 ---- /* PySequenceMethods contains sq_contains */ #define Py_TPFLAGS_HAVE_SEQUENCE_IN (1L<<1) + + /* Objects with a GC info prefix (allocated *before* the object itself!) */ + #define Py_TPFLAGS_HAVE_GCINFO (1L<<2) #define Py_TPFLAGS_DEFAULT (Py_TPFLAGS_HAVE_GETCHARBUFFER | \ Py_TPFLAGS_HAVE_SEQUENCE_IN) Index: 0.3/Include/objimpl.h *** 0.3/Include/objimpl.h Tue, 25 Apr 2000 17:33:19 -0600 nas (python/o/19_objimpl.h 1.1 644) --- gc.6(w)/Include/objimpl.h Tue, 25 Apr 2000 20:38:07 -0600 nas (python/o/19_objimpl.h 1.1.1.2 644) *************** *** 72,77 **** --- 72,94 ---- #endif /* MS_COREDLL */ + /*** Garbage Collection Support ***/ + + /* Add the object into the container set */ + extern DL_IMPORT(void) PyGC_Insert Py_PROTO((PyObject *)); + + /* Remove the object from the container set */ + extern DL_IMPORT(void) PyGC_Remove Py_PROTO((PyObject *)); + + /* GC objects are prefixed with PyGCInfo */ + extern DL_IMPORT(PyObject *) _PyGC_New Py_PROTO((PyTypeObject *)); + extern DL_IMPORT(PyVarObject *) _PyGC_NewVar Py_PROTO((PyTypeObject *, int)); + extern DL_IMPORT(PyObject *) PyGC_Realloc Py_PROTO((PyObject *, int)); + extern DL_IMPORT(void) PyGC_Del Py_PROTO((PyObject *)); + + #define PyGC_NEW(type, typeobj) ((type *) _PyGC_New(typeobj)) + #define PyGC_NEW_VAR(type, typeobj, n) ((type *) _PyGC_NewVar(typeobj, n)) + #ifdef __cplusplus } #endif Index: 0.3/Misc/Makefile.pre.in *** 0.3/Misc/Makefile.pre.in Tue, 25 Apr 2000 17:33:19 -0600 nas (python/B/45_Makefile.p 1.1 644) --- gc.6(w)/Misc/Makefile.pre.in Tue, 25 Apr 2000 17:59:00 -0600 nas (python/B/45_Makefile.p 1.2 644) *************** *** 168,174 **** MAKEFILE= $(LIBPL)/Makefile CONFIGC= $(LIBPL)/config.c CONFIGCIN= $(LIBPL)/config.c.in ! SETUP= $(LIBPL)/Setup.thread $(LIBPL)/Setup.local $(LIBPL)/Setup SYSLIBS= $(LIBM) $(LIBC) --- 168,174 ---- MAKEFILE= $(LIBPL)/Makefile CONFIGC= $(LIBPL)/config.c CONFIGCIN= $(LIBPL)/config.c.in ! SETUP= $(LIBPL)/Setup.auto $(LIBPL)/Setup.local $(LIBPL)/Setup SYSLIBS= $(LIBM) $(LIBC) Index: 0.3/Modules/Makefile.pre.in *** 0.3/Modules/Makefile.pre.in Tue, 25 Apr 2000 17:33:19 -0600 nas (python/C/17_Makefile.p 1.1 644) --- gc.6(w)/Modules/Makefile.pre.in Tue, 25 Apr 2000 17:59:00 -0600 nas (python/C/17_Makefile.p 1.1.1.1 644) *************** *** 147,156 **** # gets remade from scratch; this ensures to remove modules that are no # longer pertinent (but that were in a previous configuration). config.c Makefile: Makefile.pre config.c.in $(MAKESETUP) ! config.c Makefile: Setup.thread Setup Setup.local config.c Makefile: -rm -f $(LIBRARY) ! $(SHELL) $(MAKESETUP) Setup.thread Setup.local Setup hassignal: -rm -f hassignal --- 147,156 ---- # gets remade from scratch; this ensures to remove modules that are no # longer pertinent (but that were in a previous configuration). config.c Makefile: Makefile.pre config.c.in $(MAKESETUP) ! config.c Makefile: Setup.auto Setup Setup.local config.c Makefile: -rm -f $(LIBRARY) ! $(SHELL) $(MAKESETUP) Setup.auto Setup.local Setup hassignal: -rm -f hassignal Index: 0.3/Modules/Setup.in *** 0.3/Modules/Setup.in Tue, 25 Apr 2000 17:33:19 -0600 nas (python/C/18_Setup.in 1.1 644) --- gc.6(w)/Modules/Setup.in Tue, 25 Apr 2000 17:59:00 -0600 nas (python/C/18_Setup.in 1.1.1.1 644) *************** *** 100,106 **** GLHACK=-Dclear=__GLclear #gl glmodule.c cgensupport.c -I$(srcdir) $(GLHACK) -lgl -lX11 ! # The thread module is now automatically enabled, see Setup.thread. # Pure module. Cannot be linked dynamically. # -DWITH_QUANTIFY, -DWITH_PURIFY, or -DWITH_ALL_PURE --- 100,106 ---- GLHACK=-Dclear=__GLclear #gl glmodule.c cgensupport.c -I$(srcdir) $(GLHACK) -lgl -lX11 ! # The thread module is now automatically enabled, see Setup.auto. # Pure module. Cannot be linked dynamically. # -DWITH_QUANTIFY, -DWITH_PURIFY, or -DWITH_ALL_PURE Index: 0.3/Modules/cPickle.c *** 0.3/Modules/cPickle.c Tue, 25 Apr 2000 17:33:19 -0600 nas (python/C/27_cPickle.c 1.1 644) --- gc.6(w)/Modules/cPickle.c Tue, 25 Apr 2000 17:59:00 -0600 nas (python/C/27_cPickle.c 1.1.1.1 644) *************** *** 2885,2891 **** PyInstanceObject *inst; PyErr_Clear(); ! UNLESS (inst=PyObject_NEW(PyInstanceObject, &PyInstance_Type)) goto err; inst->in_class=(PyClassObject*)cls; Py_INCREF(cls); --- 2885,2891 ---- PyInstanceObject *inst; PyErr_Clear(); ! UNLESS (inst=PyGC_NEW(PyInstanceObject, &PyInstance_Type)) goto err; inst->in_class=(PyClassObject*)cls; Py_INCREF(cls); *************** *** 2893,2899 **** Py_DECREF(inst); goto err; } ! return (PyObject *)inst; } Py_DECREF(__getinitargs__); --- 2893,2899 ---- Py_DECREF(inst); goto err; } ! PyGC_Insert((PyObject *)inst); return (PyObject *)inst; } Py_DECREF(__getinitargs__); Index: 0.3/Modules/newmodule.c *** 0.3/Modules/newmodule.c Tue, 25 Apr 2000 17:33:19 -0600 nas (python/D/13_newmodule. 1.1 644) --- gc.6(w)/Modules/newmodule.c Tue, 25 Apr 2000 17:59:00 -0600 nas (python/D/13_newmodule. 1.1.1.1 644) *************** *** 49,61 **** &PyClass_Type, &klass, &PyDict_Type, &dict)) return NULL; ! inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type); if (inst == NULL) return NULL; Py_INCREF(klass); Py_INCREF(dict); inst->in_class = (PyClassObject *)klass; inst->in_dict = dict; return (PyObject *)inst; } --- 49,62 ---- &PyClass_Type, &klass, &PyDict_Type, &dict)) return NULL; ! inst = PyGC_NEW(PyInstanceObject, &PyInstance_Type); if (inst == NULL) return NULL; Py_INCREF(klass); Py_INCREF(dict); inst->in_class = (PyClassObject *)klass; inst->in_dict = dict; + PyGC_Insert((PyObject *)inst); return (PyObject *)inst; } Index: 0.3/Objects/classobject.c *** 0.3/Objects/classobject.c Tue, 25 Apr 2000 17:33:19 -0600 nas (python/E/16_classobjec 1.1 644) --- gc.6(w)/Objects/classobject.c Tue, 25 Apr 2000 20:38:07 -0600 nas (python/E/16_classobjec 1.1.1.2 644) *************** *** 110,116 **** } Py_INCREF(bases); } ! op = PyObject_NEW(PyClassObject, &PyClass_Type); if (op == NULL) { Py_DECREF(bases); return NULL; --- 110,116 ---- } Py_INCREF(bases); } ! op = PyGC_NEW(PyClassObject, &PyClass_Type); if (op == NULL) { Py_DECREF(bases); return NULL; *************** *** 131,136 **** --- 131,137 ---- Py_XINCREF(op->cl_getattr); Py_XINCREF(op->cl_setattr); Py_XINCREF(op->cl_delattr); + PyGC_Insert((PyObject *)op); return (PyObject *) op; } *************** *** 140,152 **** class_dealloc(op) PyClassObject *op; { Py_DECREF(op->cl_bases); Py_DECREF(op->cl_dict); Py_XDECREF(op->cl_name); Py_XDECREF(op->cl_getattr); Py_XDECREF(op->cl_setattr); Py_XDECREF(op->cl_delattr); ! free((ANY *)op); } static PyObject * --- 141,154 ---- class_dealloc(op) PyClassObject *op; { + PyGC_Remove((PyObject *)op); Py_DECREF(op->cl_bases); Py_DECREF(op->cl_dict); Py_XDECREF(op->cl_name); Py_XDECREF(op->cl_getattr); Py_XDECREF(op->cl_setattr); Py_XDECREF(op->cl_delattr); ! PyGC_Del((PyObject *)op); } static PyObject * *************** *** 386,391 **** --- 388,408 ---- return res; } + #ifdef WITH_CYCLE_GC + static int + class_recurse(PyClassObject *o, visitproc visit, void *closure) + { + if (o->cl_bases) visit(o->cl_bases, closure); + if (o->cl_dict) visit(o->cl_dict, closure); + if (o->cl_name) visit(o->cl_name, closure); + if (o->cl_getattr) visit(o->cl_getattr, closure); + if (o->cl_setattr) visit(o->cl_setattr, closure); + if (o->cl_delattr) visit(o->cl_delattr, closure); + return 1; + } + #endif /* WITH_CYCLE_GC */ + + PyTypeObject PyClass_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, *************** *** 406,411 **** --- 423,434 ---- (reprfunc)class_str, /*tp_str*/ (getattrofunc)class_getattr, /*tp_getattro*/ (setattrofunc)class_setattr, /*tp_setattro*/ + #ifdef WITH_CYCLE_GC + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GCINFO, /*tp_flags*/ + 0, /* tp_doc */ + (recurseproc)class_recurse, /* tp_recurse */ + #endif }; int *************** *** 444,455 **** PyErr_BadInternalCall(); return NULL; } ! inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type); if (inst == NULL) return NULL; Py_INCREF(class); inst->in_class = (PyClassObject *)class; inst->in_dict = PyDict_New(); if (inst->in_dict == NULL) { Py_DECREF(inst); return NULL; --- 467,479 ---- PyErr_BadInternalCall(); return NULL; } ! inst = PyGC_NEW(PyInstanceObject, &PyInstance_Type); if (inst == NULL) return NULL; Py_INCREF(class); inst->in_class = (PyClassObject *)class; inst->in_dict = PyDict_New(); + PyGC_Insert((PyObject *)inst); if (inst->in_dict == NULL) { Py_DECREF(inst); return NULL; *************** *** 498,508 **** PyObject *error_type, *error_value, *error_traceback; PyObject *del; static PyObject *delstr; /* Call the __del__ method if it exists. First temporarily revive the object and save the current exception, if any. */ #ifdef Py_TRACE_REFS /* much too complicated if Py_TRACE_REFS defined */ - extern long _Py_RefTotal; inst->ob_type = &PyInstance_Type; _Py_NewReference((PyObject *)inst); _Py_RefTotal--; /* compensate for increment in NEWREF */ --- 522,533 ---- PyObject *error_type, *error_value, *error_traceback; PyObject *del; static PyObject *delstr; + extern long _Py_RefTotal; + PyGC_Remove((PyObject *)inst); /* Call the __del__ method if it exists. First temporarily revive the object and save the current exception, if any. */ #ifdef Py_TRACE_REFS /* much too complicated if Py_TRACE_REFS defined */ inst->ob_type = &PyInstance_Type; _Py_NewReference((PyObject *)inst); _Py_RefTotal--; /* compensate for increment in NEWREF */ *************** *** 550,555 **** --- 575,581 ---- #ifdef COUNT_ALLOCS inst->ob_type->tp_free--; #endif + PyGC_Insert((PyObject *)inst); return; /* __del__ added a reference; don't delete now */ } #ifdef Py_TRACE_REFS *************** *** 561,567 **** #endif /* Py_TRACE_REFS */ Py_DECREF(inst->in_class); Py_XDECREF(inst->in_dict); ! free((ANY *)inst); } static PyObject * --- 587,593 ---- #endif /* Py_TRACE_REFS */ Py_DECREF(inst->in_class); Py_XDECREF(inst->in_dict); ! PyGC_Del((PyObject *)inst); } static PyObject * *************** *** 840,845 **** --- 866,881 ---- return outcome; } + #ifdef WITH_CYCLE_GC + static int + instance_recurse(PyInstanceObject *o, visitproc visit, void *closure) + { + if (o->in_class) visit((PyObject *)(o->in_class), closure); + if (o->in_dict) visit(o->in_dict, closure); + return 1; + } + #endif /* WITH_CYCLE_GC */ + static PyObject *getitemstr, *setitemstr, *delitemstr, *lenstr; static int *************** *** 1463,1469 **** (getattrofunc)instance_getattr, /*tp_getattro*/ (setattrofunc)instance_setattr, /*tp_setattro*/ 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT, /*tp_flags */ }; --- 1499,1511 ---- (getattrofunc)instance_getattr, /*tp_getattro*/ (setattrofunc)instance_setattr, /*tp_setattro*/ 0, /* tp_as_buffer */ ! #ifndef WITH_CYCLE_GC ! Py_TPFLAGS_DEFAULT, /*tp_flags*/ ! #else ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GCINFO, /*tp_flags*/ ! 0, /* tp_doc */ ! (recurseproc)instance_recurse, /* tp_recurse */ ! #endif }; Index: 0.3/Objects/dictobject.c *** 0.3/Objects/dictobject.c Tue, 25 Apr 2000 17:33:19 -0600 nas (python/E/19_dictobject 1.1 644) --- gc.6(w)/Objects/dictobject.c Tue, 25 Apr 2000 17:59:00 -0600 nas (python/E/19_dictobject 1.1.1.1 644) *************** *** 121,127 **** if (dummy == NULL) return NULL; } ! mp = PyObject_NEW(dictobject, &PyDict_Type); if (mp == NULL) return NULL; mp->ma_size = 0; --- 121,127 ---- if (dummy == NULL) return NULL; } ! mp = PyGC_NEW(dictobject, &PyDict_Type); if (mp == NULL) return NULL; mp->ma_size = 0; *************** *** 129,134 **** --- 129,135 ---- mp->ma_table = NULL; mp->ma_fill = 0; mp->ma_used = 0; + PyGC_Insert((PyObject *)mp); return (PyObject *)mp; } *************** *** 479,484 **** --- 480,486 ---- { register int i; register dictentry *ep; + PyGC_Remove((PyObject *)mp); Py_TRASHCAN_SAFE_BEGIN(mp) for (i = 0, ep = mp->ma_table; i < mp->ma_size; i++, ep++) { if (ep->me_key != NULL) { *************** *** 489,495 **** } } PyMem_XDEL(mp->ma_table); ! PyMem_DEL(mp); Py_TRASHCAN_SAFE_END(mp) } --- 491,497 ---- } } PyMem_XDEL(mp->ma_table); ! PyGC_Del((PyObject *)mp); Py_TRASHCAN_SAFE_END(mp) } *************** *** 1036,1041 **** --- 1038,1070 ---- return Py_None; } + #ifdef WITH_CYCLE_GC + static int + dict_recurse(PyObject *op, visitproc visit, void *closure) + { + int i = 0; + PyObject *pk; + PyObject *pv; + + while (PyDict_Next(op, &i, &pk, &pv)) { + if (!visit(pk, closure)) { + return 0; + } + if (!visit(pv, closure)) { + return 0; + } + } + return 1; + } + + static int + dict_gc_clear(PyObject *op) + { + PyDict_Clear(op); + return 0; + } + #endif /* WITH_CYCLE_GC */ + static PyMethodDef mapp_methods[] = { {"has_key", (PyCFunction)dict_has_key, METH_VARARGS}, {"keys", (PyCFunction)dict_keys}, *************** *** 1071,1076 **** --- 1100,1117 ---- 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ &dict_as_mapping, /*tp_as_mapping*/ + #ifdef WITH_CYCLE_GC + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GCINFO, /*tp_flags*/ + 0, /* tp_doc */ + (recurseproc)dict_recurse, /* tp_recurse */ + (inquiry)dict_gc_clear, /* tp_clear */ + #endif }; /* For backward compatibility with old dictionary interface */ Index: 0.3/Objects/funcobject.c *** 0.3/Objects/funcobject.c Tue, 25 Apr 2000 17:33:19 -0600 nas (python/E/23_funcobject 1.1 644) --- gc.6(w)/Objects/funcobject.c Tue, 25 Apr 2000 17:59:00 -0600 nas (python/E/23_funcobject 1.2 644) *************** *** 40,47 **** PyObject *code; PyObject *globals; { ! PyFunctionObject *op = PyObject_NEW(PyFunctionObject, ! &PyFunction_Type); if (op != NULL) { PyObject *doc; PyObject *consts; --- 40,46 ---- PyObject *code; PyObject *globals; { ! PyFunctionObject *op = PyGC_NEW(PyFunctionObject, &PyFunction_Type); if (op != NULL) { PyObject *doc; PyObject *consts; *************** *** 63,68 **** --- 62,68 ---- Py_INCREF(doc); op->func_doc = doc; } + PyGC_Insert((PyObject *)op); return (PyObject *)op; } *************** *** 186,197 **** func_dealloc(op) PyFunctionObject *op; { Py_DECREF(op->func_code); Py_DECREF(op->func_globals); Py_DECREF(op->func_name); Py_XDECREF(op->func_defaults); Py_XDECREF(op->func_doc); ! PyMem_DEL(op); } static PyObject* --- 186,198 ---- func_dealloc(op) PyFunctionObject *op; { + PyGC_Remove((PyObject *)op); Py_DECREF(op->func_code); Py_DECREF(op->func_globals); Py_DECREF(op->func_name); Py_XDECREF(op->func_defaults); Py_XDECREF(op->func_doc); ! PyGC_Del((PyObject *)op); } static PyObject* *************** *** 239,244 **** --- 240,258 ---- return h; } + #ifdef WITH_CYCLE_GC + static int + func_recurse(PyFunctionObject *f, visitproc visit, void *closure) + { + if (f->func_code) visit(f->func_code, closure); + if (f->func_globals) visit(f->func_globals, closure); + if (f->func_defaults) visit(f->func_defaults, closure); + if (f->func_doc) visit(f->func_doc, closure); + if (f->func_name) visit(f->func_name, closure); + return 1; + } + #endif /* WITH_CYCLE_GC */ + PyTypeObject PyFunction_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, *************** *** 255,258 **** --- 269,282 ---- 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ (hashfunc)func_hash, /*tp_hash*/ + #ifdef WITH_CYCLE_GC + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GCINFO, /*tp_flags*/ + 0, /* tp_doc */ + (recurseproc)func_recurse, /* tp_recurse */ + #endif }; Index: 0.3/Objects/listobject.c *** 0.3/Objects/listobject.c Tue, 25 Apr 2000 17:33:19 -0600 nas (python/E/25_listobject 1.1 644) --- gc.6(w)/Objects/listobject.c Tue, 25 Apr 2000 17:59:00 -0600 nas (python/E/25_listobject 1.1.1.1 644) *************** *** 61,94 **** int i; PyListObject *op; size_t nbytes; if (size < 0) { PyErr_BadInternalCall(); return NULL; } ! nbytes = size * sizeof(PyObject *); ! /* Check for overflow */ ! if (nbytes / sizeof(PyObject *) != (size_t)size) { ! return PyErr_NoMemory(); ! } ! op = (PyListObject *) malloc(sizeof(PyListObject)); ! if (op == NULL) { ! return PyErr_NoMemory(); ! } ! if (size <= 0) { ! op->ob_item = NULL; ! } else { ! op->ob_item = (PyObject **) malloc(nbytes); ! if (op->ob_item == NULL) { ! free((ANY *)op); return PyErr_NoMemory(); } } - op->ob_type = &PyList_Type; op->ob_size = size; for (i = 0; i < size; i++) op->ob_item[i] = NULL; ! _Py_NewReference((PyObject *)op); return (PyObject *) op; } --- 61,95 ---- int i; PyListObject *op; size_t nbytes; + PyObject **item; + if (size < 0) { PyErr_BadInternalCall(); return NULL; } ! if (size == 0) ! item = NULL; else { ! nbytes = size * sizeof(PyObject *); ! /* Check for overflow */ ! if (nbytes / sizeof(PyObject *) != (size_t)size) { return PyErr_NoMemory(); } + item = (PyObject **) malloc(nbytes); + if (item == NULL) + return PyErr_NoMemory(); + } + op = PyGC_NEW(PyListObject, &PyList_Type); + if (op == NULL) { + if (item != NULL) + free((ANY *)item); + return PyErr_NoMemory(); } op->ob_size = size; + op->ob_item = item; for (i = 0; i < size; i++) op->ob_item[i] = NULL; ! PyGC_Insert((PyObject *)op); return (PyObject *) op; } *************** *** 215,220 **** --- 216,222 ---- PyListObject *op; { int i; + PyGC_Remove((PyObject *)op); Py_TRASHCAN_SAFE_BEGIN(op) if (op->ob_item != NULL) { /* Do it backwards, for Christian Tismer. *************** *** 227,233 **** } free((ANY *)op->ob_item); } ! free((ANY *)op); Py_TRASHCAN_SAFE_END(op) } --- 229,235 ---- } free((ANY *)op->ob_item); } ! PyGC_Del((PyObject *)op); Py_TRASHCAN_SAFE_END(op) } *************** *** 1399,1404 **** --- 1401,1429 ---- return NULL; } + #ifdef WITH_CYCLE_GC + static int + list_recurse(PyListObject *o, visitproc visit, void *closure) + { + int i; + PyObject *x; + + for (i = o->ob_size; --i >= 0; ) { + x = o->ob_item[i]; + if (x != NULL && !visit(x, closure)) + return 0; + } + return 1; + } + + static int + list_clear(PyListObject *lp) + { + (void) PyList_SetSlice((PyObject *)lp, 0, lp->ob_size, 0); + return 0; + } + #endif /* WITH_CYCLE_GC */ + static char append_doc[] = "L.append(object) -- append object to end"; static char extend_doc[] = *************** *** 1464,1469 **** --- 1489,1506 ---- 0, /*tp_as_number*/ &list_as_sequence, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ + #ifdef WITH_CYCLE_GC + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GCINFO, /* tp_flags */ + 0, /* tp_doc */ + (recurseproc)list_recurse, /* tp_recurse */ + (inquiry)list_clear, /* tp_clear */ + #endif }; *************** *** 1532,1536 **** --- 1569,1584 ---- 0, /*tp_as_number*/ &immutable_list_as_sequence, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ + #ifdef WITH_CYCLE_GC + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + (recurseproc)list_recurse, /* tp_recurse */ + #endif }; Index: 0.3/Objects/tupleobject.c *** 0.3/Objects/tupleobject.c Tue, 25 Apr 2000 17:33:19 -0600 nas (python/E/33_tupleobjec 1.1 644) --- gc.6(w)/Objects/tupleobject.c Tue, 25 Apr 2000 17:59:00 -0600 nas (python/E/33_tupleobjec 1.1.1.1 644) *************** *** 84,89 **** --- 84,90 ---- op->ob_type = &PyTuple_Type; op->ob_size = size; #endif + _Py_NewReference((PyObject *)op); } else #endif *************** *** 97,112 **** return PyErr_NoMemory(); } ; ! op = (PyTupleObject *) malloc(nbytes); if (op == NULL) ! return PyErr_NoMemory(); ! ! op->ob_type = &PyTuple_Type; ! op->ob_size = size; } for (i = 0; i < size; i++) op->ob_item[i] = NULL; ! _Py_NewReference((PyObject *)op); #if MAXSAVESIZE > 0 if (size == 0) { free_tuples[0] = op; --- 98,110 ---- return PyErr_NoMemory(); } ; ! op = PyGC_NEW_VAR(PyTupleObject, &PyTuple_Type, size); if (op == NULL) ! return NULL; } for (i = 0; i < size; i++) op->ob_item[i] = NULL; ! #if MAXSAVESIZE > 0 if (size == 0) { free_tuples[0] = op; *************** *** 114,119 **** --- 112,118 ---- Py_INCREF(op); /* extra INCREF so that this is never freed */ } #endif + PyGC_Insert((PyObject *)op); return (PyObject *) op; } *************** *** 179,184 **** --- 178,184 ---- { register int i; register int len = op->ob_size; + PyGC_Remove((PyObject *)op); Py_TRASHCAN_SAFE_BEGIN(op) if (len > 0) { i = len; *************** *** 193,199 **** } #endif } ! free((ANY *)op); done: Py_TRASHCAN_SAFE_END(op) } --- 193,199 ---- } #endif } ! PyGC_Del((PyObject *)op); done: Py_TRASHCAN_SAFE_END(op) } *************** *** 401,406 **** --- 401,422 ---- return (PyObject *) np; } + #ifdef WITH_CYCLE_GC + static int + tuplerecurse(PyTupleObject *o, visitproc visit, void *closure) + { + int i; + PyObject *x; + + for (i = o->ob_size; --i >= 0; ) { + x = o->ob_item[i]; + if (x != NULL && !visit(x, closure)) + return 0; + } + return 1; + } + #endif /* WITH_CYCLE_GC */ + static PySequenceMethods tuple_as_sequence = { (inquiry)tuplelength, /*sq_length*/ (binaryfunc)tupleconcat, /*sq_concat*/ *************** *** 427,432 **** --- 443,458 ---- &tuple_as_sequence, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ (hashfunc)tuplehash, /*tp_hash*/ + #ifdef WITH_CYCLE_GC + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GCINFO, /* tp_flags */ + 0, /* tp_doc */ + (recurseproc)tuplerecurse, /* tp_recurse */ + #endif }; /* The following function breaks the notion that tuples are immutable: *************** *** 511,519 **** } else #endif { ! sv = (PyTupleObject *) ! realloc((char *)v, ! sizeof(PyTupleObject) + newsize * sizeof(PyObject *)); *pv = (PyObject *) sv; if (sv == NULL) { PyMem_DEL(v); --- 537,545 ---- } else #endif { ! PyGC_Remove((PyObject *)v); ! sv = (PyTupleObject *)PyGC_Realloc((PyObject *)v, ! sizeof(PyTupleObject) + newsize * sizeof(PyObject *)); *pv = (PyObject *) sv; if (sv == NULL) { PyMem_DEL(v); *************** *** 522,527 **** --- 548,554 ---- } } _Py_NewReference((PyObject *)sv); + PyGC_Insert((PyObject *)sv); for (i = sv->ob_size; i < newsize; i++) sv->ob_item[i] = NULL; if (last_is_sticky && sizediff > 0) { *************** *** 551,557 **** while (p) { q = p; p = (PyTupleObject *)(p->ob_item[0]); ! PyMem_DEL(q); } } #endif --- 578,584 ---- while (p) { q = p; p = (PyTupleObject *)(p->ob_item[0]); ! PyGC_Del((PyObject *)q); } } #endif Index: 0.3/PC/config.c *** 0.3/PC/config.c Tue, 25 Apr 2000 17:33:19 -0600 nas (python/E/39_config.c 1.1 644) --- gc.6(w)/PC/config.c Tue, 25 Apr 2000 17:59:00 -0600 nas (python/E/39_config.c 1.1.1.1 644) *************** *** 41,46 **** --- 41,49 ---- extern void initbinascii(); extern void initcmath(); extern void initerrno(); + #ifdef WITH_CYCLE_GC + extern void initgc(); + #endif extern void initimageop(); extern void initmath(); extern void initmd5(); *************** *** 79,84 **** --- 82,90 ---- {"binascii", initbinascii}, {"cmath", initcmath}, {"errno", initerrno}, + #ifdef WITH_CYCLE_GC + {"gc", initgc}, + #endif {"imageop", initimageop}, {"math", initmath}, {"md5", initmd5}, Index: 0.3/PC/config.h *** 0.3/PC/config.h Tue, 25 Apr 2000 17:33:19 -0600 nas (python/E/40_config.h 1.1 644) --- gc.6(w)/PC/config.h Tue, 25 Apr 2000 17:59:00 -0600 nas (python/E/40_config.h 1.1.1.1 644) *************** *** 384,389 **** --- 384,392 ---- /* Define if you want to use the GNU readline library */ /* #define WITH_READLINE 1 */ + /* Define if you want cycle garbage collection */ + #define WITH_CYCLE_GC 1 + /* Define if you have clock. */ /* #define HAVE_CLOCK */ Index: 0.3/PCbuild/python16.dsp *** 0.3/PCbuild/python16.dsp Tue, 25 Apr 2000 17:33:19 -0600 nas (python/G/1_python16.d 1.1 644) --- gc.6(w)/PCbuild/python16.dsp Tue, 25 Apr 2000 17:59:00 -0600 nas (python/G/1_python16.d 1.2 644) *************** *** 645,650 **** --- 645,665 ---- # End Source File # Begin Source File + SOURCE=..\Modules\gcmodule.c + + !IF "$(CFG)" == "python16 - Win32 Release" + + !ELSEIF "$(CFG)" == "python16 - Win32 Debug" + + !ELSEIF "$(CFG)" == "python16 - Win32 Alpha Debug" + + !ELSEIF "$(CFG)" == "python16 - Win32 Alpha Release" + + !ENDIF + + # End Source File + # Begin Source File + SOURCE=..\Python\getargs.c !IF "$(CFG)" == "python16 - Win32 Release" Index: 0.3/Modules/gcmodule.c *** 0.3/Modules/gcmodule.c Wed, 26 Apr 2000 09:48:07 -0600 nas () --- gc.6(w)/Modules/gcmodule.c Wed, 26 Apr 2000 09:39:29 -0600 nas (python/M/10_gcmodule.c 1.3 644) *************** *** 0 **** --- 1,771 ---- + /* + + Reference Cycle Garbage Collection + ================================== + + Neil Schemenauer + + Based on a post on the python-dev list. Ideas from Guido van Rossum, + Eric Tiedemann, and various others. + + http://www.enme.calgary.ca/~nascheme/python/gc.html + http://www.python.org/pipermail/python-dev/2000-March/003869.html + http://www.python.org/pipermail/python-dev/2000-March/004010.html + http://www.python.org/pipermail/python-dev/2000-March/004022.html + + For a highlevel view of the collection process, read the collect + function. + + TODO: + use a different interface for set_debug() (keywords)? + inline PyGC_Insert and PyGC_Remove calls? + tune parameters + + */ + + #include "Python.h" + + #define DEBUG + + #ifndef WITH_CYCLE_GC + #error "You must define WITH_CYCLE_GC to include this module" + #endif + + /* Structure *prefixed* to container objects participating in GC */ + typedef struct _gcinfo { + struct _gcinfo *gc_next; + struct _gcinfo *gc_prev; + int gc_refs; + } PyGCInfo; + + /* Test if a type has GC info */ + #define Py_TYPEISGC(t) PyType_HasFeature((t), Py_TPFLAGS_HAVE_GCINFO) + + /* Test if an object has GC info */ + #define Py_ISGC(o) Py_TYPEISGC((o)->ob_type) + + /* Get an object's GC info -- NULL if the object has none */ + #define Py_GCINFO(o) (Py_ISGC(o) ? ((PyGCInfo *)(o)-1) : NULL) + + /* Unsafe version of Py_GCINFO() -- only call if Py_ISGC(p) is true */ + #define Py_GCINFO_UNSAFE(o) ((PyGCInfo *)(o)-1) + + /* Get the object given the PyGCInfo */ + #define Py_GCOBJ(g) ((PyObject *)((g)+1)) + + /* magic gc_refs value */ + #define GC_MOVED -1 + + /*** Global GC state ***/ + + /* linked lists of container objects */ + static PyGCInfo generation0 = {&generation0, &generation0, 0}; + static PyGCInfo generation1 = {&generation1, &generation1, 0}; + static PyGCInfo generation2 = {&generation2, &generation2, 0}; + static int generation = 0; /* current generation being collected */ + + /* collection frequencies, XXX tune these */ + static int threshold0 = 100; /* net new containers before collection */ + static int threshold1 = 10; /* generation0 collections before collecting 1 */ + static int threshold2 = 10; /* generation1 collections before collecting 2 */ + + /* net new objects allocated since last collection */ + static int allocated = 0; + + /* set for debugging information */ + #define DEBUG_STATS (1<<0) /* print collection statistics */ + #define DEBUG_COLLECTABLE (1<<1) /* print collectable objects */ + #define DEBUG_UNCOLLECTABLE (1<<2) /* print uncollectable objects */ + #define DEBUG_INSTANCES (1<<3) /* print instances */ + #define DEBUG_OBJECTS (1<<4) /* print other objects */ + #define DEBUG_LEAK DEBUG_COLLECTABLE | \ + DEBUG_UNCOLLECTABLE | \ + DEBUG_INSTANCES | \ + DEBUG_OBJECTS + static int debug = DEBUG_LEAK; + + /* list of uncollectable objects */ + static PyObject *garbage = NULL; + + + /*** list functions ***/ + + static void + list_init(PyGCInfo *list) + { + list->gc_prev = list; + list->gc_next = list; + } + + static void + list_append(PyGCInfo *node, PyGCInfo *list) + { + node->gc_next = list; + node->gc_prev = list->gc_prev; + node->gc_prev->gc_next = node; + list->gc_prev = node; + } + + static void + list_remove(PyGCInfo *node) + { + node->gc_prev->gc_next = node->gc_next; + node->gc_next->gc_prev = node->gc_prev; + #ifdef DEBUG + node->gc_next = NULL; + node->gc_prev = NULL; + #endif + } + + static void + list_move(PyGCInfo *from, PyGCInfo *to) + { + if (from->gc_next == from) { + /* empty from list */ + list_init(to); + } else { + to->gc_next = from->gc_next; + to->gc_next->gc_prev = to; + to->gc_prev = from->gc_prev; + to->gc_prev->gc_next = to; + } + list_init(from); + } + + /* append a list onto another list */ + static void + list_lappend(PyGCInfo *from, PyGCInfo *to) + { + PyGCInfo *tail; + if (from->gc_next != from) { + tail = to->gc_prev; + tail->gc_next = from->gc_next; + tail->gc_next->gc_prev = tail; + to->gc_prev = from->gc_prev; + to->gc_prev->gc_next = to; + } + list_init(from); + } + + static long + list_size(PyGCInfo *list) + { + PyGCInfo *gc; + long n = 0; + for (gc = list->gc_next; gc != list; gc = gc->gc_next) { + n++; + } + return n; + } + + + #ifdef DEBUG + static void + list_print(PyGCInfo *list) { + PyGCInfo *op = list; + do { + printf("%x %x %x %d\n", (long)op, (long)op->gc_prev, + (long)op->gc_next, (long)op->gc_refs); + + op = op->gc_next; + } while (op != list); + } + #endif + + /*** end of list stuff ***/ + + + /* Set all gc_refs = ob_refcnt */ + static void + update_refs(PyGCInfo *containers) + { + PyGCInfo *gc = containers->gc_next; + for (; gc != containers; gc=gc->gc_next) { + gc->gc_refs = Py_GCOBJ(gc)->ob_refcnt; + } + } + + static int + visit_decref(PyObject *op, void *data) + { + if (op && Py_ISGC(op)) { + Py_GCINFO_UNSAFE(op)->gc_refs--; + } + return 1; + } + + /* Subtract internal references from gc_refs */ + static void + subtract_refs(PyGCInfo *containers) + { + recurseproc recurse; + PyGCInfo *gc = containers->gc_next; + for (; gc != containers; gc=gc->gc_next) { + recurse = Py_GCOBJ(gc)->ob_type->tp_recurse; + (void) recurse(Py_GCOBJ(gc), + (visitproc)visit_decref, + NULL); + } + } + + /* Append objects with gc_refs > 0 to roots list */ + static void + move_roots(PyGCInfo *containers, PyGCInfo *roots) + { + PyGCInfo *next; + PyGCInfo *gc = containers->gc_next; + while (gc != containers) { + next = gc->gc_next; + if (gc->gc_refs > 0) { + list_remove(gc); + list_append(gc, roots); + gc->gc_refs = GC_MOVED; + } + gc = next; + } + } + + static int + visit_reachable(PyObject *op, PyGCInfo *roots) + { + PyGCInfo *gc = Py_GCINFO(op); + if (gc && gc->gc_refs != GC_MOVED) { + list_remove(gc); + list_append(gc, roots); + gc->gc_refs = GC_MOVED; + } + return 1; + } + + /* Move objects referenced from reachable to reachable set. */ + static void + move_root_reachable(PyGCInfo *reachable) + { + recurseproc recurse; + PyGCInfo *gc = reachable->gc_next; + for (; gc != reachable; gc=gc->gc_next) { + /* careful, reachable list is growing here */ + PyObject *op = Py_GCOBJ(gc); + recurse = op->ob_type->tp_recurse; + (void) recurse(op, + (visitproc)visit_reachable, + (void *)reachable); + } + } + + /* move all objects with finalizers (instances with __del__) */ + static void + move_finalizers(PyGCInfo *unreachable, PyGCInfo *finalizers) + { + PyGCInfo *next; + PyGCInfo *gc = unreachable->gc_next; + static PyObject *delstr; + if (delstr == NULL) { + delstr = PyString_InternFromString("__del__"); + } + for (; gc != unreachable; gc=next) { + PyObject *op = Py_GCOBJ(gc); + next = gc->gc_next; + if (PyInstance_Check(op) && PyObject_HasAttr(op, delstr)) { + list_remove(gc); + list_append(gc, finalizers); + } + } + } + + + /* called by tp_recurse */ + static int + visit_finalizer_reachable(PyObject *op, PyGCInfo *finalizers) + { + PyGCInfo *gc = Py_GCINFO(op); + if (gc && gc->gc_refs != GC_MOVED) { + list_remove(gc); + list_append(gc, finalizers); + gc->gc_refs = GC_MOVED; + } + return 1; + } + + /* Move objects referenced from roots to roots */ + static void + move_finalizer_reachable(PyGCInfo *finalizers) + { + recurseproc recurse; + PyGCInfo *gc = finalizers->gc_next; + for (; gc != finalizers; gc=gc->gc_next) { + /* careful, finalizers list is growing here */ + recurse = Py_GCOBJ(gc)->ob_type->tp_recurse; + (void) recurse(Py_GCOBJ(gc), + (visitproc)visit_finalizer_reachable, + (void *)finalizers); + } + } + + static void + debug_instance(PyObject *output, char *msg, PyInstanceObject *inst) + { + char buf[200]; + char *cname; + /* be careful not to create new dictionaries */ + PyObject *classname = inst->in_class->cl_name; + if (classname != NULL && PyString_Check(classname)) + cname = PyString_AsString(classname); + else + cname = "?"; + sprintf(buf, "gc: %s<%.100s instance at %lx>\n", + msg, cname, (long)inst); + PyFile_WriteString(buf, output); + } + + static void + debug_cycle(PyObject *output, char *msg, PyObject *op) + { + if ((debug & DEBUG_INSTANCES) && PyInstance_Check(op)) { + debug_instance(output, msg, (PyInstanceObject *)op); + } else if (debug & DEBUG_OBJECTS) { + char buf[200]; + sprintf(buf, "gc: %s<%s 0x%x>\n", + msg, + op->ob_type->tp_name, + (long)op); + PyFile_WriteString(buf, output); + } + } + + /* Handle uncollectable garbage (cycles with finalizers). */ + static void + handle_finalizers(PyGCInfo *finalizers, PyGCInfo *old) + { + PyGCInfo *gc; + if (garbage == NULL) { + garbage = PyList_New(0); + } + for (gc = finalizers->gc_next; gc != finalizers; + gc = finalizers->gc_next) { + PyObject *op = Py_GCOBJ(gc); + /* Add all instances to a Python accessible list of garbage */ + if (PyInstance_Check(op)) { + PyList_Append(garbage, op); + } + /* We assume that all objects in finalizers are reachable from + * instances. Once we add the instances to the garbage list + * everything is reachable from Python again. */ + list_remove(gc); + list_append(gc, old); + } + } + + /* Break reference cycles by clearing the containers involved. This is + * tricky business as the lists can be changing and we don't know which + * objects may be freed. It is possible I screwed something up here. */ + static void + delete_garbage(PyGCInfo *unreachable, PyGCInfo *old) + { + inquiry clear; + + while (unreachable->gc_next != unreachable) { + PyGCInfo *gc = unreachable->gc_next; + PyObject *op = Py_GCOBJ(gc); + /* + PyList_Append(garbage, op); + */ + if ((clear = op->ob_type->tp_clear) != NULL) { + Py_INCREF(op); + clear((PyObject *)op); + Py_DECREF(op); + } + /* only try to call tp_clear once for each object */ + if (unreachable->gc_next == gc) { + /* still alive, move it, it may die later */ + list_remove(gc); + list_append(gc, old); + } + } + } + + /* This is the main function. Read this to understand how the + * collection process works. */ + static long + collect(PyGCInfo *young, PyGCInfo *old) + { + long n = 0; + long m = 0; + PyGCInfo reachable; + PyGCInfo unreachable; + PyGCInfo finalizers; + PyGCInfo *gc; + PyObject *output = NULL; + + if (debug) { + output = PySys_GetObject("stderr"); + } + if (debug & DEBUG_STATS) { + char buf[100]; + sprintf(buf, "gc: collecting generation %d...\n", generation); + PyFile_WriteString(buf,output); + sprintf(buf, "gc: objects in each generation: %d %d %d\n", + list_size(&generation0), + list_size(&generation1), + list_size(&generation2)); + PyFile_WriteString(buf,output); + } + + /* Using ob_refcnt and gc_refs, calculate which objects in the + * container set are reachable from outside the set (ie. have a + * refcount greater than 0 when all the references within the + * set are taken into account */ + update_refs(young); + subtract_refs(young); + + /* Move everything reachable from outside the set into the + * reachable set (ie. gc_refs > 0). Next, move everything + * reachable from objects in the reachable set. */ + list_init(&reachable); + move_roots(young, &reachable); + move_root_reachable(&reachable); + + /* move unreachable objects to a temporary list, new objects can be + * allocated after this point */ + list_init(&unreachable); + list_move(young, &unreachable); + + /* move reachable objects to next generation */ + list_lappend(&reachable, old); + + /* Move objects reachable from finalizers, we can't safely delete + * them. Python programmers should take care not to create such + * things. For Python finalizers means instance objects with + * __del__ methods. */ + list_init(&finalizers); + move_finalizers(&unreachable, &finalizers); + move_finalizer_reachable(&finalizers); + + /* Collect statistics on collectable objects found and print + * debugging information. */ + for (gc = unreachable.gc_next; gc != &unreachable; + gc = gc->gc_next) { + m++; + if (output != NULL && (debug & DEBUG_COLLECTABLE)) { + debug_cycle(output, "collectable ", Py_GCOBJ(gc)); + } + } + /* call tp_clear on objects in the collectable set. This will cause + * the reference cycles to be broken. It may also cause some objects in + * finalizers to be freed */ + delete_garbage(&unreachable, old); + + /* Collect statistics on uncollectable objects found and print + * debugging information. */ + for (gc = finalizers.gc_next; gc != &finalizers; + gc = gc->gc_next) { + n++; + if (output != NULL && (debug & DEBUG_UNCOLLECTABLE)) { + debug_cycle(output, "uncollectable ", Py_GCOBJ(gc)); + } + } + if (output != NULL && (debug & DEBUG_STATS)) { + if (m == 0 && n == 0) { + PyFile_WriteString("gc: done.\n", output); + } else { + char buf[200]; + sprintf(buf, + "gc: done, %d unreachable, %d uncollectable.\n", + n+m, n); + PyFile_WriteString(buf, output); + } + } + + /* Append instances in the uncollectable set to a Python + * reachable list of garbage. The programmer has to deal with + * this if they insist on creating this type of structure. */ + handle_finalizers(&finalizers, old); + + allocated = 0; + PyErr_Clear(); /* in case writing to sys.stderr failed */ + return n+m; + } + + static long + collect_generations(void) + { + static long collections0 = 0; + static long collections1 = 0; + long n; + + + if (collections1 > threshold2) { + generation = 2; + list_lappend(&generation0, &generation2); + list_lappend(&generation1, &generation2); + if (generation2.gc_next != &generation2) { + n = collect(&generation2, &generation2); + } + collections1 = 0; + } else if (collections0 > threshold1) { + generation = 1; + collections1++; + list_lappend(&generation0, &generation1); + if (generation1.gc_next != &generation1) { + n = collect(&generation1, &generation2); + } + collections0 = 0; + } else { + generation = 0; + collections0++; + if (generation0.gc_next != &generation0) { + n = collect(&generation0, &generation1); + } + } + return n; + } + + void + PyGC_Insert(PyObject *op) + { + /* collection lock since collecting may cause allocations */ + static int collecting = 0; + + #ifdef DEBUG + /*fprintf(stderr, "Insert 0x%x\n", op);*/ + if (!Py_ISGC(op)) { + abort(); + } + #endif + if (threshold0 && allocated > threshold0 && !collecting) { + collecting++; + collect_generations(); + collecting--; + } + allocated++; + list_append(Py_GCINFO(op), &generation0); + } + + void + PyGC_Remove(PyObject *op) + { + PyGCInfo *g = Py_GCINFO_UNSAFE(op); + #ifdef DEBUG + /*fprintf(stderr, "Remove 0x%x 0x%x\n", g, op);*/ + #endif + if (allocated > 0) { + allocated--; + } + list_remove(g); + } + + PyObject * + _PyGC_New(PyTypeObject *tp) + { + PyObject *op; + PyGCInfo *g = malloc(sizeof(*g) + tp->tp_basicsize); + if (g == NULL) { + return PyErr_NoMemory(); + } + #ifdef DEBUG + g->gc_next = NULL; + g->gc_prev = NULL; + #endif + op = Py_GCOBJ(g); + op->ob_type = tp; + _Py_NewReference(op); + return op; + } + + PyVarObject * + _PyGC_NewVar(PyTypeObject *tp, int size) + { + PyVarObject *op; + PyGCInfo *g = + g = (PyGCInfo *) malloc(sizeof(*g) + + tp->tp_basicsize + + size * tp->tp_itemsize); + if (g == NULL) { + return (PyVarObject *)PyErr_NoMemory(); + } + #ifdef DEBUG + g->gc_next = NULL; + g->gc_prev = NULL; + #endif + op = (PyVarObject *)Py_GCOBJ(g); + op->ob_type = tp; + op->ob_size = size; + _Py_NewReference((PyObject *)op); + return op; + } + + PyObject * + PyGC_Realloc(PyObject *op, int size) + { + PyGCInfo *g = Py_GCINFO(op); + g = realloc((char *)g, sizeof(*g) + size); + if (g == NULL) { + return NULL; + } else { + return Py_GCOBJ(g); + } + } + + void + PyGC_Del(PyObject *op) + { + PyGCInfo *g = Py_GCINFO_UNSAFE(op); + free(g); + } + + static char collect__doc__[] = + "collect() -> n\n" + "\n" + "Run a full collection. The number of unreachable objects is returned.\n" + ; + + static PyObject * + Py_collect(self, args) + PyObject *self; + PyObject *args; + { + long n; + + if(!PyArg_ParseTuple(args, "")) /* check no args */ + return NULL; + + generation = 2; + list_lappend(&generation0, &generation2); + list_lappend(&generation1, &generation2); + n = collect(&generation2, &generation2); + + return Py_BuildValue("i", n); + } + + static char set_debug__doc__[] = + "set_debug(flags) -> None\n" + "\n" + "Set the garbage collection debugging flags. Debugging information is\n" + "written to sys.stderr.\n" + "\n" + "flags is an integer and can have the following bits turned on:\n" + "\n" + " DEBUG_STATS - Print statistics during collection.\n" + " DEBUG_COLLECTABLE - Print collectable objects found.\n" + " DEBUG_UNCOLLECTABLE - Print unreachable but uncollectable objects found.\n" + " DEBUG_INSTANCES - Print instance objects.\n" + " DEBUG_OBJECTS - Print objects other than instances.\n" + " DEBUG_LEAK - Debug leaking programs (everything but STATS).\n" + ; + + static PyObject * + Py_set_debug(self, args) + PyObject *self; + PyObject *args; + { + if (!PyArg_ParseTuple(args, "l", &debug)) + return NULL; + + Py_INCREF(Py_None); + return Py_None; + } + + static char get_debug__doc__[] = + "get_debug() -> flags\n" + "\n" + "Get the garbage collection debugging flags.\n" + ; + + static PyObject * + Py_get_debug(self, args) + PyObject *self; + PyObject *args; + { + if(!PyArg_ParseTuple(args, "")) /* no args */ + return NULL; + + return Py_BuildValue("i", debug); + } + + static char set_thresh__doc__[] = + "set_threshold(threshold0, [threhold1, threshold2]) -> None\n" + "\n" + "Sets the collection thresholds. Setting threshold0 to zero disables\n" + "collection.\n" + ; + + static PyObject * + Py_set_thresh(self, args) + PyObject *self; + PyObject *args; + { + if (!PyArg_ParseTuple(args, "i|ii", &threshold0, + &threshold1, &threshold2)) + return NULL; + + Py_INCREF(Py_None); + return Py_None; + } + + static char get_thresh__doc__[] = + "get_threshold() -> (threshold0, threshold1, threshold2)\n" + "\n" + "Return the current collection thresholds\n" + ; + + static PyObject * + Py_get_thresh(self, args) + PyObject *self; + PyObject *args; + { + if(!PyArg_ParseTuple(args, "")) /* no args */ + return NULL; + + return Py_BuildValue("(iii)", threshold0, threshold1, threshold2); + } + + + static char gc__doc__ [] = + "This module provides access to the garbage collector for reference cycles.\n" + "\n" + "collect() -- Do a full collection right now.\n" + "set_debug() -- Set debugging flags.\n" + "get_debug() -- Get debugging flags.\n" + "set_threshold() -- Set the collection thresholds.\n" + "get_threshold() -- Return the current the collection thresholds.\n" + ; + + static PyMethodDef GcMethods[] = { + {"set_debug", Py_set_debug, METH_VARARGS, set_debug__doc__}, + {"get_debug", Py_get_debug, METH_VARARGS, get_debug__doc__}, + {"set_threshold", Py_set_thresh, METH_VARARGS, set_thresh__doc__}, + {"get_threshold", Py_get_thresh, METH_VARARGS, get_thresh__doc__}, + {"collect", Py_collect, METH_VARARGS, collect__doc__}, + {NULL, NULL} /* Sentinel */ + }; + + void + initgc(void) + { + PyObject *m; + PyObject *d; + + m = Py_InitModule4("gc", + GcMethods, + gc__doc__, + NULL, + PYTHON_API_VERSION); + d = PyModule_GetDict(m); + if (garbage == NULL) { + garbage = PyList_New(0); + } + PyDict_SetItemString(d, "garbage", garbage); + PyDict_SetItemString(d, "DEBUG_STATS", + PyInt_FromLong(DEBUG_STATS)); + PyDict_SetItemString(d, "DEBUG_COLLECTABLE", + PyInt_FromLong(DEBUG_COLLECTABLE)); + PyDict_SetItemString(d, "DEBUG_UNCOLLECTABLE", + PyInt_FromLong(DEBUG_UNCOLLECTABLE)); + PyDict_SetItemString(d, "DEBUG_INSTANCES", + PyInt_FromLong(DEBUG_INSTANCES)); + PyDict_SetItemString(d, "DEBUG_OBJECTS", + PyInt_FromLong(DEBUG_OBJECTS)); + PyDict_SetItemString(d, "DEBUG_LEAK", + PyInt_FromLong(DEBUG_LEAK)); + } + Index: 0.3/Modules/Setup.auto.in *** 0.3/Modules/Setup.auto.in Wed, 26 Apr 2000 09:48:07 -0600 nas () --- gc.6(w)/Modules/Setup.auto.in Tue, 25 Apr 2000 17:59:00 -0600 nas (python/M/11_Setup.auto 1.1 644) *************** *** 0 **** --- 1,16 ---- + # This file is transmogrified into Setup.auto by config.status. Its + # purpose is to automatically enable modules given when certain + # arguments are given to the configure script. It replaces the old + # Setup.thread.in file. + + # Include the thread module when the --with-thread argument is given to + # the configure script. + # + # *NOTE*: if the configure script decides it can't support threads, the + # thread module will still be enabled and cause compile errors. The + # solution is not to use --with-thread on platforms that don't support + # threads. + @USE_THREAD_MODULE@thread threadmodule.c + + # Garbage collection enabled with --with-cycle-gc + @USE_GC_MODULE@gc gcmodule.c Index: 0.3/Lib/test/test_gc.py *** 0.3/Lib/test/test_gc.py Wed, 26 Apr 2000 09:48:07 -0600 nas () --- gc.6(w)/Lib/test/test_gc.py Tue, 25 Apr 2000 17:59:00 -0600 nas (python/M/12_test_gc.py 1.1 644) *************** *** 0 **** --- 1,90 ---- + import gc + + def test_list(): + l = [] + l.append(l) + print 'list 0x%x' % id(l) + gc.collect() + del l + assert gc.collect() == 1 + + def test_dict(): + d = {} + d[1] = d + print 'dict 0x%x' % id(d) + gc.collect() + del d + assert gc.collect() == 1 + + def test_tuple(): + l = [] + t = (l,) + l.append(t) + print 'list 0x%x' % id(l) + print 'tuple 0x%x' % id(t) + gc.collect() + del t + del l + assert gc.collect() == 2 + + def test_class(): + class A: + pass + A.a = A + print 'class 0x%x' % id(A) + gc.collect() + del A + assert gc.collect() > 0 + + def test_instance(): + class A: + pass + a = A() + a.a = a + print repr(a) + gc.collect() + del a + assert gc.collect() > 0 + + def test_finalizer(): + class A: + def __del__(self): pass + class B: + pass + a = A() + a.a = a + id_a = id(a) + b = B() + b.b = b + print 'a', repr(a) + print 'b', repr(b) + gc.collect() + gc.garbage[:] = [] + del a + del b + assert gc.collect() > 0 + assert id(gc.garbage[0]) == id_a + + def test_function(): + d = {} + exec("def f(): pass\n") in d + print 'dict 0x%x' % id(d) + print 'func 0x%x' % id(d['f']) + gc.collect() + del d + assert gc.collect() == 2 + + + def test_all(): + debug = gc.get_debug() + gc.set_debug(gc.DEBUG_LEAK | gc.DEBUG_STATS) + test_list() + test_dict() + test_tuple() + test_class() + test_instance() + test_finalizer() + test_function() + gc.set_debug(debug) + + test_all() From cgw@fnal.gov Wed Apr 26 16:51:35 2000 From: cgw@fnal.gov (Charles G Waldman) Date: Wed, 26 Apr 2000 10:51:35 -0500 (CDT) Subject: [Patches] GC puzzle In-Reply-To: <20000425204246.A26980@acs.ucalgary.ca> References: <14596.41644.182242.918286@buffalo.fnal.gov> <20000425105829.A27743@acs.ucalgary.ca> <14597.55168.966170.542056@buffalo.fnal.gov> <20000425113959.A28093@acs.ucalgary.ca> <14598.12230.933027.669754@buffalo.fnal.gov> <20000425184352.A25863@acs.ucalgary.ca> <14598.21582.383802.338822@buffalo.fnal.gov> <20000425204246.A26980@acs.ucalgary.ca> Message-ID: <14599.4231.551732.269169@buffalo.fnal.gov> I'm testing the GC patches with Py_TRACE_REFS enabled and have come across something odd: Python 1.6a2 (#3, Apr 26 2000, 10:35:57) [GCC 2.95.2 19991024 (release)] on linux2 Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam >>> import gc [6007 refs] >>> 0 0 [6011 refs] >>> d1={} [6015 refs] >>> d2={} [6019 refs] >>> d1[0]=d2 [6021 refs] >>> d2[0]=d1 [6023 refs] >>> del d1 [6022 refs] >>> del d2 [6021 refs] >>> gc.collect() gc: collectable gc: collectable 2 [6017 refs] ### note - before I created d1 and d2 the total refs was ### 6011 - are the extra 6 references internal to the ### GVC module ? >>> d1={} ### Now I've created a new object and the total refs has ### not gone up [6017 refs] >>> d2={} ### Now I've created another, and the total refs has ### gone up by 2! [6019 refs] >>> d1[0]=d2 [6021 refs] >>> d2[0]=d1 [6023 refs] >>> del d1 [6022 refs] >>> del d2 [6021 refs] >>> gc.collect() gc: collectable gc: collectable 2 [6017 refs] ## After this round of GC, the total refs has gone >>> ## back to the value before d1 and d2 were created, ## as I'd expect... From cgw@fnal.gov Wed Apr 26 16:57:41 2000 From: cgw@fnal.gov (Charles G Waldman) Date: Wed, 26 Apr 2000 10:57:41 -0500 (CDT) Subject: [Patches] Re: Trashcan vs. GC vs. TRACE_REFS In-Reply-To: <20000426155023.A25E41CD20@dinsdale.python.org> References: <20000426155023.A25E41CD20@dinsdale.python.org> Message-ID: <14599.4597.464952.855298@buffalo.fnal.gov> Guido van Rossum wrote: > Mostly just to get all the details right (e.g. I never got > _PyResize_Tuple done, and Charles seems to have had problems > integrating that with his own patches to that piece of code...). Well, just because I got tripped up on this at first, don't use that as an argument against Neil's approach! It was a bit subtle, but sometimes things just are that way. And, in the meanwhile, Neil has written PyGC_Realloc which makes the realloc'ing of GC-objects much simpler... From cgw@fnal.gov Wed Apr 26 17:02:05 2000 From: cgw@fnal.gov (Charles G Waldman) Date: Wed, 26 Apr 2000 11:02:05 -0500 (CDT) Subject: [Patches] odd comment in tupleobject.h Message-ID: <14599.4861.472431.654856@buffalo.fnal.gov> According to tupleobject.h: /* Another generally useful object type is an tuple of object pointers. This is a mutable type: the tuple items can be changed (but not their number). Out-of-range indices or non-tuple objects are ignored. */ Mutable? Really? Or does this just mean that tuples are mutable from inside C code? From Fredrik Lundh" Message-ID: <003701bfafa0$833e7580$34aab5d4@hagrid> Charles G Waldman wrote: > /* > Another generally useful object type is an tuple of object pointers. > This is a mutable type: the tuple items can be changed (but not their > number). Out-of-range indices or non-tuple objects are ignored. > */ >=20 > Mutable? Really? =20 >=20 > Or does this just mean that tuples are mutable from inside C code? or that a tuple containing mutable objects is in fact mutable? >>> a =3D ([], {}) >>> a[0].append(1) >>> a[1]["spam"] =3D "egg" >>> a ([1], {'spam': 'egg'}) >>> From guido@python.org Wed Apr 26 18:07:20 2000 From: guido@python.org (Guido van Rossum) Date: Wed, 26 Apr 2000 13:07:20 -0400 Subject: [Patches] odd comment in tupleobject.h In-Reply-To: Your message of "Wed, 26 Apr 2000 11:02:05 CDT." <14599.4861.472431.654856@buffalo.fnal.gov> References: <14599.4861.472431.654856@buffalo.fnal.gov> Message-ID: <200004261707.NAA06596@eric.cnri.reston.va.us> > According to tupleobject.h: > > /* > Another generally useful object type is an tuple of object pointers. > This is a mutable type: the tuple items can be changed (but not their > number). Out-of-range indices or non-tuple objects are ignored. > */ > > Mutable? Really? > > Or does this just mean that tuples are mutable from inside C code? The latter. It's a very old comment... --Guido van Rossum (home page: http://www.python.org/~guido/) From NadavH@envision.co.il Wed Apr 26 20:44:54 2000 From: NadavH@envision.co.il (Nadav Horesh) Date: Wed, 26 Apr 2000 21:44:54 +0200 Subject: [Patches] acosh and asinh functions Message-ID: <39074736.B1C7D90F@envision.co.il> This is a multi-part message in MIME format. --------------30186664822EB8C794609C59 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit The computation of the inverse hyperbolic functions 'acosh' and 'asinh' is erroneous -- it has both low precision and discontinuities. The patch (using diff) is followed: ==================================================================== 60,61c60,63 < return c_log(c_sum(x,c_prod(c_i, < c_sqrt(c_diff(c_1,c_prod(x,x)))))); --- > Py_complex z; > z = c_sqrt(c_half); > c_temp = c_log(c_prod(z, c_sum( c_sqrt(c_sum(x,c_1)), c_sqrt(c_diff(x,c_1))))); > return c_sum(c_temp,c_temp); 89,90c91 < z = c_diff(c_sqrt(z),x); < return c_neg(c_log(z)); --- > return c_log(c_sum(c_sqrt(z),x)); 338c339 < PyErr_SetFromErrno(PyExc_ValueError); --- > PyErr_SetFromErrno(PyExc_ValueError); 414c415 < --- > 422c423 < } --- > } \ No newline at end of file ================================================================= I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. --------------30186664822EB8C794609C59 Content-Type: text/x-vcard; charset=us-ascii; name="NadavH.vcf" Content-Transfer-Encoding: 7bit Content-Description: Card for Nadav Horesh Content-Disposition: attachment; filename="NadavH.vcf" begin:vcard n:Horesh;Nadav tel;fax:03 9244335 tel;home:03 9314679 tel;work:03 9244339 x-mozilla-html:TRUE adr:;;;;;; version:2.1 email;internet:NadavH@Envision.com fn:Nadav Horesh end:vcard --------------30186664822EB8C794609C59-- From Jack.Jansen@oratrix.com Wed Apr 26 21:39:08 2000 From: Jack.Jansen@oratrix.com (Jack Jansen) Date: Wed, 26 Apr 2000 22:39:08 +0200 Subject: [Patches] Patch to timemodule, this time with patch:-) Message-ID: <390753EC.9A47E229@oratrix.nl> This is a multi-part message in MIME format. --------------85E38E06D9657C4E356D2881 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Here it is again (I hope:-). This patch is a workaround for Macintosh, where the GUSI I/O library (time, stat, etc) use the MacOS epoch of 1-Jan-1904 and the MSL C library (ctime, localtime, etc) uses the (apparently ANSI standard) epoch of 1-Jan-1900. Python programs see the MacOS epoch and we convert values when needed. --------------85E38E06D9657C4E356D2881 Content-Type: text/plain; charset=us-ascii; x-mac-type="54455854"; x-mac-creator="522A6368"; name="patch-timemodule" Content-Transfer-Encoding: 7bit Content-Description: Unknown Document Content-Disposition: inline; filename="patch-timemodule" Index: timemodule.c =================================================================== RCS file: /projects/cvsroot/python/dist/src/Modules/timemodule.c,v retrieving revision 2.81 diff -c -r2.81 timemodule.c *** timemodule.c 2000/03/24 20:35:20 2.81 --- timemodule.c 2000/04/21 22:58:16 *************** *** 41,46 **** --- 41,54 ---- #ifdef macintosh #include + #include + #ifdef USE_GUSI2 + /* GUSI, the I/O library which has the time() function and such uses the + ** Mac epoch of 1904. MSL, the C library which has localtime() and so uses + ** the ANSI epoch of 1900. + */ + #define GUSI_TO_MSL_EPOCH (4*365*24*60*60) + #endif /* USE_GUSI2 */ #else #include #endif *************** *** 271,276 **** --- 279,287 ---- { struct tm *p; errno = 0; + #if defined(macintosh) && defined(USE_GUSI2) + when = when + GUSI_TO_MSL_EPOCH; + #endif p = function(&when); if (p == NULL) { #ifdef EINVAL *************** *** 480,485 **** --- 491,499 ---- if (!PyArg_Parse(args, "d", &dt)) return NULL; tt = (time_t)dt; + #if defined(macintosh) && defined(USE_GUSI2) + tt = tt + GUSI_TO_MSL_EPOCH; + #endif p = ctime(&tt); if (p == NULL) { PyErr_SetString(PyExc_ValueError, "unconvertible time"); *************** *** 517,522 **** --- 531,539 ---- "mktime argument out of range"); return NULL; } + #if defined(macintosh) && defined(USE_GUSI2) + tt = tt - GUSI_TO_MSL_EPOCH; + #endif return PyFloat_FromDouble((double)tt); } --------------85E38E06D9657C4E356D2881-- From mal@lemburg.com Thu Apr 27 17:17:34 2000 From: mal@lemburg.com (M.-A. Lemburg) Date: Thu, 27 Apr 2000 18:17:34 +0200 Subject: [Patches] Unicode Patch Set 2000-04-27 Message-ID: <3908681E.993B2FE0@lemburg.com> This is a multi-part message in MIME format. --------------473E418C86175FAFC293B440 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Patch Set Contents: ------------------- Modules/_tkinter.c: Fixes a memory leak found by Fredrik Lundh. Objects/funcobject.c: Doc strings can now be given as Unicode strings. Objects/unicodeobject.c: Fixed a reference leak in the allocator. Renamed utf8_string to _PyUnicode_AsUTF8String() and made it external for use by other parts of the interpreter. Python/getargs.c: Fixed a memory leak found by Fredrik Lundh. Instead of PyUnicode_AsUTF8String() we now use _PyUnicode_AsUTF8String() which returns the string object without incremented refcount (and assures that the so obtained object remains alive until the Unicode object is garbage collected). -- Marc-Andre Lemburg ______________________________________________________________________ Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ --------------473E418C86175FAFC293B440 Content-Type: text/plain; charset=us-ascii; name="Unicode-Implementation-2000-04-27.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="Unicode-Implementation-2000-04-27.patch" Only in CVS-Python/Lib/test/output: test_winsound diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x configure -x *.bak -x *.s -x DEADJOE -x *.rej -x *.orig -x Demo -x CVS -x Doc -x *.orig -x .#* -x distutils -x PC -x PCbuild -x *.py -x ACKS -x *.txt -x README CVS-Python/Modules/_tkinter.c Python+Unicode/Modules/_tkinter.c --- CVS-Python/Modules/_tkinter.c Fri Mar 31 05:29:39 2000 +++ Python+Unicode/Modules/_tkinter.c Thu Apr 27 17:37:24 2000 @@ -553,8 +553,10 @@ PyObject* utf8 = PyUnicode_AsUTF8String (value); if (!utf8) return 0; - return Tcl_NewStringObj (PyString_AS_STRING (utf8), + result = Tcl_NewStringObj (PyString_AS_STRING (utf8), PyString_GET_SIZE (utf8)); + Py_DECREF(utf8); + return result; } else { PyObject *v = PyObject_Str(value); diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x configure -x *.bak -x *.s -x DEADJOE -x *.rej -x *.orig -x Demo -x CVS -x Doc -x *.orig -x .#* -x distutils -x PC -x PCbuild -x *.py -x ACKS -x *.txt -x README CVS-Python/Objects/funcobject.c Python+Unicode/Objects/funcobject.c --- CVS-Python/Objects/funcobject.c Fri May 22 02:55:34 1998 +++ Python+Unicode/Objects/funcobject.c Thu Apr 13 18:07:29 2000 @@ -55,7 +55,7 @@ consts = ((PyCodeObject *)code)->co_consts; if (PyTuple_Size(consts) >= 1) { doc = PyTuple_GetItem(consts, 0); - if (!PyString_Check(doc)) + if (!PyString_Check(doc) && !PyUnicode_Check(doc)) doc = Py_None; } else diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x configure -x *.bak -x *.s -x DEADJOE -x *.rej -x *.orig -x Demo -x CVS -x Doc -x *.orig -x .#* -x distutils -x PC -x PCbuild -x *.py -x ACKS -x *.txt -x README CVS-Python/Objects/unicodeobject.c Python+Unicode/Objects/unicodeobject.c --- CVS-Python/Objects/unicodeobject.c Thu Apr 13 11:11:39 2000 +++ Python+Unicode/Objects/unicodeobject.c Thu Apr 27 17:51:23 2000 @@ -208,8 +208,7 @@ if ((unicode->length < length) && _PyUnicode_Resize(unicode, length)) { free(unicode->str); - PyMem_DEL(unicode); - return NULL; + goto onError; } } else @@ -222,8 +221,10 @@ unicode->str = PyMem_NEW(Py_UNICODE, length + 1); } - if (!unicode->str) + if (!unicode->str) { + PyErr_NoMemory(); goto onError; + } unicode->str[length] = 0; unicode->length = length; unicode->hash = -1; @@ -233,7 +234,6 @@ onError: _Py_ForgetReference((PyObject *)unicode); PyMem_DEL(unicode); - PyErr_NoMemory(); return NULL; } @@ -707,25 +707,27 @@ The resulting string is cached in the Unicode object for subsequent usage by this function. The cached version is needed to implement - the character buffer interface. + the character buffer interface and will live (at least) as long as + the Unicode object itself. The refcount of the string is *not* incremented. + *** Exported for internal use by the interpreter only !!! *** + */ -static -PyObject *utf8_string(PyUnicodeObject *self, +PyObject *_PyUnicode_AsUTF8String(PyObject *unicode, const char *errors) { - PyObject *v = self->utf8str; + PyObject *v = ((PyUnicodeObject *)unicode)->utf8str; if (v) return v; - v = PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(self), - PyUnicode_GET_SIZE(self), + v = PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(unicode), + PyUnicode_GET_SIZE(unicode), errors); if (v && errors == NULL) - self->utf8str = v; + ((PyUnicodeObject *)unicode)->utf8str = v; return v; } @@ -737,7 +739,7 @@ PyErr_BadArgument(); return NULL; } - str = utf8_string((PyUnicodeObject *)unicode, NULL); + str = _PyUnicode_AsUTF8String(unicode, NULL); if (str == NULL) return NULL; Py_INCREF(str); @@ -3183,7 +3185,7 @@ on. */ if (self->hash != -1) return self->hash; - utf8 = utf8_string(self, NULL); + utf8 = _PyUnicode_AsUTF8String((PyObject *)self, NULL); if (utf8 == NULL) return -1; hash = PyObject_Hash(utf8); @@ -4087,7 +4089,7 @@ "accessing non-existent unicode segment"); return -1; } - str = utf8_string(self, NULL); + str = _PyUnicode_AsUTF8String((PyObject *)self, NULL); if (str == NULL) return -1; *ptr = (void *) PyString_AS_STRING(str); diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x configure -x *.bak -x *.s -x DEADJOE -x *.rej -x *.orig -x Demo -x CVS -x Doc -x *.orig -x .#* -x distutils -x PC -x PCbuild -x *.py -x ACKS -x *.txt -x README CVS-Python/Python/getargs.c Python+Unicode/Python/getargs.c --- CVS-Python/Python/getargs.c Tue Mar 28 22:29:59 2000 +++ Python+Unicode/Python/getargs.c Thu Apr 27 17:51:08 2000 @@ -444,6 +444,11 @@ } +/* Internal API needed by convertsimple1(): */ +extern +PyObject *_PyUnicode_AsUTF8String(PyObject *unicode, + const char *errors); + /* Convert a non-tuple argument. Return NULL if conversion went OK, or a string representing the expected type if the conversion failed. When failing, an exception may or may not have been raised. @@ -589,7 +594,7 @@ if (PyString_Check(arg)) *p = PyString_AS_STRING(arg); else if (PyUnicode_Check(arg)) { - arg = PyUnicode_AsUTF8String(arg); + arg = _PyUnicode_AsUTF8String(arg, NULL); if (arg == NULL) return "unicode conversion error"; *p = PyString_AS_STRING(arg); @@ -634,7 +639,7 @@ else if (PyString_Check(arg)) *p = PyString_AsString(arg); else if (PyUnicode_Check(arg)) { - arg = PyUnicode_AsUTF8String(arg); + arg = _PyUnicode_AsUTF8String(arg, NULL); if (arg == NULL) return "unicode conversion error"; *p = PyString_AS_STRING(arg); Only in CVS-Python/Lib/test: test_winsound.py --------------473E418C86175FAFC293B440-- From mhammond@skippinet.com.au Fri Apr 28 00:15:10 2000 From: mhammond@skippinet.com.au (Mark Hammond) Date: Fri, 28 Apr 2000 09:15:10 +1000 Subject: [Patches] Change to reference-dump procedure at shutdown In-Reply-To: Message-ID: I havent seen a response to this yet. Would you like me to submit again with the MS_WINDOWS #defines? Mark. > > > If this patch is acceptable and it is felt this > > variable should be documented, let me know, and I will > > try and hunt down all the relevant places - but IMO, > > anyone who really needs these references dumped is likely > > to see this code :-) > > > > Mark, shouldn't this be enclosed in an #ifdef > MS_WINDOWS bracket? > > Quite possibly. However, I was assuming that given there > are over 2000 references outstanding when just starting > and stopping the interpreter, the behaviour made sense > for _all_ platforms, not just Windows. > > Of course, just getting it for Windows still suits me fine... From guido@python.org Fri Apr 28 00:17:04 2000 From: guido@python.org (Guido van Rossum) Date: Thu, 27 Apr 2000 19:17:04 -0400 Subject: [Patches] Change to reference-dump procedure at shutdown In-Reply-To: Your message of "Fri, 28 Apr 2000 09:15:10 +1000." References: Message-ID: <200004272317.TAA15007@eric.cnri.reston.va.us> > I havent seen a response to this yet. Would you like me to submit > again with the MS_WINDOWS #defines? Yes, please do. My time is overbooked. :-( --Guido van Rossum (home page: http://www.python.org/~guido/) From cgw@fnal.gov Fri Apr 28 00:29:28 2000 From: cgw@fnal.gov (Charles G Waldman) Date: Thu, 27 Apr 2000 18:29:28 -0500 (CDT) Subject: [Patches] nice speedup for compile.c Message-ID: <14600.52568.898364.667776@buffalo.fnal.gov> This implements an idea suggested in one of the /*XXX*/ comments in compile.c With this patch in place, the time required to import a 5000-line file (with lots of constants in it) is reduced from 15 seconds to under 3 seconds on my system. I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. Index: Python/compile.c =================================================================== RCS file: /projects/cvsroot/python/dist/src/Python/compile.c,v retrieving revision 2.105 diff -c -r2.105 compile.c *** compile.c 2000/04/13 14:10:44 2.105 --- compile.c 2000/04/27 23:26:20 *************** *** 300,307 **** struct compiling { PyObject *c_code; /* string */ ! PyObject *c_consts; /* list of objects */ ! PyObject *c_names; /* list of strings (names) */ PyObject *c_globals; /* dictionary (value=None) */ PyObject *c_locals; /* dictionary (value=localID) */ PyObject *c_varnames; /* list (inverse of c_locals) */ --- 300,309 ---- struct compiling { PyObject *c_code; /* string */ ! PyObject *c_consts; /* dictionary of objects */ ! PyObject *c_const_list; /* inverse of c_consts */ ! PyObject *c_names; /* dictionary of strings (names) */ ! PyObject *c_name_list; /* inverse of c_names */ PyObject *c_globals; /* dictionary (value=None) */ PyObject *c_locals; /* dictionary (value=localID) */ PyObject *c_varnames; /* list (inverse of c_locals) */ *************** *** 403,409 **** static void com_addoparg Py_PROTO((struct compiling *, int, int)); static void com_addfwref Py_PROTO((struct compiling *, int, int *)); static void com_backpatch Py_PROTO((struct compiling *, int)); ! static int com_add Py_PROTO((struct compiling *, PyObject *, PyObject *)); static int com_addconst Py_PROTO((struct compiling *, PyObject *)); static int com_addname Py_PROTO((struct compiling *, PyObject *)); static void com_addopname Py_PROTO((struct compiling *, int, node *)); --- 405,411 ---- static void com_addoparg Py_PROTO((struct compiling *, int, int)); static void com_addfwref Py_PROTO((struct compiling *, int, int *)); static void com_backpatch Py_PROTO((struct compiling *, int)); ! static int com_add Py_PROTO((struct compiling *, PyObject *, PyObject *, PyObject *)); static int com_addconst Py_PROTO((struct compiling *, PyObject *)); static int com_addname Py_PROTO((struct compiling *, PyObject *)); static void com_addopname Py_PROTO((struct compiling *, int, node *)); *************** *** 421,442 **** struct compiling *c; char *filename; { if ((c->c_code = PyString_FromStringAndSize((char *)NULL, 1000)) == NULL) ! goto fail_3; ! if ((c->c_consts = PyList_New(0)) == NULL) ! goto fail_2; ! if ((c->c_names = PyList_New(0)) == NULL) ! goto fail_1; if ((c->c_globals = PyDict_New()) == NULL) ! goto fail_0; if ((c->c_locals = PyDict_New()) == NULL) ! goto fail_00; if ((c->c_varnames = PyList_New(0)) == NULL) ! goto fail_000; if ((c->c_lnotab = PyString_FromStringAndSize((char *)NULL, 1000)) == NULL) ! goto fail_0000; c->c_nlocals = 0; c->c_argcount = 0; c->c_flags = 0; --- 423,449 ---- struct compiling *c; char *filename; { + memset((void *)c, '\0', sizeof(struct compiling)); if ((c->c_code = PyString_FromStringAndSize((char *)NULL, 1000)) == NULL) ! goto fail; ! if ((c->c_consts = PyDict_New()) == NULL) ! goto fail; ! if ((c->c_const_list = PyList_New(0)) == NULL) ! goto fail; ! if ((c->c_names = PyDict_New()) == NULL) ! goto fail; ! if ((c->c_name_list = PyList_New(0)) == NULL) ! goto fail; if ((c->c_globals = PyDict_New()) == NULL) ! goto fail; if ((c->c_locals = PyDict_New()) == NULL) ! goto fail; if ((c->c_varnames = PyList_New(0)) == NULL) ! goto fail; if ((c->c_lnotab = PyString_FromStringAndSize((char *)NULL, 1000)) == NULL) ! goto fail; c->c_nlocals = 0; c->c_argcount = 0; c->c_flags = 0; *************** *** 458,476 **** c-> c_lnotab_next = 0; return 1; ! fail_0000: ! Py_DECREF(c->c_varnames); ! fail_000: ! Py_DECREF(c->c_locals); ! fail_00: ! Py_DECREF(c->c_globals); ! fail_0: ! Py_DECREF(c->c_names); ! fail_1: ! Py_DECREF(c->c_consts); ! fail_2: ! Py_DECREF(c->c_code); ! fail_3: return 0; } --- 465,472 ---- c-> c_lnotab_next = 0; return 1; ! fail: ! com_free(c); return 0; } *************** *** 480,486 **** --- 476,484 ---- { Py_XDECREF(c->c_code); Py_XDECREF(c->c_consts); + Py_XDECREF(c->c_const_list); Py_XDECREF(c->c_names); + Py_XDECREF(c->c_name_list); Py_XDECREF(c->c_globals); Py_XDECREF(c->c_locals); Py_XDECREF(c->c_varnames); *************** *** 665,688 **** /* Handle literals and names uniformly */ static int ! com_add(c, list, v) struct compiling *c; PyObject *list; PyObject *v; { ! int n = PyList_Size(list); ! int i; ! /* XXX This is quadratic in the number of names per compilation unit. ! XXX Should use a dictionary. */ ! for (i = n; --i >= 0; ) { ! PyObject *w = PyList_GetItem(list, i); ! if (v->ob_type == w->ob_type && PyObject_Compare(v, w) == 0) ! return i; } ! /* Check for error from PyObject_Compare */ ! if (PyErr_Occurred() || PyList_Append(list, v) != 0) ! c->c_errors++; return n; } static int --- 663,706 ---- /* Handle literals and names uniformly */ static int ! com_add(c, dict, list, v) struct compiling *c; + PyObject *dict; PyObject *list; PyObject *v; { ! PyObject *w, *t=NULL, *np=NULL; ! int n; ! ! t = PyTuple_New(2); ! if (t == NULL) ! goto fail; ! PyTuple_SetItem(t, 0, v); ! Py_INCREF(v); ! PyTuple_SetItem(t, 1, (PyObject *)v->ob_type); ! Py_INCREF(v->ob_type); ! w = PyDict_GetItem(dict, t); ! if (PyErr_Occurred()) /* check for error from Py_ObjectCompare */ ! goto fail; ! if (w){ ! n = PyInt_AsLong(w); ! } else { ! n = PyList_Size(list); ! if ((np = PyInt_FromLong((long)n)) == NULL) ! goto fail; ! if (PyList_Append(list, v) != 0) ! goto fail; ! if (PyDict_SetItem(dict, t, np) != 0) ! goto fail; ! Py_DECREF(np); } ! Py_DECREF(t); return n; + fail: + Py_XDECREF(np); + Py_XDECREF(t); + c->c_errors++; + return 0; } static int *************** *** 690,696 **** struct compiling *c; PyObject *v; { ! return com_add(c, c->c_consts, v); } static int --- 708,714 ---- struct compiling *c; PyObject *v; { ! return com_add(c, c->c_consts, c->c_const_list, v); } static int *************** *** 698,704 **** struct compiling *c; PyObject *v; { ! return com_add(c, c->c_names, v); } #ifdef PRIVATE_NAME_MANGLING --- 716,722 ---- struct compiling *c; PyObject *v; { ! return com_add(c, c->c_names, c->c_name_list, v); } #ifdef PRIVATE_NAME_MANGLING *************** *** 3373,3379 **** #define NEXTOP() (*next_instr++) #define NEXTARG() (next_instr += 2, (next_instr[-1]<<8) + next_instr[-2]) #define GETITEM(v, i) (PyList_GetItem((v), (i))) ! #define GETNAMEOBJ(i) (GETITEM(c->c_names, (i))) PyErr_Fetch(&error_type, &error_value, &error_traceback); --- 3391,3397 ---- #define NEXTOP() (*next_instr++) #define NEXTARG() (next_instr += 2, (next_instr[-1]<<8) + next_instr[-2]) #define GETITEM(v, i) (PyList_GetItem((v), (i))) ! #define GETNAMEOBJ(i) (GETITEM(c->c_name_list, (i))) PyErr_Fetch(&error_type, &error_value, &error_traceback); *************** *** 3480,3487 **** co = NULL; if (sc.c_errors == 0) { PyObject *consts, *names, *varnames, *filename, *name; ! consts = PyList_AsTuple(sc.c_consts); ! names = PyList_AsTuple(sc.c_names); varnames = PyList_AsTuple(sc.c_varnames); filename = PyString_InternFromString(sc.c_filename); name = PyString_InternFromString(sc.c_name); --- 3498,3505 ---- co = NULL; if (sc.c_errors == 0) { PyObject *consts, *names, *varnames, *filename, *name; ! consts = PyList_AsTuple(sc.c_const_list); ! names = PyList_AsTuple(sc.c_name_list); varnames = PyList_AsTuple(sc.c_varnames); filename = PyString_InternFromString(sc.c_filename); name = PyString_InternFromString(sc.c_name); From mhammond@skippinet.com.au Fri Apr 28 00:33:21 2000 From: mhammond@skippinet.com.au (Mark Hammond) Date: Fri, 28 Apr 2000 09:33:21 +1000 Subject: [Patches] Modified patch for refcount dumping procedure. Message-ID: This is a modification to my recent patch. The new behaviour is now only for Windows. Checkin message: For Windows debug builds, we now only offer to dump remaining object references if the environment variable PYTHONDUMPREFS exists. The default behaviour caused problems for background or otherwise invisible processes that use the debug build of Python. diff -c -r2.92 pythonrun.c *** pythonrun.c 2000/04/14 19:13:24 2.92 --- pythonrun.c 2000/04/27 23:29:26 *************** *** 242,248 **** #endif #ifdef Py_TRACE_REFS ! if (_Py_AskYesNo("Print left references?")) { _Py_PrintReferences(stderr); } #endif /* Py_TRACE_REFS */ --- 242,252 ---- #endif #ifdef Py_TRACE_REFS ! if ( ! #ifdef MS_WINDOWS /* Only ask on Windows if env var set */ ! getenv("PYTHONDUMPREFS") && ! #endif /* MS_WINDOWS */ ! _Py_AskYesNo("Print left references?")) { _Py_PrintReferences(stderr); } #endif /* Py_TRACE_REFS */ Release info: I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. Mark. From mal@lemburg.com Fri Apr 28 10:19:45 2000 From: mal@lemburg.com (M.-A. Lemburg) Date: Fri, 28 Apr 2000 11:19:45 +0200 Subject: [Patches] nice speedup for compile.c References: <14600.52568.898364.667776@buffalo.fnal.gov> Message-ID: <390957B1.76F6F199@lemburg.com> I haven't tried the patch, but from looking at it, I guess it would be better to leave the old names (c_names and c_consts) together with their previous semantics in place and add new c_consts_dict and c_names_dict objects to the end of the compiling structure. -- Marc-Andre Lemburg ______________________________________________________________________ Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ From sjoerd@oratrix.nl Fri Apr 28 11:35:54 2000 From: sjoerd@oratrix.nl (Sjoerd Mullender) Date: Fri, 28 Apr 2000 12:35:54 +0200 Subject: [Patches] freeze patch Message-ID: <20000428103555.B79E8301CF9@bireme.oratrix.nl> cmp.py is obsolete... Index: bkfile.py =================================================================== RCS file: /projects/cvsroot/python/dist/src/Tools/freeze/bkfile.py,v retrieving revision 1.1 diff -u -r1.1 bkfile.py --- bkfile.py 1998/08/25 14:06:51 1.1 +++ bkfile.py 2000/04/28 10:32:51 @@ -35,11 +35,8 @@ self.__file.close() if self.__backup is None: return - import cmp - # don't use cmp.cmp because of NFS bugs :-( and - # anyway, the stat mtime values differ so do_cmp will - # most likely be called anyway - if cmp.do_cmp(self.__backup, self.__filename): + import filecmp + if filecmp.cmp(self.__backup, self.__filename, shallow = 0): import os os.unlink(self.__filename) os.rename(self.__backup, self.__filename) I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. -- Sjoerd Mullender From take.vos@travelunie.nl Fri Apr 28 14:23:32 2000 From: take.vos@travelunie.nl (Take Vos) Date: Fri, 28 Apr 2000 15:23:32 +0200 (CEST) Subject: [Patches] port to NCR MP-RAS (sys V unix) Message-ID: <00Apr28.152457cest.116002@ds1.travelunie.nl> This message is in MIME format --_=XFMail.1.4.4.Linux:20000428152332:724=_ Content-Type: text/plain; charset=us-ascii what it does: port to NCR MP-RAS (Sys V unix) changes: Makefile.in Use the dgux style compiling, to create a shared library from libpython.a, as NCR MP-RAS dlopen() doesn't have access to the symbols in the executable, but it has access to the symbols which are loaded in from a shared library. I guess dgux, is very similar. unix_sv is the uname -s name of NCR MP-RAS. I also copied this libpython.so to the Modules directory, so it will be linked into the python executable without the leading ../ which confuses the runtime loader to find the library from the LD_LIBRARY_PATH (or the defaults path). These changes are also found in Modules/Makefile.pre.in configure I had to edit configure, I guess there has never been ported GNU software to MP-RAS :-), and I probably had to edit configure.in but I don't have the development tools for configure. Anyway, I copied the special dgux stuff for MP-RAS. Added the -Hnocopyr to the OPT variable, so the compiler won't print the anoying copyright line. Also when checking for -OPT:Olimit=0 and -Olimit 1500, I let it be cached to "no" state, becuase the compiler accepts this options but says, "Don't know this optimilization option, turning off optimilization" also shared libraries are build with ld -G. That was it and that was that. Sorry that I didn't patch it against the CVS tree, but I am under high time pressure. The disclamer: I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. -- Take Vos --_=XFMail.1.4.4.Linux:20000428152332:724=_ Content-Disposition: attachment; filename="Python-1.5.2-mpras.patch" Content-Transfer-Encoding: base64 Content-Description: Python-1.5.2-mpras.patch Content-Type: application/octet-stream; name=Python-1.5.2-mpras.patch; SizeOnDisk=4943 ZGlmZiAtYyBQeXRob24tMS41LjIvTWFrZWZpbGUuaW4gUHl0aG9uLTEuNS4yLW1wcmFzL01ha2Vm aWxlLmluCioqKiBQeXRob24tMS41LjIvTWFrZWZpbGUuaW4JVHVlIEZlYiAyMyAxNjo0MzoxNSAx OTk5Ci0tLSBQeXRob24tMS41LjItbXByYXMvTWFrZWZpbGUuaW4JRnJpIEFwciAyOCAxNDoyNDow MSAyMDAwCioqKioqKioqKioqKioqKgoqKiogMTc3LDE4MyAqKioqCiAgCQlATUFLRV9MRExJQlJB UllACiAgCQljZCBNb2R1bGVzOyAgJChNQUtFKSBPUFQ9IiQoT1BUKSIgVkVSU0lPTj0iJChWRVJT SU9OKSIgXAogIAkJCXByZWZpeD0iJChwcmVmaXgpIiBleGVjX3ByZWZpeD0iJChleGVjX3ByZWZp eCkiIFwKISAJCQlMSUJSQVJZPS4uLyQoTERMSUJSQVJZKSBsaW5rCiAgCiAgTW9kdWxlcy9weXRo b24ubzogJChzcmNkaXIpL01vZHVsZXMvcHl0aG9uLmMKICAJCWNkIE1vZHVsZXM7ICQoTUFLRSkg T1BUPSIkKE9QVCkiIHB5dGhvbi5vCi0tLSAxNzcsMTgzIC0tLS0KICAJCUBNQUtFX0xETElCUkFS WUAKICAJCWNkIE1vZHVsZXM7ICAkKE1BS0UpIE9QVD0iJChPUFQpIiBWRVJTSU9OPSIkKFZFUlNJ T04pIiBcCiAgCQkJcHJlZml4PSIkKHByZWZpeCkiIGV4ZWNfcHJlZml4PSIkKGV4ZWNfcHJlZml4 KSIgXAohIAkJCUxJQlJBUlk9JChMRExJQlJBUlkpIGxpbmsKICAKICBNb2R1bGVzL3B5dGhvbi5v OiAkKHNyY2RpcikvTW9kdWxlcy9weXRob24uYwogIAkJY2QgTW9kdWxlczsgJChNQUtFKSBPUFQ9 IiQoT1BUKSIgcHl0aG9uLm8KKioqKioqKioqKioqKioqCioqKiAxOTcsMjEzICoqKioKICAJCXRo ZW4gZm9yIGkgaW4gJChTVUJESVJTKTsgZG8gcm0gLWYgJCRpL2FkZDJsaWI7IGRvbmU7IHRydWU7 IFwKICAJCWVsc2UgdHJ1ZTsgZmkKICAJCWZvciBpIGluICQoU1VCRElSUyk7IGRvIFwKISAJCQko Y2QgJCRpOyAkKE1BS0UpIFZFUlNJT049IiQoVkVSU0lPTikiIGFkZDJsaWIpOyBkb25lCiAgCiAg IyBUaGlzIHJ1bGUgaXMgb25seSBoZXJlIGZvciBERy9VWCEhIQogIGxpYnB5dGhvbiQoVkVSU0lP Tikuc286CSQoTElCUkFSWSkKICAJCWNhc2UgYHVuYW1lIC1zIHwgdHIgLWQgJy8gJyB8IHRyICdb QS1aXScgJ1thLXpdJ2AgaW4gXAogIAkJKmRndXgqKSBcCiEgCQkgICAgdGVzdCAtZCBkZ3V4IHx8 IG1rZGlyIGRndXg7IFwKISAJCSAgICAoY2QgZGd1eDthciB4IC4uLyReO2xkIC1HIC1vIC4uLyRA ICogKTsgXAohIAkJICAgIC9iaW4vcm0gLXJmIC4vZGd1eCBcCiAgCQkgICAgOzsgXAohIAkJZXNh YwogIAogICMgVGhpcyBydWxlIGlzIGhlcmUgZm9yIE9QRU5TVEVQL1JoYXBzb2R5L01hY09TWAog IGxpYnB5dGhvbiQoVkVSU0lPTikuZHlsaWI6ICQoTElCUkFSWSkKLS0tIDE5NywyMjAgLS0tLQog IAkJdGhlbiBmb3IgaSBpbiAkKFNVQkRJUlMpOyBkbyBybSAtZiAkJGkvYWRkMmxpYjsgZG9uZTsg dHJ1ZTsgXAogIAkJZWxzZSB0cnVlOyBmaQogIAkJZm9yIGkgaW4gJChTVUJESVJTKTsgZG8gXAoh IAkJCShjZCAkJGk7ICQoTUFLRSkgVkVSU0lPTj0iJChWRVJTSU9OKSIgYWRkMmxpYik7IGRvbmU7 XAohIAkJY3AgJEAgTW9kdWxlcwogIAogICMgVGhpcyBydWxlIGlzIG9ubHkgaGVyZSBmb3IgREcv VVghISEKICBsaWJweXRob24kKFZFUlNJT04pLnNvOgkkKExJQlJBUlkpCiAgCQljYXNlIGB1bmFt ZSAtcyB8IHRyIC1kICcvICcgfCB0ciAnW0EtWl0nICdbYS16XSdgIGluIFwKICAJCSpkZ3V4Kikg XAohIAkJICAgIHRlc3QgLWQgc2hsaWIgfHwgbWtkaXIgc2hsaWI7IFwKISAJCSAgICAoY2Qgc2hs aWI7YXIgeCAuLi8kXjtsZCAtRyAtbyAuLi8kQCAqICk7IFwKISAJCSAgICAvYmluL3JtIC1yZiAu L3NobGliIFwKICAJCSAgICA7OyBcCiEgCQkqdW5peF9zdiopIFwKISAJCSAgICB0ZXN0IC1kIHNo bGliIHx8IG1rZGlyIHNobGliOyBcCiEgCQkgICAgKGNkIHNobGliO2FyIHggLi4vJF47bGQgLUcg LW8gLi4vJEAgKiApOyBcCiEgCQkgICAgL2Jpbi9ybSAtcmYgLi9zaGxpYiBcCiEgCQkgICAgOzsg XAohIAkJZXNhYztcCiEgCQljcCAkQCBNb2R1bGVzCiAgCiAgIyBUaGlzIHJ1bGUgaXMgaGVyZSBm b3IgT1BFTlNURVAvUmhhcHNvZHkvTWFjT1NYCiAgbGlicHl0aG9uJChWRVJTSU9OKS5keWxpYjog JChMSUJSQVJZKQpkaWZmIC1jIFB5dGhvbi0xLjUuMi9jb25maWd1cmUgUHl0aG9uLTEuNS4yLW1w cmFzL2NvbmZpZ3VyZQoqKiogUHl0aG9uLTEuNS4yL2NvbmZpZ3VyZQlTYXQgQXByIDEwIDE4OjAy OjE4IDE5OTkKLS0tIFB5dGhvbi0xLjUuMi1tcHJhcy9jb25maWd1cmUJVGh1IEFwciAyNyAxMjox NDozMiAyMDAwCioqKioqKioqKioqKioqKgoqKiogMTAwNCwxMDA5ICoqKioKLS0tIDEwMDQsMTAx MSAtLS0tCiAgCSAgIExETElCUkFSWT0nbGlicHl0aG9uJChWRVJTSU9OKS5zbyc7OwogIAlkZ3V4 KikKICAJICAgTElOS0NDPSJMRF9SVU5fUEFUSD0kbGliZGlyIFwkKFBVUklGWSkgXCQoQ0MpIjs7 CisgCXVuaXhfc3YqKQorIAkgICBMSU5LQ0M9IkxEX1JVTl9QQVRIPSRsaWJkaXIgXCQoUFVSSUZZ KSBcJChDQykiOzsKICAJKikgTElOS0NDPSJcJChQVVJJRlkpIFwkKENDKSI7OwogIAllc2FjCiAg ZmkKKioqKioqKioqKioqKioqCioqKiAxMDIwLDEwMzAgKioqKgogIGZpICAKICAKICAjIERHL1VY IHJlcXVpcmVzIHNvbWUgZmFuY3kgbGQgY29udG9ydGlvbnMgdG8gcHJvZHVjZSBhIC5zbyBmcm9t IGFuIC5hCiEgaWYgdGVzdCAiJE1BQ0hERVAiID0gImRndXhSNCIKISB0aGVuCiAgICBMRExJQlJB Ulk9J2xpYnB5dGhvbiQoVkVSU0lPTikuc28nCiAgICBPUFQ9IiRPUFQgLXBpYyIKISBmaQogIGVj aG8gIiRhY190IiIkTERMSUJSQVJZIiAxPiY2CiAgCiAgIyBJZiBMRExJQlJBUlkgaXMgZGlmZmVy ZW50IGZyb20gTElCUkFSWSwgZW1pdCBhIHJ1bGUgdG8gYnVpbGQgaXQuCi0tLSAxMDIyLDEwMzcg LS0tLQogIGZpICAKICAKICAjIERHL1VYIHJlcXVpcmVzIHNvbWUgZmFuY3kgbGQgY29udG9ydGlv bnMgdG8gcHJvZHVjZSBhIC5zbyBmcm9tIGFuIC5hCiEgY2FzZSAkTUFDSERFUCBpbgohIGRndXhS NCopCiAgICBMRExJQlJBUlk9J2xpYnB5dGhvbiQoVkVSU0lPTikuc28nCiAgICBPUFQ9IiRPUFQg LXBpYyIKISAgIDs7CiEgdW5peF9zdiopCiEgICBMRExJQlJBUlk9J2xpYnB5dGhvbiQoVkVSU0lP Tikuc28nCiEgICBPUFQ9IiRPUFQgLUhub2NvcHlyIC1waWMiCiEgICA7OwohIGVzYWMKICBlY2hv ICIkYWNfdCIiJExETElCUkFSWSIgMT4mNgogIAogICMgSWYgTERMSUJSQVJZIGlzIGRpZmZlcmVu dCBmcm9tIExJQlJBUlksIGVtaXQgYSBydWxlIHRvIGJ1aWxkIGl0LgoqKioqKioqKioqKioqKioK KioqIDEyOTgsMTMwNiAqKioqCiAgCiAgZmkKICAKLSAKICBlY2hvICRhY19uICJjaGVja2luZyB3 aGV0aGVyICRDQyBhY2NlcHRzIC1PUFQ6T2xpbWl0PTAiIi4uLiAkYWNfYyIgMT4mNgogIGVjaG8g ImNvbmZpZ3VyZToxMzA0OiBjaGVja2luZyB3aGV0aGVyICRDQyBhY2NlcHRzIC1PUFQ6T2xpbWl0 PTAiID4mNQogIGlmIGV2YWwgInRlc3QgXCJgZWNobyAnJCcneydhY19jdl9vcHRfb2xpbWl0X29r JytzZXR9J2BcIiA9IHNldCI7IHRoZW4KICAgIGVjaG8gJGFjX24gIihjYWNoZWQpICRhY19jIiAx PiY2CiAgZWxzZQotLS0gMTMwNSwxMzE2IC0tLS0KICAKICBmaQogIAogIGVjaG8gJGFjX24gImNo ZWNraW5nIHdoZXRoZXIgJENDIGFjY2VwdHMgLU9QVDpPbGltaXQ9MCIiLi4uICRhY19jIiAxPiY2 CiAgZWNobyAiY29uZmlndXJlOjEzMDQ6IGNoZWNraW5nIHdoZXRoZXIgJENDIGFjY2VwdHMgLU9Q VDpPbGltaXQ9MCIgPiY1CisgY2FzZSAkTUFDSERFUCBpbgorIHVuaXhfc3YqKQorIAlhY19jdl9v cHRfb2xpbWl0X29rPW5vOzsKKyBlc2FjCiAgaWYgZXZhbCAidGVzdCBcImBlY2hvICckJyd7J2Fj X2N2X29wdF9vbGltaXRfb2snK3NldH0nYFwiID0gc2V0IjsgdGhlbgogICAgZWNobyAkYWNfbiAi KGNhY2hlZCkgJGFjX2MiIDE+JjYKICBlbHNlCioqKioqKioqKioqKioqKgoqKiogMTMzNCwxMzQw ICoqKioKICAgIE9QVD0iJE9QVCAtT1BUOk9saW1pdD0wIgogIGVsc2UKICAgIGVjaG8gJGFjX24g ImNoZWNraW5nIHdoZXRoZXIgJENDIGFjY2VwdHMgLU9saW1pdCAxNTAwIiIuLi4gJGFjX2MiIDE+ JjYKISBlY2hvICJjb25maWd1cmU6MTMzODogY2hlY2tpbmcgd2hldGhlciAkQ0MgYWNjZXB0cyAt T2xpbWl0IDE1MDAiID4mNQogICAgaWYgZXZhbCAidGVzdCBcImBlY2hvICckJyd7J2FjX2N2X29s aW1pdF9vaycrc2V0fSdgXCIgPSBzZXQiOyB0aGVuCiAgICBlY2hvICRhY19uICIoY2FjaGVkKSAk YWNfYyIgMT4mNgogIGVsc2UKLS0tIDEzNDQsMTM1NCAtLS0tCiAgICBPUFQ9IiRPUFQgLU9QVDpP bGltaXQ9MCIKICBlbHNlCiAgICBlY2hvICRhY19uICJjaGVja2luZyB3aGV0aGVyICRDQyBhY2Nl cHRzIC1PbGltaXQgMTUwMCIiLi4uICRhY19jIiAxPiY2CiEgICBlY2hvICJjb25maWd1cmU6MTMz ODogY2hlY2tpbmcgd2hldGhlciAkQ0MgYWNjZXB0cyAtT2xpbWl0IDE1MDAiID4mNQohICAgY2Fz ZSAkTUFDSERFUCBpbgohICAgdW5peF9zdiopCiEgCWFjX2N2X29saW1pdF9vaz1ubzs7CiEgICBl c2FjCiAgICBpZiBldmFsICJ0ZXN0IFwiYGVjaG8gJyQnJ3snYWNfY3Zfb2xpbWl0X29rJytzZXR9 J2BcIiA9IHNldCI7IHRoZW4KICAgIGVjaG8gJGFjX24gIihjYWNoZWQpICRhY19jIiAxPiY2CiAg ZWxzZQoqKioqKioqKioqKioqKioKKioqIDIyNDYsMjI1MSAqKioqCi0tLSAyMjYwLDIyNjYgLS0t LQogIAkJZmkgOzsKICAJTGludXgqKSBMRFNIQVJFRD0iZ2NjIC1zaGFyZWQiOzsKICAJZGd1eCop IExEU0hBUkVEPSJsZCAtRyI7OworIAlVTklYX1NWKikgTERTSEFSRUQ9ImxkIC1HIjs7CiAgCUZy ZWVCU0QqLzMqKSBMRFNIQVJFRD0iZ2NjIC1zaGFyZWQiOzsKICAJRnJlZUJTRCp8T3BlbkJTRCop IExEU0hBUkVEPSJsZCAtQnNoYXJlYWJsZSI7OwogIAlOZXRCU0QqKQo= --_=XFMail.1.4.4.Linux:20000428152332:724=_-- End of MIME message From guido@python.org Fri Apr 28 15:11:40 2000 From: guido@python.org (Guido van Rossum) Date: Fri, 28 Apr 2000 10:11:40 -0400 Subject: [Patches] nice speedup for compile.c In-Reply-To: Your message of "Fri, 28 Apr 2000 11:19:45 +0200." <390957B1.76F6F199@lemburg.com> References: <14600.52568.898364.667776@buffalo.fnal.gov> <390957B1.76F6F199@lemburg.com> Message-ID: <200004281411.KAA16128@eric.cnri.reston.va.us> > I haven't tried the patch, but from looking at it, I guess > it would be better to leave the old names (c_names and c_consts) > together with their previous semantics in place and > add new c_consts_dict and c_names_dict objects > to the end of the compiling structure. I concur. Charles, would you mind resubmitting? --Guido van Rossum (home page: http://www.python.org/~guido/) From cgw@fnal.gov Fri Apr 28 16:59:03 2000 From: cgw@fnal.gov (Charles G Waldman) Date: Fri, 28 Apr 2000 10:59:03 -0500 (CDT) Subject: [Patches] Resubmit speedup patch for compile.c In-Reply-To: <200004281411.KAA16128@eric.cnri.reston.va.us> References: <14600.52568.898364.667776@buffalo.fnal.gov> <390957B1.76F6F199@lemburg.com> <200004281411.KAA16128@eric.cnri.reston.va.us> Message-ID: <14601.46407.32803.275261@buffalo.fnal.gov> mal wrote: > I haven't tried the patch, but from looking at it, I guess > it would be better to leave the old names (c_names and c_consts) > together with their previous semantics in place and > add new c_consts_dict and c_names_dict objects > to the end of the compiling structure. Below find the reworked patch. I don't completely agree with the objections, but, whatever makes you and Guido happy is good with me. I can see the objections to changing the semantics of existing variables, however I don't understand why the new members need to be added at the _end_ of the compiling structure. To me this makes the code less readable because it puts related items further away in the source code. The compiling structure is only used internally, so I don't quite see why rearranging it is a problem. But, whatever, I don't want to argue. Disclaimer: I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. Commit notice: Follow a suggestion in an /*XXX*/ comment to speed up compilation by using supplemental dictionaries to keep track of names and constants, eliminating quadratic behavior. With this patch in place, the time to import a 5000-line file with lots of constants is reduced from 20 seconds to under 3 on my system. Patch: Index: Python/compile.c =================================================================== RCS file: /projects/cvsroot/python/dist/src/Python/compile.c,v retrieving revision 2.105 diff -c -r2.105 compile.c *** compile.c 2000/04/13 14:10:44 2.105 --- compile.c 2000/04/28 15:57:48 *************** *** 327,332 **** --- 327,334 ---- #ifdef PRIVATE_NAME_MANGLING char *c_private; /* for private name mangling */ #endif + PyObject *c_const_dict; /* inverse of c_consts */ + PyObject *c_name_dict; /* inverse of c_names */ }; *************** *** 403,409 **** static void com_addoparg Py_PROTO((struct compiling *, int, int)); static void com_addfwref Py_PROTO((struct compiling *, int, int *)); static void com_backpatch Py_PROTO((struct compiling *, int)); ! static int com_add Py_PROTO((struct compiling *, PyObject *, PyObject *)); static int com_addconst Py_PROTO((struct compiling *, PyObject *)); static int com_addname Py_PROTO((struct compiling *, PyObject *)); static void com_addopname Py_PROTO((struct compiling *, int, node *)); --- 405,411 ---- static void com_addoparg Py_PROTO((struct compiling *, int, int)); static void com_addfwref Py_PROTO((struct compiling *, int, int *)); static void com_backpatch Py_PROTO((struct compiling *, int)); ! static int com_add Py_PROTO((struct compiling *, PyObject *, PyObject *, PyObject *)); static int com_addconst Py_PROTO((struct compiling *, PyObject *)); static int com_addname Py_PROTO((struct compiling *, PyObject *)); static void com_addopname Py_PROTO((struct compiling *, int, node *)); *************** *** 421,442 **** struct compiling *c; char *filename; { if ((c->c_code = PyString_FromStringAndSize((char *)NULL, 1000)) == NULL) ! goto fail_3; if ((c->c_consts = PyList_New(0)) == NULL) ! goto fail_2; if ((c->c_names = PyList_New(0)) == NULL) ! goto fail_1; if ((c->c_globals = PyDict_New()) == NULL) ! goto fail_0; if ((c->c_locals = PyDict_New()) == NULL) ! goto fail_00; if ((c->c_varnames = PyList_New(0)) == NULL) ! goto fail_000; if ((c->c_lnotab = PyString_FromStringAndSize((char *)NULL, 1000)) == NULL) ! goto fail_0000; c->c_nlocals = 0; c->c_argcount = 0; c->c_flags = 0; --- 423,449 ---- struct compiling *c; char *filename; { + memset((void *)c, '\0', sizeof(struct compiling)); if ((c->c_code = PyString_FromStringAndSize((char *)NULL, 1000)) == NULL) ! goto fail; if ((c->c_consts = PyList_New(0)) == NULL) ! goto fail; ! if ((c->c_const_dict = PyDict_New()) == NULL) ! goto fail; if ((c->c_names = PyList_New(0)) == NULL) ! goto fail; ! if ((c->c_name_dict = PyDict_New()) == NULL) ! goto fail; if ((c->c_globals = PyDict_New()) == NULL) ! goto fail; if ((c->c_locals = PyDict_New()) == NULL) ! goto fail; if ((c->c_varnames = PyList_New(0)) == NULL) ! goto fail; if ((c->c_lnotab = PyString_FromStringAndSize((char *)NULL, 1000)) == NULL) ! goto fail; c->c_nlocals = 0; c->c_argcount = 0; c->c_flags = 0; *************** *** 458,476 **** c-> c_lnotab_next = 0; return 1; ! fail_0000: ! Py_DECREF(c->c_varnames); ! fail_000: ! Py_DECREF(c->c_locals); ! fail_00: ! Py_DECREF(c->c_globals); ! fail_0: ! Py_DECREF(c->c_names); ! fail_1: ! Py_DECREF(c->c_consts); ! fail_2: ! Py_DECREF(c->c_code); ! fail_3: return 0; } --- 465,472 ---- c-> c_lnotab_next = 0; return 1; ! fail: ! com_free(c); return 0; } *************** *** 480,486 **** --- 476,484 ---- { Py_XDECREF(c->c_code); Py_XDECREF(c->c_consts); + Py_XDECREF(c->c_const_dict); Py_XDECREF(c->c_names); + Py_XDECREF(c->c_name_dict); Py_XDECREF(c->c_globals); Py_XDECREF(c->c_locals); Py_XDECREF(c->c_varnames); *************** *** 665,688 **** /* Handle literals and names uniformly */ static int ! com_add(c, list, v) struct compiling *c; PyObject *list; PyObject *v; { ! int n = PyList_Size(list); ! int i; ! /* XXX This is quadratic in the number of names per compilation unit. ! XXX Should use a dictionary. */ ! for (i = n; --i >= 0; ) { ! PyObject *w = PyList_GetItem(list, i); ! if (v->ob_type == w->ob_type && PyObject_Compare(v, w) == 0) ! return i; ! } ! /* Check for error from PyObject_Compare */ ! if (PyErr_Occurred() || PyList_Append(list, v) != 0) ! c->c_errors++; return n; } static int --- 663,708 ---- /* Handle literals and names uniformly */ static int ! com_add(c, list, dict, v) struct compiling *c; PyObject *list; + PyObject *dict; PyObject *v; { ! PyObject *w, *t=NULL, *np=NULL; ! int n; ! ! t = PyTuple_New(2); ! if (t == NULL) ! goto fail; ! PyTuple_SetItem(t, 0, v); ! Py_INCREF(v); ! /*need to keep track of both value and type, else e.g. 1 and 1L ! are treated as the same constant */ ! PyTuple_SetItem(t, 1, (PyObject *)v->ob_type); ! Py_INCREF(v->ob_type); ! w = PyDict_GetItem(dict, t); ! if (PyErr_Occurred()) /* check for error from Py_ObjectCompare */ ! goto fail; ! if (w){ ! n = PyInt_AsLong(w); ! } else { ! n = PyList_Size(list); ! if ((np = PyInt_FromLong((long)n)) == NULL) ! goto fail; ! if (PyList_Append(list, v) != 0) ! goto fail; ! if (PyDict_SetItem(dict, t, np) != 0) ! goto fail; ! Py_DECREF(np); ! } ! Py_DECREF(t); return n; + fail: + Py_XDECREF(np); + Py_XDECREF(t); + c->c_errors++; + return 0; } static int *************** *** 690,696 **** struct compiling *c; PyObject *v; { ! return com_add(c, c->c_consts, v); } static int --- 710,716 ---- struct compiling *c; PyObject *v; { ! return com_add(c, c->c_consts, c->c_const_dict, v); } static int *************** *** 698,704 **** struct compiling *c; PyObject *v; { ! return com_add(c, c->c_names, v); } #ifdef PRIVATE_NAME_MANGLING --- 718,724 ---- struct compiling *c; PyObject *v; { ! return com_add(c, c->c_names, c->c_name_dict, v); } #ifdef PRIVATE_NAME_MANGLING From guido@python.org Fri Apr 28 17:41:40 2000 From: guido@python.org (Guido van Rossum) Date: Fri, 28 Apr 2000 12:41:40 -0400 Subject: [Patches] Resubmit speedup patch for compile.c In-Reply-To: Your message of "Fri, 28 Apr 2000 10:59:03 CDT." <14601.46407.32803.275261@buffalo.fnal.gov> References: <14600.52568.898364.667776@buffalo.fnal.gov> <390957B1.76F6F199@lemburg.com> <200004281411.KAA16128@eric.cnri.reston.va.us> <14601.46407.32803.275261@buffalo.fnal.gov> Message-ID: <200004281641.MAA17321@eric.cnri.reston.va.us> > Below find the reworked patch. I don't completely agree with the > objections, but, whatever makes you and Guido happy is good with me. > > I can see the objections to changing the semantics of existing > variables, however I don't understand why the new members need to be > added at the _end_ of the compiling structure. To me this makes the > code less readable because it puts related items further away in the > source code. The compiling structure is only used internally, so I > don't quite see why rearranging it is a problem. But, whatever, I > don't want to argue. I do want to argue! :-) You're right, those new members don't need to be banned to the end. I've also replaced your code to create a tuple with a call to Py_BuildValue() -- much less code and doesn't seem to be any slower. Here's the patch that will go in now. Also thanks for changing the bizarre error handling in com_init() into something sane! Index: compile.c =================================================================== RCS file: /projects/cvsroot/python/dist/src/Python/compile.c,v retrieving revision 2.105 diff -c -r2.105 compile.c *** compile.c 2000/04/13 14:10:44 2.105 --- compile.c 2000/04/28 16:39:16 *************** *** 301,307 **** --- 301,309 ---- struct compiling { PyObject *c_code; /* string */ PyObject *c_consts; /* list of objects */ + PyObject *c_const_dict; /* inverse of c_consts */ PyObject *c_names; /* list of strings (names) */ + PyObject *c_name_dict; /* inverse of c_names */ PyObject *c_globals; /* dictionary (value=None) */ PyObject *c_locals; /* dictionary (value=localID) */ PyObject *c_varnames; /* list (inverse of c_locals) */ *************** *** 403,409 **** static void com_addoparg Py_PROTO((struct compiling *, int, int)); static void com_addfwref Py_PROTO((struct compiling *, int, int *)); static void com_backpatch Py_PROTO((struct compiling *, int)); ! static int com_add Py_PROTO((struct compiling *, PyObject *, PyObject *)); static int com_addconst Py_PROTO((struct compiling *, PyObject *)); static int com_addname Py_PROTO((struct compiling *, PyObject *)); static void com_addopname Py_PROTO((struct compiling *, int, node *)); --- 405,411 ---- static void com_addoparg Py_PROTO((struct compiling *, int, int)); static void com_addfwref Py_PROTO((struct compiling *, int, int *)); static void com_backpatch Py_PROTO((struct compiling *, int)); ! static int com_add Py_PROTO((struct compiling *, PyObject *, PyObject *, PyObject *)); static int com_addconst Py_PROTO((struct compiling *, PyObject *)); static int com_addname Py_PROTO((struct compiling *, PyObject *)); static void com_addopname Py_PROTO((struct compiling *, int, node *)); *************** *** 421,442 **** struct compiling *c; char *filename; { if ((c->c_code = PyString_FromStringAndSize((char *)NULL, 1000)) == NULL) ! goto fail_3; if ((c->c_consts = PyList_New(0)) == NULL) ! goto fail_2; if ((c->c_names = PyList_New(0)) == NULL) ! goto fail_1; if ((c->c_globals = PyDict_New()) == NULL) ! goto fail_0; if ((c->c_locals = PyDict_New()) == NULL) ! goto fail_00; if ((c->c_varnames = PyList_New(0)) == NULL) ! goto fail_000; if ((c->c_lnotab = PyString_FromStringAndSize((char *)NULL, 1000)) == NULL) ! goto fail_0000; c->c_nlocals = 0; c->c_argcount = 0; c->c_flags = 0; --- 423,449 ---- struct compiling *c; char *filename; { + memset((void *)c, '\0', sizeof(struct compiling)); if ((c->c_code = PyString_FromStringAndSize((char *)NULL, 1000)) == NULL) ! goto fail; if ((c->c_consts = PyList_New(0)) == NULL) ! goto fail; ! if ((c->c_const_dict = PyDict_New()) == NULL) ! goto fail; if ((c->c_names = PyList_New(0)) == NULL) ! goto fail; ! if ((c->c_name_dict = PyDict_New()) == NULL) ! goto fail; if ((c->c_globals = PyDict_New()) == NULL) ! goto fail; if ((c->c_locals = PyDict_New()) == NULL) ! goto fail; if ((c->c_varnames = PyList_New(0)) == NULL) ! goto fail; if ((c->c_lnotab = PyString_FromStringAndSize((char *)NULL, 1000)) == NULL) ! goto fail; c->c_nlocals = 0; c->c_argcount = 0; c->c_flags = 0; *************** *** 458,476 **** c-> c_lnotab_next = 0; return 1; ! fail_0000: ! Py_DECREF(c->c_varnames); ! fail_000: ! Py_DECREF(c->c_locals); ! fail_00: ! Py_DECREF(c->c_globals); ! fail_0: ! Py_DECREF(c->c_names); ! fail_1: ! Py_DECREF(c->c_consts); ! fail_2: ! Py_DECREF(c->c_code); ! fail_3: return 0; } --- 465,472 ---- c-> c_lnotab_next = 0; return 1; ! fail: ! com_free(c); return 0; } *************** *** 480,486 **** --- 476,484 ---- { Py_XDECREF(c->c_code); Py_XDECREF(c->c_consts); + Py_XDECREF(c->c_const_dict); Py_XDECREF(c->c_names); + Py_XDECREF(c->c_name_dict); Py_XDECREF(c->c_globals); Py_XDECREF(c->c_locals); Py_XDECREF(c->c_varnames); *************** *** 665,688 **** /* Handle literals and names uniformly */ static int ! com_add(c, list, v) struct compiling *c; PyObject *list; PyObject *v; { ! int n = PyList_Size(list); ! int i; ! /* XXX This is quadratic in the number of names per compilation unit. ! XXX Should use a dictionary. */ ! for (i = n; --i >= 0; ) { ! PyObject *w = PyList_GetItem(list, i); ! if (v->ob_type == w->ob_type && PyObject_Compare(v, w) == 0) ! return i; ! } ! /* Check for error from PyObject_Compare */ ! if (PyErr_Occurred() || PyList_Append(list, v) != 0) ! c->c_errors++; return n; } static int --- 663,701 ---- /* Handle literals and names uniformly */ static int ! com_add(c, list, dict, v) struct compiling *c; PyObject *list; + PyObject *dict; PyObject *v; { ! PyObject *w, *t, *np=NULL; ! long n; ! ! t = Py_BuildValue("(OO)", v, v->ob_type); ! if (t == NULL) ! goto fail; ! w = PyDict_GetItem(dict, t); ! if (w != NULL) { ! n = PyInt_AsLong(w); ! } else { ! n = PyList_Size(list); ! np = PyInt_FromLong(n); ! if (np == NULL) ! goto fail; ! if (PyList_Append(list, v) != 0) ! goto fail; ! if (PyDict_SetItem(dict, t, np) != 0) ! goto fail; ! Py_DECREF(np); ! } ! Py_DECREF(t); return n; + fail: + Py_XDECREF(np); + Py_XDECREF(t); + c->c_errors++; + return 0; } static int *************** *** 690,696 **** struct compiling *c; PyObject *v; { ! return com_add(c, c->c_consts, v); } static int --- 703,709 ---- struct compiling *c; PyObject *v; { ! return com_add(c, c->c_consts, c->c_const_dict, v); } static int *************** *** 698,704 **** struct compiling *c; PyObject *v; { ! return com_add(c, c->c_names, v); } #ifdef PRIVATE_NAME_MANGLING --- 711,717 ---- struct compiling *c; PyObject *v; { ! return com_add(c, c->c_names, c->c_name_dict, v); } #ifdef PRIVATE_NAME_MANGLING --Guido van Rossum (home page: http://www.python.org/~guido/) From mal@lemburg.com Fri Apr 28 20:49:24 2000 From: mal@lemburg.com (M.-A. Lemburg) Date: Fri, 28 Apr 2000 21:49:24 +0200 Subject: [Patches] Adding -U command line option Message-ID: <3909EB44.CC4E58A2@lemburg.com> This is a multi-part message in MIME format. --------------9D1A897A1EADDA003E5CBA4B Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit The attached patch adds a new experimental option -U to the Python interpreter. With the option enabled the Python compiler interprets all "..." strings as u"..." (same with r"..." and ur"..."). This provides a way to "look into the future" when someday all strings turn into Unicode and also simplifies testing the Unicode/string integration. Patch Set Contents: ------------------- Include/pydebug.h: Added Py_UnicodeFlag for use by the -U command line option. Modules/main.c: Added -U command line option. With the option enabled the Python compiler interprets all "..." strings as u"..." (same with r"..." and ur"..."). Python/compile.c: Support for the new -U command line option option: with the option enabled the Python compiler interprets all "..." strings as u"..." (same with r"..." and ur"..."). Python/pythonrun.c: Added Py_UnicodeFlag for use by the -U command line option. _____________________________________________________________________ Disclaimer: I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. -- Marc-Andre Lemburg ______________________________________________________________________ Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ --------------9D1A897A1EADDA003E5CBA4B Content-Type: text/plain; charset=us-ascii; name="Unicode-Implementation-2000-04-28.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="Unicode-Implementation-2000-04-28.patch" diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x configure -x *.bak -x *.s -x DEADJOE -x *.rej -x *.orig -x Demo -x CVS -x Doc -x *.orig -x .#* -x distutils -x PC -x PCbuild -x *.py -x ACKS -x *.txt -x README CVS-Python/Include/pydebug.h Python+Unicode/Include/pydebug.h --- CVS-Python/Include/pydebug.h Fri Dec 4 19:48:15 1998 +++ Python+Unicode/Include/pydebug.h Fri Apr 28 20:42:35 2000 @@ -43,6 +43,7 @@ extern DL_IMPORT(int) Py_UseClassExceptionsFlag; extern DL_IMPORT(int) Py_FrozenFlag; extern DL_IMPORT(int) Py_TabcheckFlag; +extern DL_IMPORT(int) Py_UnicodeFlag; DL_IMPORT(void) Py_FatalError Py_PROTO((char *)); diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x configure -x *.bak -x *.s -x DEADJOE -x *.rej -x *.orig -x Demo -x CVS -x Doc -x *.orig -x .#* -x distutils -x PC -x PCbuild -x *.py -x ACKS -x *.txt -x README CVS-Python/Modules/main.c Python+Unicode/Modules/main.c --- CVS-Python/Modules/main.c Mon Apr 19 19:54:19 1999 +++ Python+Unicode/Modules/main.c Fri Apr 28 20:47:36 2000 @@ -75,6 +75,7 @@ "; static char *usage_mid = "\ -u : unbuffered binary stdout and stderr (also PYTHONUNBUFFERED=x)\n\ +-U : experimental: turns '...' into u'...'\n\ -v : verbose (trace import statements) (also PYTHONVERBOSE=x)\n\ -x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\ -X : disable class based built-in exceptions\n\ @@ -119,7 +120,7 @@ if ((p = getenv("PYTHONUNBUFFERED")) && *p != '\0') unbuffered = 1; - while ((c = getopt(argc, argv, "c:diOStuvxX")) != EOF) { + while ((c = getopt(argc, argv, "c:diOStuUvxX")) != EOF) { if (c == 'c') { /* -c is the last option; following arguments that look like options are left for the @@ -170,6 +171,10 @@ case 'X': Py_UseClassExceptionsFlag = 0; + break; + + case 'U': + Py_UnicodeFlag++; break; /* This space reserved for other options */ diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x configure -x *.bak -x *.s -x DEADJOE -x *.rej -x *.orig -x Demo -x CVS -x Doc -x *.orig -x .#* -x distutils -x PC -x PCbuild -x *.py -x ACKS -x *.txt -x README CVS-Python/Python/compile.c Python+Unicode/Python/compile.c --- CVS-Python/Python/compile.c Thu Apr 13 18:10:59 2000 +++ Python+Unicode/Python/compile.c Fri Apr 28 20:41:23 2000 @@ -907,7 +907,7 @@ return NULL; } } - if (unicode) { + if (unicode || Py_UnicodeFlag) { if (rawmode) return PyUnicode_DecodeRawUnicodeEscape( s, len, NULL); diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x configure -x *.bak -x *.s -x DEADJOE -x *.rej -x *.orig -x Demo -x CVS -x Doc -x *.orig -x .#* -x distutils -x PC -x PCbuild -x *.py -x ACKS -x *.txt -x README CVS-Python/Python/pythonrun.c Python+Unicode/Python/pythonrun.c --- CVS-Python/Python/pythonrun.c Tue Apr 25 12:34:21 2000 +++ Python+Unicode/Python/pythonrun.c Fri Apr 28 20:34:42 2000 @@ -88,6 +88,7 @@ int Py_NoSiteFlag; /* Suppress 'import site' */ int Py_UseClassExceptionsFlag = 1; /* Needed by bltinmodule.c */ int Py_FrozenFlag; /* Needed by getpath.c */ +int Py_UnicodeFlag = 0; /* Needed by compile.c */ static int initialized = 0; --------------9D1A897A1EADDA003E5CBA4B-- From bwarsaw@python.org Sat Apr 29 01:20:20 2000 From: bwarsaw@python.org (Barry A. Warsaw) Date: Fri, 28 Apr 2000 20:20:20 -0400 (EDT) Subject: [Patches] utime(path, NULL) Message-ID: <14602.10948.514287.329941@anthem.cnri.reston.va.us> On some OSes (Solaris and Linux at least), the second argument to utime() can be NULL, which sets the atime and mtime of the file to the current time. Here is a patch that gives this functionality if second argument to os.utime() is omitted. E.g. import os os.utime(path) == #include utime(path, NULL) One minor bogosity: because of the way default arguments work for longs, os.utime(path) is equivalent to os.utime(path, (-1, -1)). Is this a big deal? Should other magic be used instead? -Barry Index: libos.tex =================================================================== RCS file: /projects/cvsroot/python/dist/src/Doc/lib/libos.tex,v retrieving revision 1.38 diff -c -r1.38 libos.tex *** libos.tex 2000/04/03 20:13:53 1.38 --- libos.tex 2000/04/29 00:15:42 *************** *** 704,710 **** \begin{funcdesc}{utime}{path, (atime, mtime)} Set the access and modified time of the file to the given values. ! (The second argument is a tuple of two items.) Availability: Macintosh, \UNIX{}, Windows. \end{funcdesc} --- 704,711 ---- \begin{funcdesc}{utime}{path, (atime, mtime)} Set the access and modified time of the file to the given values. ! The second argument is a tuple of two items; if it is omitted, then ! these times are set to the current time. Availability: Macintosh, \UNIX{}, Windows. \end{funcdesc} Index: posixmodule.c =================================================================== RCS file: /projects/cvsroot/python/dist/src/Modules/posixmodule.c,v retrieving revision 2.132 diff -c -r2.132 posixmodule.c *** posixmodule.c 2000/04/26 20:34:28 2.132 --- posixmodule.c 2000/04/29 00:10:52 *************** *** 1258,1264 **** PyObject *args; { char *path; ! long atime, mtime; int res; /* XXX should define struct utimbuf instead, above */ --- 1258,1264 ---- PyObject *args; { char *path; ! long atime=-1, mtime=-1; int res; /* XXX should define struct utimbuf instead, above */ *************** *** 1274,1286 **** #define UTIME_ARG buf #endif /* HAVE_UTIME_H */ ! if (!PyArg_ParseTuple(args, "s(ll):utime", &path, &atime, &mtime)) return NULL; ! ATIME = atime; ! MTIME = mtime; ! Py_BEGIN_ALLOW_THREADS ! res = utime(path, UTIME_ARG); ! Py_END_ALLOW_THREADS if (res < 0) return posix_error_with_filename(path); Py_INCREF(Py_None); --- 1274,1294 ---- #define UTIME_ARG buf #endif /* HAVE_UTIME_H */ ! if (!PyArg_ParseTuple(args, "s|(ll):utime", &path, &atime, &mtime)) return NULL; ! if (atime == -1 && mtime == -1) { ! /* optional time values not given */ ! Py_BEGIN_ALLOW_THREADS ! res = utime(path, NULL); ! Py_END_ALLOW_THREADS ! } ! else { ! ATIME = atime; ! MTIME = mtime; ! Py_BEGIN_ALLOW_THREADS ! res = utime(path, UTIME_ARG); ! Py_END_ALLOW_THREADS ! } if (res < 0) return posix_error_with_filename(path); Py_INCREF(Py_None); From brian@garage.co.jp Sat Apr 29 04:13:55 2000 From: brian@garage.co.jp (Brian Hooper) Date: Sat, 29 Apr 2000 03:13:55 GMT Subject: [Patches] slightly expanded Unicode supported Py_BuildValue Message-ID: <20000429031355.84728.qmail@hotmail.com> Hi again, > > Here's a patch which changes modsupport to add 'U' and 'U#', > > to support building Unicode objects from a null-terminated > > Py_UNICODE *, and a Py_UNICODE * with length, respectively. > >If you would change the 'U' (capital U) to 'u' (lowercase u) >the patch would be perfect :-) After using the API with the lower-case 'u' a little bit, I feel I should mention that it's actually a little confusing to have the argument to PyArgs_ParseTuple be 'U' but the argument to Py_BuildValue be 'u' - this in comparison with 's', which is the same for both PyArgs_ParseTuple and Py_BuildValue, even though one signifies a Python string object and the other signifies regular char * data which gets turned into a Python string. Doesn't this case seem like it ought to be parallel? I think after actually trying it out it seems a little unwieldy and confusing. If 'u' is preferable to 'U', why not change the PyArgs_ParseTuple argument to 'u' also? I think making PyArgs_ParseTuple and Py_BuildValue as complimentary as possible makes them easiest to use and understand. Just my 2 cents, --Brian ________________________________________________________________________ Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com From robin@jessikat.demon.co.uk Sat Apr 29 09:40:45 2000 From: robin@jessikat.demon.co.uk (Robin Becker) Date: Sat, 29 Apr 2000 09:40:45 +0100 Subject: [Patches] win32 module case bugfix to allcaps83 Message-ID: The following patch seems to fix a module case bug in 1.6a2 caused by wrong return values in routine allcaps83 in import.c *** import.c.orig Sat Apr 29 09:12:18 2000 --- import.c Sat Apr 29 09:14:34 2000 *************** *** 1035,1046 **** char *end = strchr(s, '\0'); if (dot != NULL) { if (dot-s > 8) ! return 1; /* More than 8 before '.' */ if (end-dot > 4) ! return 1; /* More than 3 after '.' */ end = strchr(dot+1, '.'); if (end != NULL) ! return 1; /* More than one dot */ } else if (end-s > 8) return 1; /* More than 8 and no dot */ --- 1035,1046 ---- char *end = strchr(s, '\0'); if (dot != NULL) { if (dot-s > 8) ! return 0; /* More than 8 before '.' */ if (end-dot > 4) ! return 0; /* More than 3 after '.' */ end = strchr(dot+1, '.'); if (end != NULL) ! return 0; /* More than one dot */ } else if (end-s > 8) return 1; /* More than 8 and no dot */ I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. -- Robin Becker From mal@lemburg.com Sat Apr 29 14:01:01 2000 From: mal@lemburg.com (M.-A. Lemburg) Date: Sat, 29 Apr 2000 15:01:01 +0200 Subject: [Patches] slightly expanded Unicode supported Py_BuildValue References: <20000429031355.84728.qmail@hotmail.com> Message-ID: <390ADD0D.9722FA7D@lemburg.com> Brian Hooper wrote: > > Hi again, > > > > Here's a patch which changes modsupport to add 'U' and 'U#', > > > to support building Unicode objects from a null-terminated > > > Py_UNICODE *, and a Py_UNICODE * with length, respectively. > > > >If you would change the 'U' (capital U) to 'u' (lowercase u) > >the patch would be perfect :-) > > After using the API with the lower-case 'u' a little bit, I feel > I should mention that it's actually a little confusing to have > the argument to PyArgs_ParseTuple be 'U' but the argument to > Py_BuildValue be 'u' - this in comparison with 's', which is > the same for both PyArgs_ParseTuple and Py_BuildValue, even though > one signifies a Python string object and the other signifies > regular char * data which gets turned into a Python string. > > Doesn't this case seem like it ought to be parallel? I think after actually > trying it out it seems a little unwieldy and confusing. If 'u' is > preferable to 'U', why not change the PyArgs_ParseTuple argument to 'u' > also? I think making PyArgs_ParseTuple and Py_BuildValue as complimentary > as possible makes them easiest to use and understand. With the case switch, your patch gets in sync with what "s" does for PyArgs_ParseTuple() and Py_BuildValue(): the first reads string objects as char* while the second creates string objects from char*. The "U" in PyArgs_ParseTuple() does two things: it first checks the object for being a Unicode object and then returns a PyObject*. There also is a "S" marker which does the same for string objects. One could argue to also have a set of "u" markers for PyArgs_ParseTuple(): these should then return Py_UNICODE* instead of char*. Perhaps this is what you are thinking about ? It would make a nice complement to your recent patches. -- Marc-Andre Lemburg ______________________________________________________________________ Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ From mal@lemburg.com Sat Apr 29 14:34:47 2000 From: mal@lemburg.com (M.-A. Lemburg) Date: Sat, 29 Apr 2000 15:34:47 +0200 Subject: [Patches] Adding -U command line option References: <3909EB44.CC4E58A2@lemburg.com> Message-ID: <390AE4F7.84D6B996@lemburg.com> This is a multi-part message in MIME format. --------------44FAD210BAEBD7EFCE0EE2E0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit The attached patch adds a new experimental option -U to the Python interpreter. With the option enabled the Python compiler interprets all "..." strings as u"..." (same with r"..." and ur"..."). This provides a way to "look into the future" when someday all strings turn into Unicode and also simplifies testing the Unicode/string integration. The new version of the patch fixes a problem when trying to use byte compiled PYC files compiled with -U option and without this option side-by-side: when using -U, the magic number for PYC files gets incremented by one so that a Python process using this option will only use precompiled PYC files created by Python processes also using -U. This allow people willing to test drive the complete switch to Unicode without harming their standard Python installation. Patch Set Contents: ------------------- Include/pydebug.h: Added Py_UnicodeFlag for use by the -U command line option. Modules/main.c: Added -U command line option. With the option enabled the Python compiler interprets all "..." strings as u"..." (same with r"..." and ur"..."). Python/compile.c: Support for the new -U command line option option: with the option enabled the Python compiler interprets all "..." strings as u"..." (same with r"..." and ur"..."). Python/pythonrun.c: Added Py_UnicodeFlag for use by the -U command line option. Python/import.c: Changed all references to the MAGIC constant to use a global pyc_magic instead. This global is initially set to MAGIC, but can be changed by the _PyImport_Init() function to provide for special features implemented in the compiler which are settable using command line switches and affect the way PYC files are generated. Currently this change is only done for the -U flag. _____________________________________________________________________ Disclaimer: I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. -- Marc-Andre Lemburg ______________________________________________________________________ Business: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ --------------44FAD210BAEBD7EFCE0EE2E0 Content-Type: text/plain; charset=us-ascii; name="Unicode-Implementation-2000-04-29.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="Unicode-Implementation-2000-04-29.patch" diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x configure -x *.bak -x *.s -x DEADJOE -x *.rej -x *.orig -x Demo -x CVS -x Doc -x *.orig -x .#* -x distutils -x PC -x PCbuild -x *.py -x ACKS -x *.txt -x README CVS-Python/Include/pydebug.h Python+Unicode/Include/pydebug.h --- CVS-Python/Include/pydebug.h Fri Dec 4 19:48:15 1998 +++ Python+Unicode/Include/pydebug.h Fri Apr 28 20:42:35 2000 @@ -43,6 +43,7 @@ extern DL_IMPORT(int) Py_UseClassExceptionsFlag; extern DL_IMPORT(int) Py_FrozenFlag; extern DL_IMPORT(int) Py_TabcheckFlag; +extern DL_IMPORT(int) Py_UnicodeFlag; DL_IMPORT(void) Py_FatalError Py_PROTO((char *)); diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x configure -x *.bak -x *.s -x DEADJOE -x *.rej -x *.orig -x Demo -x CVS -x Doc -x *.orig -x .#* -x distutils -x PC -x PCbuild -x *.py -x ACKS -x *.txt -x README CVS-Python/Modules/main.c Python+Unicode/Modules/main.c --- CVS-Python/Modules/main.c Mon Apr 19 19:54:19 1999 +++ Python+Unicode/Modules/main.c Fri Apr 28 20:47:36 2000 @@ -75,6 +75,7 @@ "; static char *usage_mid = "\ -u : unbuffered binary stdout and stderr (also PYTHONUNBUFFERED=x)\n\ +-U : experimental: turns '...' into u'...'\n\ -v : verbose (trace import statements) (also PYTHONVERBOSE=x)\n\ -x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\ -X : disable class based built-in exceptions\n\ @@ -119,7 +120,7 @@ if ((p = getenv("PYTHONUNBUFFERED")) && *p != '\0') unbuffered = 1; - while ((c = getopt(argc, argv, "c:diOStuvxX")) != EOF) { + while ((c = getopt(argc, argv, "c:diOStuUvxX")) != EOF) { if (c == 'c') { /* -c is the last option; following arguments that look like options are left for the @@ -170,6 +171,10 @@ case 'X': Py_UseClassExceptionsFlag = 0; + break; + + case 'U': + Py_UnicodeFlag++; break; /* This space reserved for other options */ diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x configure -x *.bak -x *.s -x DEADJOE -x *.rej -x *.orig -x Demo -x CVS -x Doc -x *.orig -x .#* -x distutils -x PC -x PCbuild -x *.py -x ACKS -x *.txt -x README CVS-Python/Python/compile.c Python+Unicode/Python/compile.c --- CVS-Python/Python/compile.c Thu Apr 13 18:10:59 2000 +++ Python+Unicode/Python/compile.c Fri Apr 28 20:41:23 2000 @@ -907,7 +907,7 @@ return NULL; } } - if (unicode) { + if (unicode || Py_UnicodeFlag) { if (rawmode) return PyUnicode_DecodeRawUnicodeEscape( s, len, NULL); diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x configure -x *.bak -x *.s -x DEADJOE -x *.rej -x *.orig -x Demo -x CVS -x Doc -x *.orig -x .#* -x distutils -x PC -x PCbuild -x *.py -x ACKS -x *.txt -x README CVS-Python/Python/import.c Python+Unicode/Python/import.c --- CVS-Python/Python/import.c Tue Apr 25 12:34:21 2000 +++ Python+Unicode/Python/import.c Sat Apr 29 15:18:01 2000 @@ -84,7 +84,12 @@ /* XXX Perhaps the magic number should be frozen and a version field added to the .pyc file header? */ /* New way to come up with the magic number: (YEAR-1995), MONTH, DAY */ -#define MAGIC (20121 | ((long)'\r'<<16) | ((long)'\n'<<24)) +#define MAGIC (50428 | ((long)'\r'<<16) | ((long)'\n'<<24)) + +/* Magic word as global; note that _PyImport_Init() can change the + value of this global to accomodate for alterations of how the + compiler works which are enabled by command line switches. */ +static long pyc_magic = MAGIC; /* See _PyImport_FixupExtension() below */ static PyObject *extensions = NULL; @@ -135,6 +140,13 @@ filetab->suffix = ".pyo"; } } + + if (Py_UnicodeFlag) { + /* Fix the pyc_magic so that byte compiled code created + using the all-Unicode method doesn't interfere with + code created in normal operation mode. */ + pyc_magic = MAGIC + 1; + } } void @@ -366,7 +378,7 @@ long PyImport_GetMagicNumber() { - return MAGIC; + return pyc_magic; } @@ -572,7 +584,7 @@ if (fp == NULL) return NULL; magic = PyMarshal_ReadLongFromFile(fp); - if (magic != MAGIC) { + if (magic != pyc_magic) { if (Py_VerboseFlag) PySys_WriteStderr("# %s has bad magic\n", cpathname); fclose(fp); @@ -627,7 +639,7 @@ PyObject *m; magic = PyMarshal_ReadLongFromFile(fp); - if (magic != MAGIC) { + if (magic != pyc_magic) { PyErr_Format(PyExc_ImportError, "Bad magic number in %.200s", cpathname); return NULL; @@ -685,7 +697,7 @@ "# can't create %s\n", cpathname); return; } - PyMarshal_WriteLongToFile(MAGIC, fp); + PyMarshal_WriteLongToFile(pyc_magic, fp); /* First write a 0 for mtime */ PyMarshal_WriteLongToFile(0L, fp); PyMarshal_WriteObjectToFile((PyObject *)co, fp); @@ -1953,10 +1965,10 @@ if (!PyArg_ParseTuple(args, ":get_magic")) return NULL; - buf[0] = (char) ((MAGIC >> 0) & 0xff); - buf[1] = (char) ((MAGIC >> 8) & 0xff); - buf[2] = (char) ((MAGIC >> 16) & 0xff); - buf[3] = (char) ((MAGIC >> 24) & 0xff); + buf[0] = (char) ((pyc_magic >> 0) & 0xff); + buf[1] = (char) ((pyc_magic >> 8) & 0xff); + buf[2] = (char) ((pyc_magic >> 16) & 0xff); + buf[3] = (char) ((pyc_magic >> 24) & 0xff); return PyString_FromStringAndSize(buf, 4); } diff -u -rbP -x *.o -x *.pyc -x Makefile -x *~ -x *.so -x add2lib -x pgen -x buildno -x config.* -x libpython* -x python -x Setup -x Setup.local -x Setup.thread -x hassignal -x Makefile.pre -x configure -x *.bak -x *.s -x DEADJOE -x *.rej -x *.orig -x Demo -x CVS -x Doc -x *.orig -x .#* -x distutils -x PC -x PCbuild -x *.py -x ACKS -x *.txt -x README CVS-Python/Python/pythonrun.c Python+Unicode/Python/pythonrun.c --- CVS-Python/Python/pythonrun.c Tue Apr 25 12:34:21 2000 +++ Python+Unicode/Python/pythonrun.c Fri Apr 28 20:34:42 2000 @@ -88,6 +88,7 @@ int Py_NoSiteFlag; /* Suppress 'import site' */ int Py_UseClassExceptionsFlag = 1; /* Needed by bltinmodule.c */ int Py_FrozenFlag; /* Needed by getpath.c */ +int Py_UnicodeFlag = 0; /* Needed by compile.c */ static int initialized = 0; --------------44FAD210BAEBD7EFCE0EE2E0-- From brian@garage.co.jp Sat Apr 29 19:19:13 2000 From: brian@garage.co.jp (Brian Hooper) Date: Sat, 29 Apr 2000 18:19:13 GMT Subject: [Patches] slightly expanded Unicode supported Py_BuildValue Message-ID: <20000429181913.28204.qmail@hotmail.com> Hi Marc-Andre, Thanks for your crystal clear explanation - I understand now! 'U' and 'u' are analogous to 'S' and 's'. OK, I'm going to make everything symmetric, then :-) --Brian >Brian Hooper wrote: > > > > Hi again, > > > > > > Here's a patch which changes modsupport to add 'U' and 'U#', > > > > to support building Unicode objects from a null-terminated > > > > Py_UNICODE *, and a Py_UNICODE * with length, respectively. > > > > > >If you would change the 'U' (capital U) to 'u' (lowercase u) > > >the patch would be perfect :-) > > > > After using the API with the lower-case 'u' a little bit, I feel > > I should mention that it's actually a little confusing to have > > the argument to PyArgs_ParseTuple be 'U' but the argument to > > Py_BuildValue be 'u' - this in comparison with 's', which is > > the same for both PyArgs_ParseTuple and Py_BuildValue, even though > > one signifies a Python string object and the other signifies > > regular char * data which gets turned into a Python string. > > > > Doesn't this case seem like it ought to be parallel? I think after >actually > > trying it out it seems a little unwieldy and confusing. If 'u' is > > preferable to 'U', why not change the PyArgs_ParseTuple argument to 'u' > > also? I think making PyArgs_ParseTuple and Py_BuildValue as >complimentary > > as possible makes them easiest to use and understand. > >With the case switch, your patch gets in sync with what >"s" does for PyArgs_ParseTuple() and Py_BuildValue(): the >first reads string objects as char* while the second creates >string objects from char*. > >The "U" in PyArgs_ParseTuple() does two things: it first >checks the object for being a Unicode object and then >returns a PyObject*. There also is a "S" marker which >does the same for string objects. > >One could argue to also have a set of "u" markers for >PyArgs_ParseTuple(): these should then return Py_UNICODE* >instead of char*. Perhaps this is what you are thinking >about ? It would make a nice complement to your recent patches. > >-- >Marc-Andre Lemburg >______________________________________________________________________ >Business: http://www.lemburg.com/ >Python Pages: http://www.lemburg.com/python/ > > ________________________________________________________________________ Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com From Vladimir.Marangozov@inrialpes.fr Sun Apr 30 20:39:24 2000 From: Vladimir.Marangozov@inrialpes.fr (Vladimir Marangozov) Date: Sun, 30 Apr 2000 21:39:24 +0200 (CEST) Subject: [Patches] PyMem [1/8] - Memory API: Summary Message-ID: <200004301939.VAA14990@python.inrialpes.fr> Second (and hopefully, final) round of patches relative to the malloc cleanup and the renewed memory interfaces. It affects *lots* of files in the distribution -- more than enough for May 1st ;-) I hereby send a patch per directory to easy their review, except the two key include files, mymalloc.h and objimpl.h which are to be saved as is (better than a context diff for Include/* anyway). Interface summary ================= Each memory interface exports both functions and macros. Functions preserve binary compatibility of the code across different releases while MACROS trade it for speed. Public API Functions MACROS -------------- ---------------------------- -------------------- 1) Core Memory Allocator (see mymalloc.h) - raw mem malloc PyMem_Malloc/Realloc/Free PyMem_MALLOC/REALLOC/FREE - type-oriented PyMem_New/Resize/Del PyMem_NEW/RESIZE/DEL 2) Core Object Memory Allocator & Facilities (see objimpl.h) - object malloc PyObject_Malloc/Realloc/Free PyObject_MALLOC/REALLOC/FREE - initialization PyObject_Init/InitVar PyObject_INIT/INIT_VAR - constr./destr. PyObject_New/NewVar/Del PyObject_NEW/NEW_VAR/DEL All APIs operate on the Python heap(s). Objects that are subject to custom allocation strategies (custom = non Python = std malloc, C++ new, 3rd party) are out of bounds -- we can't do much about them from Python except providing handy macros related to their structure. The extension-type developer is responsible for their allocation/deallocation with the malloc of choice. See the comments in objimpl.h I tend to be slightly verbose :-) so if you think the comments in the source can be shortened (or improved) for clarity, you're welcome.. Needless to say, once checked in, a complete overhaul of the Python memory interfaces would be in place. I encourage you to take some time reviewing your favorite files in the distribution and see how and why they have changed. More specific comments follow for each part of the patch suite. -- Vladimir MARANGOZOV | Vladimir.Marangozov@inrialpes.fr http://sirac.inrialpes.fr/~marangoz | tel:(+33-4)76615277 fax:76615252 From Vladimir.Marangozov@inrialpes.fr Sun Apr 30 20:40:33 2000 From: Vladimir.Marangozov@inrialpes.fr (Vladimir Marangozov) Date: Sun, 30 Apr 2000 21:40:33 +0200 (CEST) Subject: [Patches] PyMem [2/8] - Include/mymalloc.h Message-ID: <200004301940.VAA15018@python.inrialpes.fr> [ Include/mymalloc.h ] The Python core malloc. These interfaces have been discussed extensively already -- I have nothing to add here. For now, the default Python malloc is standard C malloc so I don't expect any code breakage. -- Vladimir MARANGOZOV | Vladimir.Marangozov@inrialpes.fr http://sirac.inrialpes.fr/~marangoz | tel:(+33-4)76615277 fax:76615252 -- Disclaimer: I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. -------------------------------[ cut here ]--------------------------- #ifndef Py_MYMALLOC_H #define Py_MYMALLOC_H /*********************************************************** Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam, The Netherlands. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the names of Stichting Mathematisch Centrum or CWI or Corporation for National Research Initiatives or CNRI not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. While CWI is the initial source for this software, a modified version is made available by the Corporation for National Research Initiatives (CNRI) at the Internet address ftp://ftp.python.org. STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************/ /* Lowest-level memory allocation interface */ #ifdef macintosh #define ANY void #endif #ifdef __STDC__ #define ANY void #endif #ifdef __TURBOC__ #define ANY void #endif #ifdef __GNUC__ #define ANY void #endif #ifndef ANY #define ANY char #endif #ifdef HAVE_STDLIB_H #include #endif #include "myproto.h" #ifdef __cplusplus /* Move this down here since some C++ #include's don't like to be included inside an extern "C" */ extern "C" { #endif #ifdef SYMANTEC__CFM68K__ #pragma lib_export on #endif #ifndef DL_IMPORT /* declarations for DLL import */ #define DL_IMPORT(RTYPE) RTYPE #endif #ifndef NULL #define NULL ((ANY *)0) #endif #ifdef MALLOC_ZERO_RETURNS_NULL /* XXX Always allocate one extra byte, since some malloc's return NULL XXX for malloc(0) or realloc(p, 0). */ #define _PyMem_EXTRA 1 #else #define _PyMem_EXTRA 0 #endif /* * Core memory allocator * ===================== */ /* To make sure the interpreter is user-malloc friendly, all memory APIs are implemented on top of this one. The PyCore_* macros can be defined to make the interpreter use a custom allocator. Note that they are for internal use only. Both the core and extension modules should use the PyMem_* API. */ #ifndef PyCore_MALLOC_FUNC #undef PyCore_REALLOC_FUNC #undef PyCore_FREE_FUNC #define PyCore_MALLOC_FUNC malloc #define PyCore_REALLOC_FUNC realloc #define PyCore_FREE_FUNC free #endif #ifndef PyCore_MALLOC_PROTO #undef PyCore_REALLOC_PROTO #undef PyCore_FREE_PROTO #define PyCore_MALLOC_PROTO Py_PROTO((size_t)) #define PyCore_REALLOC_PROTO Py_PROTO((ANY *, size_t)) #define PyCore_FREE_PROTO Py_PROTO((ANY *)) #endif #ifdef NEED_TO_DECLARE_MALLOC_AND_FRIEND extern ANY *PyCore_MALLOC_FUNC PyCore_MALLOC_PROTO; extern ANY *PyCore_REALLOC_FUNC PyCore_REALLOC_PROTO; extern void PyCore_FREE_FUNC PyCore_FREE_PROTO; #endif #ifndef PyCore_MALLOC #undef PyCore_REALLOC #undef PyCore_FREE #define PyCore_MALLOC(n) PyCore_MALLOC_FUNC(n) #define PyCore_REALLOC(p, n) PyCore_REALLOC_FUNC((p), (n)) #define PyCore_FREE(p) PyCore_FREE_FUNC(p) #endif /* BEWARE: Each interface exports both functions and macros. Extension modules should normally use the functions for ensuring binary compatibility of the user's code across Python versions. Subsequently, if the Python runtime switches to its own malloc (different from standard malloc), no recompilation is required for the extensions. The macro versions trade compatibility for speed. They can be used whenever there is a performance problem, but their use implies recompilation of the code for each new Python release. The Python core uses the macros because it *is* compiled on every upgrade. This might not be the case with 3rd party extensions in a custom setup (for example, a customer does not always have access to the source of 3rd party deliverables). You have been warned! */ /* * Raw memory interface * ==================== */ /* Functions */ /* Function wrappers around PyCore_MALLOC and friends; useful if you need to be sure that you are using the same memory allocator as Python. Note that the wrappers make sure that allocating 0 bytes returns a non-NULL pointer, even if the underlying malloc doesn't. Returned pointers must be checked for NULL explicitly. No action is performed on failure. */ extern DL_IMPORT(ANY *) PyMem_Malloc Py_PROTO((size_t)); extern DL_IMPORT(ANY *) PyMem_Realloc Py_PROTO((ANY *, size_t)); extern DL_IMPORT(void) PyMem_Free Py_PROTO((ANY *)); /* Starting from Python 1.6, the wrappers Py_{Malloc,Realloc,Free} are no longer supported. They used to call PyErr_NoMemory() on failure. The following are provided for backwards source code compatibility. Their use is deprecated. */ #define Py_Malloc(n) /* deprecated Py_Malloc */ PyMem_Malloc(n) #define Py_Realloc(p, n) /* deprecated Py_Realloc */ PyMem_Realloc((p), (n)) #define Py_Free(p) /* deprecated Py_Free */ PyMem_Free(p) /* Macros */ #define PyMem_MALLOC(n) PyCore_MALLOC(n) #define PyMem_REALLOC(p, n) PyCore_REALLOC((ANY *)(p), (n)) #define PyMem_FREE(p) PyCore_FREE((ANY *)(p)) /* * Type-oriented memory interface * ============================== */ /* Functions */ #define PyMem_New(type, n) \ ( (type *) PyMem_Malloc((n) * sizeof(type)) ) #define PyMem_Resize(p, type, n) \ ( (p) = (type *) PyMem_Realloc((n) * sizeof(type)) ) #define PyMem_Del(p) PyMem_Free(p) /* Macros */ #define PyMem_NEW(type, n) \ ( (type *) PyMem_MALLOC(_PyMem_EXTRA + (n) * sizeof(type)) ) #define PyMem_RESIZE(p, type, n) \ if ((p) == NULL) \ (p) = (type *)(PyMem_MALLOC( \ _PyMem_EXTRA + (n) * sizeof(type))); \ else \ (p) = (type *)(PyMem_REALLOC((p), \ _PyMem_EXTRA + (n) * sizeof(type))) #define PyMem_DEL(p) PyMem_FREE(p) /* PyMem_XDEL is deprecated. To avoid the call when p is NULL, it is recommended to write the test explicitly in the code. Note that according to ANSI C, free(NULL) has no effect. */ #define PyMem_XDEL(p) /* deprecated PyMem_XDEL */ PyMem_DEL(p) #ifdef __cplusplus } #endif #endif /* !Py_MYMALLOC_H */ From Vladimir.Marangozov@inrialpes.fr Sun Apr 30 20:41:26 2000 From: Vladimir.Marangozov@inrialpes.fr (Vladimir Marangozov) Date: Sun, 30 Apr 2000 21:41:26 +0200 (CEST) Subject: [Patches] PyMem [3/8] - Include/objimpl.h Message-ID: <200004301941.VAA15041@python.inrialpes.fr> [ Include/objimpl.h ] This is news for everybody. This is the Python object allocator for implementing object contructors and destructors. It may differ from the core malloc completely. Quite useful for "real" GC, among others (not that GC over RC is unreal!) By default, it's implemented on top (in terms) of the core malloc. All extension (non-core) types should use the function version of the API: PyObject_New/NewVar/Del, *not* the macro version. This ensures that Python keeps control on *all* "normal" objects, except the "foreigners" that are allocated with custom mallocs. For custom mallocs, we still require the initialization of the object through PyObject_Init/InitVar after its allocation! Thus, we can have the potential to customize and/or change the internal object header representation (the PyObject struct). The object malloc API (PyObject_Malloc/Realloc/Free) is exported because sometimes people want to customize their object-specific allocators, so PyObject_New gets inlined (in practice, this is done in more or less random ways). To avoid this randomness, we also provide some facilities for customizing the object constructors (_PyObject_SIZE/VAR_SIZE and PyObject_Init/InitVar). We're also willing to provide guidance on how to achieve this customization with the interfaces defined below. All this may seem unnecessary at first sight, but take a good look at the incoming Objects/* and Modules/* patches. The code speaks for itself. -- Vladimir MARANGOZOV | Vladimir.Marangozov@inrialpes.fr http://sirac.inrialpes.fr/~marangoz | tel:(+33-4)76615277 fax:76615252 -- Disclaimer: I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. -------------------------------[ cut here ]--------------------------- #ifndef Py_OBJIMPL_H #define Py_OBJIMPL_H #ifdef __cplusplus extern "C" { #endif /*********************************************************** Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam, The Netherlands. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the names of Stichting Mathematisch Centrum or CWI or Corporation for National Research Initiatives or CNRI not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. While CWI is the initial source for this software, a modified version is made available by the Corporation for National Research Initiatives (CNRI) at the Internet address ftp://ftp.python.org. STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************/ #include "mymalloc.h" /* Functions and macros for modules that implement new object types. You must first include "object.h". - PyObject_New(type, typeobj) allocates memory for a new object of the given type; here 'type' must be the C structure type used to represent the object and 'typeobj' the address of the corresponding type object. Reference count and type pointer are filled in; the rest of the bytes of the object are *undefined*! The resulting expression type is 'type *'. The size of the object is actually determined by the tp_basicsize field of the type object. - PyObject_NewVar(type, typeobj, n) is similar but allocates a variable-size object with n extra items. The size is computed as tp_basicsize plus n * tp_itemsize. This fills in the ob_size field as well. - PyObject_Del(op) releases the memory allocated for an object. - PyObject_Init(op, typeobj) and PyObject_InitVar(op, typeobj, n) are similar to PyObject_{New, NewVar} except that they don't allocate the memory needed for an object. Instead of the 'type' parameter, they accept the pointer of a new object (allocated by an arbitrary allocator) and initialize its object header fields. Note that objects created with PyObject_{New, NewVar} are allocated within the Python heap by an object allocator, the latter being implemented (by default) on top of the Python raw memory allocator. This ensures that Python keeps control on the user's objects regarding their memory management; for instance, they may be subject to automatic garbage collection. In case a specific form of memory management is needed, implying that the objects would not reside in the Python heap (for example standard malloc heap(s) are mandatory, use of shared memory, C++ local storage or operator new), you must first allocate the object with your custom allocator, then pass its pointer to PyObject_{Init, InitVar} for filling in its Python-specific fields: reference count, type pointer, possibly others. You should be aware that Python has very limited control over these objects because they don't cooperate with the Python memory manager. Such objects may not be eligible for automatic garbage collection and you have to make sure that they are released accordingly whenever their destructor gets called (cf. the specific form of memory management you're using). Unless you have specific memory management requirements, it is recommended to use PyObject_{New, NewVar, Del}. */ /* * Core object memory allocator * ============================ */ /* The purpose of the object allocator is to make make the distinction between "object memory" and the rest within the Python heap. Object memory is the one allocated by PyObject_{New, NewVar}, i.e. the one that holds the object's representation defined by its C type structure, *excluding* any object-specific memory buffers that might be referenced by the structure (for type structures that have pointer fields). By default, the object memory allocator is implemented on top of the raw memory allocator. The PyCore_* macros can be defined to make the interpreter use a custom object memory allocator. They are reserved for internal memory management purposes exclusively. Both the core and extension modules should use the PyObject_* API. */ #ifndef PyCore_OBJECT_MALLOC_FUNC #undef PyCore_OBJECT_REALLOC_FUNC #undef PyCore_OBJECT_FREE_FUNC #define PyCore_OBJECT_MALLOC_FUNC PyCore_MALLOC_FUNC #define PyCore_OBJECT_REALLOC_FUNC PyCore_REALLOC_FUNC #define PyCore_OBJECT_FREE_FUNC PyCore_FREE_FUNC #endif #ifndef PyCore_OBJECT_MALLOC_PROTO #undef PyCore_OBJECT_REALLOC_PROTO #undef PyCore_OBJECT_FREE_PROTO #define PyCore_OBJECT_MALLOC_PROTO PyCore_MALLOC_PROTO #define PyCore_OBJECT_REALLOC_PROTO PyCore_REALLOC_PROTO #define PyCore_OBJECT_FREE_PROTO PyCore_FREE_PROTO #endif #ifdef NEED_TO_DECLARE_OBJECT_MALLOC_AND_FRIEND extern ANY *PyCore_OBJECT_MALLOC_FUNC PyCore_OBJECT_MALLOC_PROTO; extern ANY *PyCore_OBJECT_REALLOC_FUNC PyCore_OBJECT_REALLOC_PROTO; extern void PyCore_OBJECT_FREE_FUNC PyCore_OBJECT_FREE_PROTO; #endif #ifndef PyCore_OBJECT_MALLOC #undef PyCore_OBJECT_REALLOC #undef PyCore_OBJECT_FREE #define PyCore_OBJECT_MALLOC(n) PyCore_OBJECT_MALLOC_FUNC(n) #define PyCore_OBJECT_REALLOC(p, n) PyCore_OBJECT_REALLOC_FUNC((p), (n)) #define PyCore_OBJECT_FREE(p) PyCore_OBJECT_FREE_FUNC(p) #endif /* * Raw object memory interface * =========================== */ /* The use of this API should be avoided, unless a builtin object constructor inlines PyObject_{New, NewVar}, either because the latter functions cannot allocate the exact amount of needed memory, either for speed. This situation is exceptional, but occurs for some object constructors (PyBuffer_New, PyList_New...). Inlining PyObject_{New, NewVar} for objects that are supposed to belong to the Python heap is discouraged. If you really have to, make sure the object is initialized with PyObject_{Init, InitVar}. Do *not* inline PyObject_{Init, InitVar} for user-extension types or you might seriously interfere with Python's memory management. */ /* Functions */ /* Wrappers around PyCore_OBJECT_MALLOC and friends; useful if you need to be sure that you are using the same object memory allocator as Python. These wrappers *do not* make sure that allocating 0 bytes returns a non-NULL pointer. Returned pointers must be checked for NULL explicitly; no action is performed on failure. */ extern DL_IMPORT(ANY *) PyObject_Malloc Py_PROTO((size_t)); extern DL_IMPORT(ANY *) PyObject_Realloc Py_PROTO((ANY *, size_t)); extern DL_IMPORT(void) PyObject_Free Py_PROTO((ANY *)); /* Macros */ #define PyObject_MALLOC(n) PyCore_OBJECT_MALLOC(n) #define PyObject_REALLOC(op, n) PyCore_OBJECT_REALLOC((ANY *)(op), (n)) #define PyObject_FREE(op) PyCore_OBJECT_FREE((ANY *)(op)) /* * Generic object allocator interface * ================================== */ /* Functions */ extern DL_IMPORT(PyObject *) PyObject_Init Py_PROTO((PyObject *, PyTypeObject *)); extern DL_IMPORT(PyVarObject *) PyObject_InitVar Py_PROTO((PyVarObject *, PyTypeObject *, int)); extern DL_IMPORT(PyObject *) _PyObject_New Py_PROTO((PyTypeObject *)); extern DL_IMPORT(PyVarObject *) _PyObject_NewVar Py_PROTO((PyTypeObject *, int)); extern DL_IMPORT(void) _PyObject_Del Py_PROTO((PyObject *)); #define PyObject_New(type, typeobj) \ ( (type *) _PyObject_New(typeobj) ) #define PyObject_NewVar(type, typeobj, n) \ ( (type *) _PyObject_NewVar((typeobj), (n)) ) #define PyObject_Del(op) _PyObject_Del((PyObject *)(op)) /* Macros trading binary compatibility for speed. See also mymalloc.h. Note that these macros expect non-NULL object pointers.*/ #define PyObject_INIT(op, typeobj) \ ( _Py_NewReference((PyObject *)(op)), (op)->ob_type = (typeobj), (op) ) #define PyObject_INIT_VAR(op, typeobj, size) \ ( PyObject_INIT((op), (typeobj)) -> ob_size = (size), (op) ) #define _PyObject_SIZE(typeobj) ( (typeobj)->tp_basicsize ) #define _PyObject_VAR_SIZE(typeobj, n) \ ( (typeobj)->tp_basicsize + (n) * (typeobj)->tp_itemsize ) #define PyObject_NEW(type, typeobj) \ ( (type *) PyObject_Init( \ (PyObject *) PyObject_MALLOC( _PyObject_SIZE(typeobj) ), (typeobj)) ) #define PyObject_NEW_VAR(type, typeobj, n) \ ( (type *) PyObject_InitVar( \ (PyVarObject *) PyObject_MALLOC( _PyObject_VAR_SIZE((typeobj),(n)) ),\ (typeobj), (n)) ) #define PyObject_DEL(op) PyObject_FREE(op) /* This example code implements an object constructor with a custom allocator, where PyObject_New is inlined, and shows the important distinction between two steps (at least): 1) the actual allocation of the object storage; 2) the initialization of the Python specific fields in this storage with PyObject_{Init, InitVar}. PyObject * YourObject_New(...) { PyObject *op; op = (PyObject *) Your_Allocator(_PyObject_SIZE(YourTypeStruct)); if (op == NULL) return PyErr_NoMemory(); op = PyObject_Init(op, &YourTypeStruct); if (op == NULL) return NULL; op->ob_field = value; ... return op; } Note that in C++, the use of the new operator usually implies that the 1st step is performed automatically for you, so in a C++ class constructor you would start directly with PyObject_Init/InitVar. */ #ifdef __cplusplus } #endif #endif /* !Py_OBJIMPL_H */ From Vladimir.Marangozov@inrialpes.fr Sun Apr 30 20:42:38 2000 From: Vladimir.Marangozov@inrialpes.fr (Vladimir Marangozov) Date: Sun, 30 Apr 2000 21:42:38 +0200 (CEST) Subject: [Patches] PyMem [4/8] - Parser/* Message-ID: <200004301942.VAA15064@python.inrialpes.fr> [ Parser/* ] Nothing new compared to the first round of patches posted previously. Just mixed mallocs medicine. -- Vladimir MARANGOZOV | Vladimir.Marangozov@inrialpes.fr http://sirac.inrialpes.fr/~marangoz | tel:(+33-4)76615277 fax:76615252 -- Disclaimer: I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. -------------------------------[ cut here ]--------------------------- diff -cr PyCVS/Parser/myreadline.c PyMem/Parser/myreadline.c *** PyCVS/Parser/myreadline.c Sat Apr 29 00:24:10 2000 --- PyMem/Parser/myreadline.c Sat Apr 29 00:36:20 2000 *************** *** 89,95 **** int n; char *p; n = 100; ! if ((p = malloc(n)) == NULL) return NULL; fflush(stdout); if (prompt) --- 89,95 ---- int n; char *p; n = 100; ! if ((p = PyMem_MALLOC(n)) == NULL) return NULL; fflush(stdout); if (prompt) *************** *** 99,105 **** case 0: /* Normal case */ break; case 1: /* Interrupt */ ! free(p); return NULL; case -1: /* EOF */ case -2: /* Error */ --- 99,105 ---- case 0: /* Normal case */ break; case 1: /* Interrupt */ ! PyMem_FREE(p); return NULL; case -1: /* EOF */ case -2: /* Error */ *************** *** 117,135 **** n = strlen(p); while (n > 0 && p[n-1] != '\n') { int incr = n+2; ! p = realloc(p, n + incr); if (p == NULL) return NULL; if (my_fgets(p+n, incr, stdin) != 0) break; n += strlen(p+n); } ! return realloc(p, n+1); } /* By initializing this function pointer, systems embedding Python can ! override the readline function. */ char *(*PyOS_ReadlineFunctionPointer) Py_PROTO((char *)); --- 117,137 ---- n = strlen(p); while (n > 0 && p[n-1] != '\n') { int incr = n+2; ! p = PyMem_REALLOC(p, n + incr); if (p == NULL) return NULL; if (my_fgets(p+n, incr, stdin) != 0) break; n += strlen(p+n); } ! return PyMem_REALLOC(p, n+1); } /* By initializing this function pointer, systems embedding Python can ! override the readline function. ! ! Note: Python expects in return a buffer allocated with PyMem_Malloc. */ char *(*PyOS_ReadlineFunctionPointer) Py_PROTO((char *)); diff -cr PyCVS/Parser/parsetok.c PyMem/Parser/parsetok.c *** PyCVS/Parser/parsetok.c Sat Apr 29 00:24:10 2000 --- PyMem/Parser/parsetok.c Sat Apr 29 00:38:47 2000 *************** *** 192,198 **** err_ret->offset = tok->cur - tok->buf; if (tok->buf != NULL) { int len = tok->inp - tok->buf; ! err_ret->text = malloc(len + 1); if (err_ret->text != NULL) { if (len > 0) strncpy(err_ret->text, tok->buf, len); --- 192,198 ---- err_ret->offset = tok->cur - tok->buf; if (tok->buf != NULL) { int len = tok->inp - tok->buf; ! err_ret->text = PyMem_NEW(char, len + 1); if (err_ret->text != NULL) { if (len > 0) strncpy(err_ret->text, tok->buf, len); diff -cr PyCVS/Parser/pgenmain.c PyMem/Parser/pgenmain.c *** PyCVS/Parser/pgenmain.c Sat Apr 29 00:24:10 2000 --- PyMem/Parser/pgenmain.c Sat Apr 29 00:43:20 2000 *************** *** 139,145 **** putc(' ', stderr); } fprintf(stderr, "^\n"); ! free(err.text); } Py_Exit(1); } --- 139,145 ---- putc(' ', stderr); } fprintf(stderr, "^\n"); ! PyMem_DEL(err.text); } Py_Exit(1); } *************** *** 196,202 **** char *prompt; { int n = 1000; ! char *p = malloc(n); char *q; if (p == NULL) return NULL; --- 196,202 ---- char *prompt; { int n = 1000; ! char *p = PyMem_MALLOC(n); char *q; if (p == NULL) return NULL; *************** *** 209,215 **** n = strlen(p); if (n > 0 && p[n-1] != '\n') p[n-1] = '\n'; ! return realloc(p, n+1); } #ifdef HAVE_STDARG_PROTOTYPES --- 209,215 ---- n = strlen(p); if (n > 0 && p[n-1] != '\n') p[n-1] = '\n'; ! return PyMem_REALLOC(p, n+1); } #ifdef HAVE_STDARG_PROTOTYPES diff -cr PyCVS/Parser/tokenizer.c PyMem/Parser/tokenizer.c *** PyCVS/Parser/tokenizer.c Sat Apr 29 00:24:10 2000 --- PyMem/Parser/tokenizer.c Sun Apr 30 08:14:20 2000 *************** *** 219,244 **** if (new == NULL) tok->done = E_INTR; else if (*new == '\0') { ! free(new); tok->done = E_EOF; } else if (tok->start != NULL) { int start = tok->start - tok->buf; int oldlen = tok->cur - tok->buf; int newlen = oldlen + strlen(new); ! char *buf = realloc(tok->buf, newlen+1); tok->lineno++; if (buf == NULL) { ! free(tok->buf); tok->buf = NULL; ! free(new); tok->done = E_NOMEM; return EOF; } tok->buf = buf; tok->cur = tok->buf + oldlen; strcpy(tok->buf + oldlen, new); ! free(new); tok->inp = tok->buf + newlen; tok->end = tok->inp + 1; tok->start = tok->buf + start; --- 219,245 ---- if (new == NULL) tok->done = E_INTR; else if (*new == '\0') { ! PyMem_FREE(new); tok->done = E_EOF; } else if (tok->start != NULL) { int start = tok->start - tok->buf; int oldlen = tok->cur - tok->buf; int newlen = oldlen + strlen(new); ! char *buf = tok->buf; ! PyMem_RESIZE(buf, char, newlen+1); tok->lineno++; if (buf == NULL) { ! PyMem_DEL(tok->buf); tok->buf = NULL; ! PyMem_FREE(new); tok->done = E_NOMEM; return EOF; } tok->buf = buf; tok->cur = tok->buf + oldlen; strcpy(tok->buf + oldlen, new); ! PyMem_FREE(new); tok->inp = tok->buf + newlen; tok->end = tok->inp + 1; tok->start = tok->buf + start; *************** *** 246,252 **** else { tok->lineno++; if (tok->buf != NULL) ! free(tok->buf); tok->buf = new; tok->cur = tok->buf; tok->inp = strchr(tok->buf, '\0'); --- 247,253 ---- else { tok->lineno++; if (tok->buf != NULL) ! PyMem_DEL(tok->buf); tok->buf = new; tok->cur = tok->buf; tok->inp = strchr(tok->buf, '\0'); From Vladimir.Marangozov@inrialpes.fr Sun Apr 30 20:43:38 2000 From: Vladimir.Marangozov@inrialpes.fr (Vladimir Marangozov) Date: Sun, 30 Apr 2000 21:43:38 +0200 (CEST) Subject: [Patches] PyMem [5/8] - Python/* Message-ID: <200004301943.VAA15088@python.inrialpes.fr> [ Python/* ] Nothing new here either. Malloc cleanup + small syntaxic code improvement in import.c The docs should mention that PyOS_Readline, when hooked by embedding apps, expects in return a buffer allocated with PyMem_Malloc, because this buffer is subsequently released by Python with PyMem_FREE/DEL. -- Vladimir MARANGOZOV | Vladimir.Marangozov@inrialpes.fr http://sirac.inrialpes.fr/~marangoz | tel:(+33-4)76615277 fax:76615252 -- Disclaimer: I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. -------------------------------[ cut here ]--------------------------- diff -cr PyCVS/Python/bltinmodule.c PyMem/Python/bltinmodule.c *** PyCVS/Python/bltinmodule.c Sat Apr 29 00:24:10 2000 --- PyMem/Python/bltinmodule.c Sat Apr 29 00:50:10 2000 *************** *** 1875,1881 **** else { /* strip trailing '\n' */ result = PyString_FromStringAndSize(s, strlen(s)-1); } ! free(s); return result; } if (v != NULL) { --- 1875,1881 ---- else { /* strip trailing '\n' */ result = PyString_FromStringAndSize(s, strlen(s)-1); } ! PyMem_FREE(s); return result; } if (v != NULL) { diff -cr PyCVS/Python/ceval.c PyMem/Python/ceval.c *** PyCVS/Python/ceval.c Sat Apr 29 00:24:10 2000 --- PyMem/Python/ceval.c Sat Apr 29 00:54:34 2000 *************** *** 2558,2564 **** class); Py_DECREF(arg); ! PyMem_XDEL(k); return result; } --- 2558,2565 ---- class); Py_DECREF(arg); ! if (k != NULL) ! PyMem_DEL(k); return result; } diff -cr PyCVS/Python/compile.c PyMem/Python/compile.c *** PyCVS/Python/compile.c Sat Apr 29 00:24:10 2000 --- PyMem/Python/compile.c Sat Apr 29 00:57:18 2000 *************** *** 112,118 **** Py_XDECREF(co->co_filename); Py_XDECREF(co->co_name); Py_XDECREF(co->co_lnotab); ! PyMem_DEL(co); } static PyObject * --- 112,118 ---- Py_XDECREF(co->co_filename); Py_XDECREF(co->co_name); Py_XDECREF(co->co_lnotab); ! PyObject_DEL(co); } static PyObject * diff -cr PyCVS/Python/import.c PyMem/Python/import.c *** PyCVS/Python/import.c Sat Apr 29 00:24:10 2000 --- PyMem/Python/import.c Sat Apr 29 01:06:21 2000 *************** *** 119,125 **** ++countD; for (scan = _PyImport_StandardFiletab; scan->suffix != NULL; ++scan) ++countS; ! filetab = malloc((countD + countS + 1) * sizeof(struct filedescr)); memcpy(filetab, _PyImport_DynLoadFiletab, countD * sizeof(struct filedescr)); memcpy(filetab + countD, _PyImport_StandardFiletab, --- 119,125 ---- ++countD; for (scan = _PyImport_StandardFiletab; scan->suffix != NULL; ++scan) ++countS; ! filetab = PyMem_NEW(struct filedescr, countD + countS + 1); memcpy(filetab, _PyImport_DynLoadFiletab, countD * sizeof(struct filedescr)); memcpy(filetab + countD, _PyImport_StandardFiletab, *************** *** 2386,2395 **** } ! /* API for embedding applications that want to add their own entries to the ! table of built-in modules. This should normally be called *before* ! Py_Initialize(). When the malloc() or realloc() call fails, -1 is returned ! and the existing table is unchanged. After a similar function by Just van Rossum. */ --- 2386,2395 ---- } ! /* API for embedding applications that want to add their own entries ! to the table of built-in modules. This should normally be called ! *before* Py_Initialize(). When the table resize fails, -1 is ! returned and the existing table is unchanged. After a similar function by Just van Rossum. */ *************** *** 2410,2419 **** ; /* Allocate new memory for the combined table */ ! if (our_copy == NULL) ! p = malloc((i+n+1) * sizeof(struct _inittab)); ! else ! p = realloc(our_copy, (i+n+1) * sizeof(struct _inittab)); if (p == NULL) return -1; --- 2410,2417 ---- ; /* Allocate new memory for the combined table */ ! p = our_copy; ! PyMem_RESIZE(p, struct _inittab, i+n+1); if (p == NULL) return -1; diff -cr PyCVS/Python/marshal.c PyMem/Python/marshal.c *** PyCVS/Python/marshal.c Sat Apr 29 00:24:10 2000 --- PyMem/Python/marshal.c Sun Apr 30 16:49:11 2000 *************** *** 514,530 **** PyErr_SetString(PyExc_ValueError, "bad marshal data"); return NULL; } ! buffer = (char *)Py_Malloc(n); if (buffer == NULL) ! return NULL; if (r_string(buffer, (int)n, p) != n) { ! free(buffer); PyErr_SetString(PyExc_EOFError, "EOF read where object expected"); return NULL; } v = PyUnicode_DecodeUTF8(buffer, n, NULL); ! free(buffer); return v; } --- 514,530 ---- PyErr_SetString(PyExc_ValueError, "bad marshal data"); return NULL; } ! buffer = PyMem_NEW(char, n); if (buffer == NULL) ! return PyErr_NoMemory(); if (r_string(buffer, (int)n, p) != n) { ! PyMem_DEL(buffer); PyErr_SetString(PyExc_EOFError, "EOF read where object expected"); return NULL; } v = PyUnicode_DecodeUTF8(buffer, n, NULL); ! PyMem_DEL(buffer); return v; } diff -cr PyCVS/Python/pythonrun.c PyMem/Python/pythonrun.c *** PyCVS/Python/pythonrun.c Sat Apr 29 00:24:10 2000 --- PyMem/Python/pythonrun.c Sat Apr 29 01:07:45 2000 *************** *** 542,548 **** if (n == NULL) { if (err.error == E_EOF) { if (err.text) ! free(err.text); return E_EOF; } err_input(&err); --- 542,548 ---- if (n == NULL) { if (err.error == E_EOF) { if (err.text) ! PyMem_DEL(err.text); return E_EOF; } err_input(&err); *************** *** 1008,1014 **** v = Py_BuildValue("(ziiz)", err->filename, err->lineno, err->offset, err->text); if (err->text != NULL) { ! free(err->text); err->text = NULL; } switch (err->error) { --- 1008,1014 ---- v = Py_BuildValue("(ziiz)", err->filename, err->lineno, err->offset, err->text); if (err->text != NULL) { ! PyMem_DEL(err->text); err->text = NULL; } switch (err->error) { diff -cr PyCVS/Python/traceback.c PyMem/Python/traceback.c *** PyCVS/Python/traceback.c Sat Apr 29 00:24:10 2000 --- PyMem/Python/traceback.c Sat Apr 29 01:09:25 2000 *************** *** 71,77 **** Py_TRASHCAN_SAFE_BEGIN(tb) Py_XDECREF(tb->tb_next); Py_XDECREF(tb->tb_frame); ! PyMem_DEL(tb); Py_TRASHCAN_SAFE_END(tb) } --- 71,77 ---- Py_TRASHCAN_SAFE_BEGIN(tb) Py_XDECREF(tb->tb_next); Py_XDECREF(tb->tb_frame); ! PyObject_DEL(tb); Py_TRASHCAN_SAFE_END(tb) } From Vladimir.Marangozov@inrialpes.fr Sun Apr 30 20:44:28 2000 From: Vladimir.Marangozov@inrialpes.fr (Vladimir Marangozov) Date: Sun, 30 Apr 2000 21:44:28 +0200 (CEST) Subject: [Patches] PyMem [6/8] - Objects/* Message-ID: <200004301944.VAA15111@python.inrialpes.fr> [ Objects/* ] Major interventions w.r.t the new interfaces. All builtin objects use the macro versions of the Object memory API. Object constructors that inline PyObject_New/NewVar have been marked as such. Object initializations with _Py_NewReference and the like have been hidden (at best) with PyObject_INIT/INIT_VAR. The functions for all memory APIs are implemented in object.c -- Vladimir MARANGOZOV | Vladimir.Marangozov@inrialpes.fr http://sirac.inrialpes.fr/~marangoz | tel:(+33-4)76615277 fax:76615252 -- Disclaimer: I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. -------------------------------[ cut here ]--------------------------- diff -cr PyCVS/Objects/bufferobject.c PyMem/Objects/bufferobject.c *** PyCVS/Objects/bufferobject.c Sat Apr 29 00:24:07 2000 --- PyMem/Objects/bufferobject.c Sat Apr 29 23:28:21 2000 *************** *** 188,198 **** "size must be zero or positive"); return NULL; } ! b = (PyBufferObject *)malloc(sizeof(*b) + size); if ( b == NULL ) return PyErr_NoMemory(); ! b->ob_type = &PyBuffer_Type; ! _Py_NewReference((PyObject *)b); b->b_base = NULL; b->b_ptr = (void *)(b + 1); --- 188,198 ---- "size must be zero or positive"); return NULL; } ! /* PyObject_New is inlined */ ! b = (PyBufferObject *) PyObject_MALLOC(sizeof(*b) + size); if ( b == NULL ) return PyErr_NoMemory(); ! PyObject_INIT((PyObject *)b, &PyBuffer_Type); b->b_base = NULL; b->b_ptr = (void *)(b + 1); *************** *** 212,218 **** PyBufferObject *self; { Py_XDECREF(self->b_base); ! free((void *)self); } static int --- 212,218 ---- PyBufferObject *self; { Py_XDECREF(self->b_base); ! PyObject_DEL(self); } static int diff -cr PyCVS/Objects/classobject.c PyMem/Objects/classobject.c *** PyCVS/Objects/classobject.c Sat Apr 29 00:24:07 2000 --- PyMem/Objects/classobject.c Sun Apr 30 07:25:15 2000 *************** *** 147,153 **** Py_XDECREF(op->cl_getattr); Py_XDECREF(op->cl_setattr); Py_XDECREF(op->cl_delattr); ! free((ANY *)op); } static PyObject * --- 147,153 ---- Py_XDECREF(op->cl_getattr); Py_XDECREF(op->cl_setattr); Py_XDECREF(op->cl_delattr); ! PyObject_DEL(op); } static PyObject * *************** *** 561,567 **** #endif /* Py_TRACE_REFS */ Py_DECREF(inst->in_class); Py_XDECREF(inst->in_dict); ! free((ANY *)inst); } static PyObject * --- 561,567 ---- #endif /* Py_TRACE_REFS */ Py_DECREF(inst->in_class); Py_XDECREF(inst->in_dict); ! PyObject_DEL(inst); } static PyObject * *************** *** 1498,1505 **** im = free_list; if (im != NULL) { free_list = (PyMethodObject *)(im->im_self); ! im->ob_type = &PyMethod_Type; ! _Py_NewReference((PyObject *)im); } else { im = PyObject_NEW(PyMethodObject, &PyMethod_Type); --- 1498,1504 ---- im = free_list; if (im != NULL) { free_list = (PyMethodObject *)(im->im_self); ! PyObject_INIT(im, &PyMethod_Type); } else { im = PyObject_NEW(PyMethodObject, &PyMethod_Type); *************** *** 1691,1698 **** PyMethod_Fini() { while (free_list) { ! PyMethodObject *v = free_list; ! free_list = (PyMethodObject *)(v->im_self); ! PyMem_DEL(v); } } --- 1690,1697 ---- PyMethod_Fini() { while (free_list) { ! PyMethodObject *im = free_list; ! free_list = (PyMethodObject *)(im->im_self); ! PyObject_DEL(im); } } diff -cr PyCVS/Objects/cobject.c PyMem/Objects/cobject.c *** PyCVS/Objects/cobject.c Sat Apr 29 00:24:07 2000 --- PyMem/Objects/cobject.c Sat Apr 29 23:31:09 2000 *************** *** 151,157 **** else (self->destructor)(self->cobject); } ! PyMem_DEL(self); } --- 151,157 ---- else (self->destructor)(self->cobject); } ! PyObject_DEL(self); } diff -cr PyCVS/Objects/complexobject.c PyMem/Objects/complexobject.c *** PyCVS/Objects/complexobject.c Sat Apr 29 00:24:07 2000 --- PyMem/Objects/complexobject.c Sat Apr 29 23:31:23 2000 *************** *** 166,178 **** PyComplex_FromCComplex(cval) Py_complex cval; { ! register PyComplexObject *op = ! (PyComplexObject *) malloc(sizeof(PyComplexObject)); if (op == NULL) return PyErr_NoMemory(); ! op->ob_type = &PyComplex_Type; op->cval = cval; - _Py_NewReference((PyObject *)op); return (PyObject *) op; } --- 166,179 ---- PyComplex_FromCComplex(cval) Py_complex cval; { ! register PyComplexObject *op; ! ! /* PyObject_New is inlined */ ! op = (PyComplexObject *) PyObject_MALLOC(sizeof(PyComplexObject)); if (op == NULL) return PyErr_NoMemory(); ! PyObject_INIT(op, &PyComplex_Type); op->cval = cval; return (PyObject *) op; } *************** *** 226,232 **** complex_dealloc(op) PyObject *op; { ! PyMem_DEL(op); } --- 227,233 ---- complex_dealloc(op) PyObject *op; { ! PyObject_DEL(op); } diff -cr PyCVS/Objects/dictobject.c PyMem/Objects/dictobject.c *** PyCVS/Objects/dictobject.c Sat Apr 29 00:24:07 2000 --- PyMem/Objects/dictobject.c Sun Apr 30 07:27:21 2000 *************** *** 277,283 **** break; } } ! newtable = (dictentry *) malloc(sizeof(dictentry) * newsize); if (newtable == NULL) { PyErr_NoMemory(); return -1; --- 277,283 ---- break; } } ! newtable = PyMem_NEW(dictentry, newsize); if (newtable == NULL) { PyErr_NoMemory(); return -1; *************** *** 301,307 **** } } ! PyMem_XDEL(oldtable); return 0; } --- 301,308 ---- } } ! if (oldtable != NULL) ! PyMem_DEL(oldtable); return 0; } *************** *** 488,495 **** Py_DECREF(ep->me_value); } } ! PyMem_XDEL(mp->ma_table); ! PyMem_DEL(mp); Py_TRASHCAN_SAFE_END(mp) } --- 489,497 ---- Py_DECREF(ep->me_value); } } ! if (mp->ma_table != NULL) ! PyMem_DEL(mp->ma_table); ! PyObject_DEL(mp); Py_TRASHCAN_SAFE_END(mp) } diff -cr PyCVS/Objects/fileobject.c PyMem/Objects/fileobject.c *** PyCVS/Objects/fileobject.c Sat Apr 29 00:24:07 2000 --- PyMem/Objects/fileobject.c Sat Apr 29 23:41:14 2000 *************** *** 215,221 **** if (f->f_mode != NULL) { Py_DECREF(f->f_mode); } ! free((char *)f); } static PyObject * --- 215,221 ---- if (f->f_mode != NULL) { Py_DECREF(f->f_mode); } ! PyObject_DEL(f); } static PyObject * diff -cr PyCVS/Objects/floatobject.c PyMem/Objects/floatobject.c *** PyCVS/Objects/floatobject.c Sat Apr 29 00:24:07 2000 --- PyMem/Objects/floatobject.c Sun Apr 30 09:22:23 2000 *************** *** 98,106 **** #define BHEAD_SIZE 8 /* Enough for a 64-bit pointer */ #define N_FLOATOBJECTS ((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyFloatObject)) - #define PyMem_MALLOC malloc - #define PyMem_FREE free - struct _floatblock { struct _floatblock *next; PyFloatObject objects[N_FLOATOBJECTS]; --- 98,103 ---- *************** *** 115,123 **** fill_free_list() { PyFloatObject *p, *q; ! p = (PyFloatObject *)PyMem_MALLOC(sizeof(PyFloatBlock)); if (p == NULL) ! return (PyFloatObject *)PyErr_NoMemory(); ((PyFloatBlock *)p)->next = block_list; block_list = (PyFloatBlock *)p; p = &((PyFloatBlock *)p)->objects[0]; --- 112,121 ---- fill_free_list() { PyFloatObject *p, *q; ! /* XXX Float blocks escape the object heap. Use PyObject_MALLOC ??? */ ! p = (PyFloatObject *) PyMem_MALLOC(sizeof(PyFloatBlock)); if (p == NULL) ! return (PyFloatObject *) PyErr_NoMemory(); ((PyFloatBlock *)p)->next = block_list; block_list = (PyFloatBlock *)p; p = &((PyFloatBlock *)p)->objects[0]; *************** *** 141,151 **** if ((free_list = fill_free_list()) == NULL) return NULL; } op = free_list; free_list = (PyFloatObject *)op->ob_type; ! op->ob_type = &PyFloat_Type; op->ob_fval = fval; - _Py_NewReference((PyObject *)op); return (PyObject *) op; } --- 139,149 ---- if ((free_list = fill_free_list()) == NULL) return NULL; } + /* PyObject_New is inlined */ op = free_list; free_list = (PyFloatObject *)op->ob_type; ! PyObject_INIT(op, &PyFloat_Type); op->ob_fval = fval; return (PyObject *) op; } *************** *** 779,785 **** } } else { ! PyMem_FREE(list); bf++; } fsum += frem; --- 777,783 ---- } } else { ! PyMem_FREE(list); /* XXX PyObject_FREE ??? */ bf++; } fsum += frem; diff -cr PyCVS/Objects/frameobject.c PyMem/Objects/frameobject.c *** PyCVS/Objects/frameobject.c Sat Apr 29 00:24:07 2000 --- PyMem/Objects/frameobject.c Sun Apr 30 07:33:22 2000 *************** *** 180,207 **** if (builtins != NULL && !PyDict_Check(builtins)) builtins = NULL; if (free_list == NULL) { f = (PyFrameObject *) ! malloc(sizeof(PyFrameObject) + ! extras*sizeof(PyObject *)); if (f == NULL) return (PyFrameObject *)PyErr_NoMemory(); ! f->ob_type = &PyFrame_Type; ! _Py_NewReference((PyObject *)f); } else { f = free_list; free_list = free_list->f_back; if (f->f_nlocals + f->f_stacksize < extras) { f = (PyFrameObject *) ! realloc(f, sizeof(PyFrameObject) + ! extras*sizeof(PyObject *)); if (f == NULL) return (PyFrameObject *)PyErr_NoMemory(); } else extras = f->f_nlocals + f->f_stacksize; ! f->ob_type = &PyFrame_Type; ! _Py_NewReference((PyObject *)f); } if (builtins == NULL) { /* No builtins! Make up a minimal one. */ --- 180,206 ---- if (builtins != NULL && !PyDict_Check(builtins)) builtins = NULL; if (free_list == NULL) { + /* PyObject_New is inlined */ f = (PyFrameObject *) ! PyObject_MALLOC(sizeof(PyFrameObject) + ! extras*sizeof(PyObject *)); if (f == NULL) return (PyFrameObject *)PyErr_NoMemory(); ! PyObject_INIT(f, &PyFrame_Type); } else { f = free_list; free_list = free_list->f_back; if (f->f_nlocals + f->f_stacksize < extras) { f = (PyFrameObject *) ! PyObject_REALLOC(f, sizeof(PyFrameObject) + ! extras*sizeof(PyObject *)); if (f == NULL) return (PyFrameObject *)PyErr_NoMemory(); } else extras = f->f_nlocals + f->f_stacksize; ! PyObject_INIT(f, &PyFrame_Type); } if (builtins == NULL) { /* No builtins! Make up a minimal one. */ *************** *** 376,381 **** while (free_list != NULL) { PyFrameObject *f = free_list; free_list = free_list->f_back; ! PyMem_DEL(f); } } --- 375,380 ---- while (free_list != NULL) { PyFrameObject *f = free_list; free_list = free_list->f_back; ! PyObject_DEL(f); } } diff -cr PyCVS/Objects/funcobject.c PyMem/Objects/funcobject.c *** PyCVS/Objects/funcobject.c Sat Apr 29 00:24:07 2000 --- PyMem/Objects/funcobject.c Sat Apr 29 23:55:01 2000 *************** *** 191,197 **** Py_DECREF(op->func_name); Py_XDECREF(op->func_defaults); Py_XDECREF(op->func_doc); ! PyMem_DEL(op); } static PyObject* --- 191,197 ---- Py_DECREF(op->func_name); Py_XDECREF(op->func_defaults); Py_XDECREF(op->func_doc); ! PyObject_DEL(op); } static PyObject* diff -cr PyCVS/Objects/intobject.c PyMem/Objects/intobject.c *** PyCVS/Objects/intobject.c Sat Apr 29 00:24:07 2000 --- PyMem/Objects/intobject.c Sun Apr 30 09:23:01 2000 *************** *** 94,102 **** #define BHEAD_SIZE 8 /* Enough for a 64-bit pointer */ #define N_INTOBJECTS ((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyIntObject)) - #define PyMem_MALLOC malloc - #define PyMem_FREE free - struct _intblock { struct _intblock *next; PyIntObject objects[N_INTOBJECTS]; --- 94,99 ---- *************** *** 111,119 **** fill_free_list() { PyIntObject *p, *q; ! p = (PyIntObject *)PyMem_MALLOC(sizeof(PyIntBlock)); if (p == NULL) ! return (PyIntObject *)PyErr_NoMemory(); ((PyIntBlock *)p)->next = block_list; block_list = (PyIntBlock *)p; p = &((PyIntBlock *)p)->objects[0]; --- 108,117 ---- fill_free_list() { PyIntObject *p, *q; ! /* XXX Int blocks escape the object heap. Use PyObject_MALLOC ??? */ ! p = (PyIntObject *) PyMem_MALLOC(sizeof(PyIntBlock)); if (p == NULL) ! return (PyIntObject *) PyErr_NoMemory(); ((PyIntBlock *)p)->next = block_list; block_list = (PyIntBlock *)p; p = &((PyIntBlock *)p)->objects[0]; *************** *** 164,174 **** if ((free_list = fill_free_list()) == NULL) return NULL; } v = free_list; free_list = (PyIntObject *)v->ob_type; ! v->ob_type = &PyInt_Type; v->ob_ival = ival; - _Py_NewReference((PyObject *)v); #if NSMALLNEGINTS + NSMALLPOSINTS > 0 if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) { /* save this one for a following allocation */ --- 162,172 ---- if ((free_list = fill_free_list()) == NULL) return NULL; } + /* PyObject_New is inlined */ v = free_list; free_list = (PyIntObject *)v->ob_type; ! PyObject_INIT(v, &PyInt_Type); v->ob_ival = ival; #if NSMALLNEGINTS + NSMALLPOSINTS > 0 if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) { /* save this one for a following allocation */ *************** *** 933,939 **** } } else { ! PyMem_FREE(list); bf++; } isum += irem; --- 931,937 ---- } } else { ! PyMem_FREE(list); /* XXX PyObject_FREE ??? */ bf++; } isum += irem; diff -cr PyCVS/Objects/listobject.c PyMem/Objects/listobject.c *** PyCVS/Objects/listobject.c Sat Apr 29 00:24:07 2000 --- PyMem/Objects/listobject.c Sun Apr 30 00:48:14 2000 *************** *** 70,76 **** if (nbytes / sizeof(PyObject *) != (size_t)size) { return PyErr_NoMemory(); } ! op = (PyListObject *) malloc(sizeof(PyListObject)); if (op == NULL) { return PyErr_NoMemory(); } --- 70,77 ---- if (nbytes / sizeof(PyObject *) != (size_t)size) { return PyErr_NoMemory(); } ! /* PyObject_NewVar is inlined */ ! op = (PyListObject *) PyObject_MALLOC(sizeof(PyListObject)); if (op == NULL) { return PyErr_NoMemory(); } *************** *** 78,94 **** op->ob_item = NULL; } else { ! op->ob_item = (PyObject **) malloc(nbytes); if (op->ob_item == NULL) { ! free((ANY *)op); return PyErr_NoMemory(); } } ! op->ob_type = &PyList_Type; ! op->ob_size = size; for (i = 0; i < size; i++) op->ob_item[i] = NULL; - _Py_NewReference((PyObject *)op); return (PyObject *) op; } --- 79,93 ---- op->ob_item = NULL; } else { ! op->ob_item = (PyObject **) PyMem_MALLOC(nbytes); if (op->ob_item == NULL) { ! PyObject_FREE(op); return PyErr_NoMemory(); } } ! PyObject_INIT_VAR(op, &PyList_Type, size); for (i = 0; i < size; i++) op->ob_item[i] = NULL; return (PyObject *) op; } *************** *** 225,233 **** while (--i >= 0) { Py_XDECREF(op->ob_item[i]); } ! free((ANY *)op->ob_item); } ! free((ANY *)op); Py_TRASHCAN_SAFE_END(op) } --- 224,232 ---- while (--i >= 0) { Py_XDECREF(op->ob_item[i]); } ! PyMem_FREE(op->ob_item); } ! PyObject_DEL(op); Py_TRASHCAN_SAFE_END(op) } *************** *** 501,507 **** else { /* Insert d items; recycle ihigh-ilow items */ NRESIZE(item, PyObject *, a->ob_size + d); if (item == NULL) { ! PyMem_XDEL(recycle); PyErr_NoMemory(); return -1; } --- 500,507 ---- else { /* Insert d items; recycle ihigh-ilow items */ NRESIZE(item, PyObject *, a->ob_size + d); if (item == NULL) { ! if (recycle != NULL) ! PyMem_DEL(recycle); PyErr_NoMemory(); return -1; } diff -cr PyCVS/Objects/longobject.c PyMem/Objects/longobject.c *** PyCVS/Objects/longobject.c Sat Apr 29 00:24:07 2000 --- PyMem/Objects/longobject.c Sun Apr 30 00:13:09 2000 *************** *** 995,1001 **** long_dealloc(v) PyObject *v; { ! PyMem_DEL(v); } static PyObject * --- 995,1001 ---- long_dealloc(v) PyObject *v; { ! PyObject_DEL(v); } static PyObject * diff -cr PyCVS/Objects/methodobject.c PyMem/Objects/methodobject.c *** PyCVS/Objects/methodobject.c Sat Apr 29 00:24:07 2000 --- PyMem/Objects/methodobject.c Sun Apr 30 00:15:12 2000 *************** *** 46,53 **** op = free_list; if (op != NULL) { free_list = (PyCFunctionObject *)(op->m_self); ! op->ob_type = &PyCFunction_Type; ! _Py_NewReference((PyObject *)op); } else { op = PyObject_NEW(PyCFunctionObject, &PyCFunction_Type); --- 46,52 ---- op = free_list; if (op != NULL) { free_list = (PyCFunctionObject *)(op->m_self); ! PyObject_INIT(op, &PyCFunction_Type); } else { op = PyObject_NEW(PyCFunctionObject, &PyCFunction_Type); *************** *** 288,293 **** while (free_list) { PyCFunctionObject *v = free_list; free_list = (PyCFunctionObject *)(v->m_self); ! PyMem_DEL(v); } } --- 287,292 ---- while (free_list) { PyCFunctionObject *v = free_list; free_list = (PyCFunctionObject *)(v->m_self); ! PyObject_DEL(v); } } diff -cr PyCVS/Objects/moduleobject.c PyMem/Objects/moduleobject.c *** PyCVS/Objects/moduleobject.c Sat Apr 29 00:24:07 2000 --- PyMem/Objects/moduleobject.c Sun Apr 30 00:16:34 2000 *************** *** 170,176 **** _PyModule_Clear((PyObject *)m); Py_DECREF(m->md_dict); } ! free((char *)m); } static PyObject * --- 170,176 ---- _PyModule_Clear((PyObject *)m); Py_DECREF(m->md_dict); } ! PyObject_DEL(m); } static PyObject * diff -cr PyCVS/Objects/object.c PyMem/Objects/object.c *** PyCVS/Objects/object.c Sat Apr 29 00:24:07 2000 --- PyMem/Objects/object.c Sun Apr 30 07:34:17 2000 *************** *** 112,161 **** } #endif - #ifndef MS_COREDLL PyObject * ! _PyObject_New(tp) ! PyTypeObject *tp; ! #else ! PyObject * ! _PyObject_New(tp,op) ! PyTypeObject *tp; PyObject *op; ! #endif { ! #ifndef MS_COREDLL ! PyObject *op = (PyObject *) malloc(tp->tp_basicsize); ! #endif ! if (op == NULL) ! return PyErr_NoMemory(); ! op->ob_type = tp; _Py_NewReference(op); return op; } - #ifndef MS_COREDLL PyVarObject * ! _PyObject_NewVar(tp, size) PyTypeObject *tp; int size; ! #else PyVarObject * ! _PyObject_NewVar(tp, size, op) PyTypeObject *tp; int size; - PyVarObject *op; - #endif { ! #ifndef MS_COREDLL ! PyVarObject *op = (PyVarObject *) ! malloc(tp->tp_basicsize + size * tp->tp_itemsize); ! #endif if (op == NULL) return (PyVarObject *)PyErr_NoMemory(); ! op->ob_type = tp; ! op->ob_size = size; ! _Py_NewReference((PyObject *)op); ! return op; } int --- 112,179 ---- } #endif PyObject * ! PyObject_Init(op, tp) PyObject *op; ! PyTypeObject *tp; { ! if (op == NULL) { ! PyErr_SetString(PyExc_SystemError, ! "NULL object passed to PyObject_Init"); ! return op; ! } ! /* Any changes should be reflected in PyObject_INIT (objimpl.h) */ _Py_NewReference(op); + op->ob_type = tp; return op; } PyVarObject * ! PyObject_InitVar(op, tp, size) ! PyVarObject *op; PyTypeObject *tp; int size; ! { ! if (op == NULL) { ! PyErr_SetString(PyExc_SystemError, ! "NULL object passed to PyObject_InitVar"); ! return op; ! } ! /* Any changes should be reflected in PyObject_INIT_VAR */ ! _Py_NewReference(op); ! op->ob_type = tp; ! op->ob_size = size; ! return op; ! } ! ! PyObject * ! _PyObject_New(tp) ! PyTypeObject *tp; ! { ! PyObject *op; ! op = (PyObject *) PyObject_MALLOC(_PyObject_SIZE(tp)); ! if (op == NULL) ! return PyErr_NoMemory(); ! return PyObject_INIT(op, tp); ! } ! PyVarObject * ! _PyObject_NewVar(tp, size) PyTypeObject *tp; int size; { ! PyVarObject *op; ! op = (PyVarObject *) PyObject_MALLOC(_PyObject_VAR_SIZE(tp, size)); if (op == NULL) return (PyVarObject *)PyErr_NoMemory(); ! return PyObject_INIT_VAR(op, tp, size); ! } ! ! void ! _PyObject_Del(op) ! PyObject *op; ! { ! PyObject_FREE(op); } int *************** *** 888,917 **** int (*_Py_abstract_hack) Py_FPROTO((PyObject *)) = &PyObject_Length; ! /* Malloc wrappers (see mymalloc.h) */ ! ! /* The Py_{Malloc,Realloc} wrappers call PyErr_NoMemory() on failure */ ANY * ! Py_Malloc(nbytes) size_t nbytes; { - ANY *p; #if _PyMem_EXTRA > 0 if (nbytes == 0) nbytes = _PyMem_EXTRA; #endif ! p = malloc(nbytes); ! if (p != NULL) ! return p; ! else { ! PyErr_NoMemory(); ! return NULL; ! } } ANY * ! Py_Realloc(p, nbytes) ANY *p; size_t nbytes; { --- 906,926 ---- int (*_Py_abstract_hack) Py_FPROTO((PyObject *)) = &PyObject_Length; ! /* Python's malloc wrappers (see mymalloc.h) */ ANY * ! PyMem_Malloc(nbytes) size_t nbytes; { #if _PyMem_EXTRA > 0 if (nbytes == 0) nbytes = _PyMem_EXTRA; #endif ! return PyMem_MALLOC(nbytes); } ANY * ! PyMem_Realloc(p, nbytes) ANY *p; size_t nbytes; { *************** *** 919,970 **** if (nbytes == 0) nbytes = _PyMem_EXTRA; #endif ! p = realloc(p, nbytes); ! if (p != NULL) ! return p; ! else { ! PyErr_NoMemory(); ! return NULL; ! } } void ! Py_Free(p) ANY *p; { ! free(p); } ! /* The PyMem_{Malloc,Realloc} wrappers don't call anything on failure */ ANY * ! PyMem_Malloc(nbytes) size_t nbytes; { ! #if _PyMem_EXTRA > 0 ! if (nbytes == 0) ! nbytes = _PyMem_EXTRA; ! #endif ! return malloc(nbytes); } ANY * ! PyMem_Realloc(p, nbytes) ANY *p; size_t nbytes; { ! #if _PyMem_EXTRA > 0 ! if (nbytes == 0) ! nbytes = _PyMem_EXTRA; ! #endif ! return realloc(p, nbytes); } void ! PyMem_Free(p) ANY *p; { ! free(p); } --- 928,966 ---- if (nbytes == 0) nbytes = _PyMem_EXTRA; #endif ! return PyMem_REALLOC(p, nbytes); } void ! PyMem_Free(p) ANY *p; { ! PyMem_FREE(p); } ! ! /* Python's object malloc wrappers (see objimpl.h) */ ANY * ! PyObject_Malloc(nbytes) size_t nbytes; { ! return PyObject_MALLOC(nbytes); } ANY * ! PyObject_Realloc(p, nbytes) ANY *p; size_t nbytes; { ! return PyObject_REALLOC(p, nbytes); } void ! PyObject_Free(p) ANY *p; { ! PyObject_FREE(p); } diff -cr PyCVS/Objects/rangeobject.c PyMem/Objects/rangeobject.c *** PyCVS/Objects/rangeobject.c Sat Apr 29 00:24:07 2000 --- PyMem/Objects/rangeobject.c Sun Apr 30 00:33:25 2000 *************** *** 61,67 **** range_dealloc(r) rangeobject *r; { ! PyMem_DEL(r); } static PyObject * --- 61,67 ---- range_dealloc(r) rangeobject *r; { ! PyObject_DEL(r); } static PyObject * diff -cr PyCVS/Objects/sliceobject.c PyMem/Objects/sliceobject.c *** PyCVS/Objects/sliceobject.c Sat Apr 29 00:24:07 2000 --- PyMem/Objects/sliceobject.c Sun Apr 30 00:44:54 2000 *************** *** 57,64 **** PyObject *stop; PyObject *step; { ! PySliceObject *obj = ! (PySliceObject *) PyObject_NEW(PySliceObject, &PySlice_Type); if (step == NULL) step = Py_None; Py_INCREF(step); --- 57,63 ---- PyObject *stop; PyObject *step; { ! PySliceObject *obj = PyObject_NEW(PySliceObject, &PySlice_Type); if (step == NULL) step = Py_None; Py_INCREF(step); *************** *** 115,121 **** Py_DECREF(r->step); Py_DECREF(r->start); Py_DECREF(r->stop); ! PyMem_DEL(r); } static PyObject * --- 114,120 ---- Py_DECREF(r->step); Py_DECREF(r->start); Py_DECREF(r->stop); ! PyObject_DEL(r); } static PyObject * diff -cr PyCVS/Objects/stringobject.c PyMem/Objects/stringobject.c *** PyCVS/Objects/stringobject.c Sat Apr 29 00:24:07 2000 --- PyMem/Objects/stringobject.c Sun Apr 30 01:02:47 2000 *************** *** 92,110 **** return (PyObject *)op; } #endif /* DONT_SHARE_SHORT_STRINGS */ op = (PyStringObject *) ! malloc(sizeof(PyStringObject) + size * sizeof(char)); if (op == NULL) return PyErr_NoMemory(); ! op->ob_type = &PyString_Type; ! op->ob_size = size; #ifdef CACHE_HASH op->ob_shash = -1; #endif #ifdef INTERN_STRINGS op->ob_sinterned = NULL; #endif - _Py_NewReference((PyObject *)op); if (str != NULL) memcpy(op->ob_sval, str, size); op->ob_sval[size] = '\0'; --- 92,110 ---- return (PyObject *)op; } #endif /* DONT_SHARE_SHORT_STRINGS */ + + /* PyObject_NewVar is inlined */ op = (PyStringObject *) ! PyObject_MALLOC(sizeof(PyStringObject) + size * sizeof(char)); if (op == NULL) return PyErr_NoMemory(); ! PyObject_INIT_VAR(op, &PyString_Type, size); #ifdef CACHE_HASH op->ob_shash = -1; #endif #ifdef INTERN_STRINGS op->ob_sinterned = NULL; #endif if (str != NULL) memcpy(op->ob_sval, str, size); op->ob_sval[size] = '\0'; *************** *** 142,160 **** return (PyObject *)op; } #endif /* DONT_SHARE_SHORT_STRINGS */ op = (PyStringObject *) ! malloc(sizeof(PyStringObject) + size * sizeof(char)); if (op == NULL) return PyErr_NoMemory(); ! op->ob_type = &PyString_Type; ! op->ob_size = size; #ifdef CACHE_HASH op->ob_shash = -1; #endif #ifdef INTERN_STRINGS op->ob_sinterned = NULL; #endif - _Py_NewReference((PyObject *)op); strcpy(op->ob_sval, str); #ifndef DONT_SHARE_SHORT_STRINGS if (size == 0) { --- 142,160 ---- return (PyObject *)op; } #endif /* DONT_SHARE_SHORT_STRINGS */ + + /* PyObject_NewVar is inlined */ op = (PyStringObject *) ! PyObject_MALLOC(sizeof(PyStringObject) + size * sizeof(char)); if (op == NULL) return PyErr_NoMemory(); ! PyObject_INIT_VAR(op, &PyString_Type, size); #ifdef CACHE_HASH op->ob_shash = -1; #endif #ifdef INTERN_STRINGS op->ob_sinterned = NULL; #endif strcpy(op->ob_sval, str); #ifndef DONT_SHARE_SHORT_STRINGS if (size == 0) { *************** *** 172,178 **** string_dealloc(op) PyObject *op; { ! PyMem_DEL(op); } int --- 172,178 ---- string_dealloc(op) PyObject *op; { ! PyObject_DEL(op); } int *************** *** 307,325 **** return (PyObject *)a; } size = a->ob_size + b->ob_size; op = (PyStringObject *) ! malloc(sizeof(PyStringObject) + size * sizeof(char)); if (op == NULL) return PyErr_NoMemory(); ! op->ob_type = &PyString_Type; ! op->ob_size = size; #ifdef CACHE_HASH op->ob_shash = -1; #endif #ifdef INTERN_STRINGS op->ob_sinterned = NULL; #endif - _Py_NewReference((PyObject *)op); memcpy(op->ob_sval, a->ob_sval, (int) a->ob_size); memcpy(op->ob_sval + a->ob_size, b->ob_sval, (int) b->ob_size); op->ob_sval[size] = '\0'; --- 307,324 ---- return (PyObject *)a; } size = a->ob_size + b->ob_size; + /* PyObject_NewVar is inlined */ op = (PyStringObject *) ! PyObject_MALLOC(sizeof(PyStringObject) + size * sizeof(char)); if (op == NULL) return PyErr_NoMemory(); ! PyObject_INIT_VAR(op, &PyString_Type, size); #ifdef CACHE_HASH op->ob_shash = -1; #endif #ifdef INTERN_STRINGS op->ob_sinterned = NULL; #endif memcpy(op->ob_sval, a->ob_sval, (int) a->ob_size); memcpy(op->ob_sval + a->ob_size, b->ob_sval, (int) b->ob_size); op->ob_sval[size] = '\0'; *************** *** 342,360 **** Py_INCREF(a); return (PyObject *)a; } op = (PyStringObject *) ! malloc(sizeof(PyStringObject) + size * sizeof(char)); if (op == NULL) return PyErr_NoMemory(); ! op->ob_type = &PyString_Type; ! op->ob_size = size; #ifdef CACHE_HASH op->ob_shash = -1; #endif #ifdef INTERN_STRINGS op->ob_sinterned = NULL; #endif - _Py_NewReference((PyObject *)op); for (i = 0; i < size; i += a->ob_size) memcpy(op->ob_sval+i, a->ob_sval, (int) a->ob_size); op->ob_sval[size] = '\0'; --- 341,358 ---- Py_INCREF(a); return (PyObject *)a; } + /* PyObject_NewVar is inlined */ op = (PyStringObject *) ! PyObject_MALLOC(sizeof(PyStringObject) + size * sizeof(char)); if (op == NULL) return PyErr_NoMemory(); ! PyObject_INIT_VAR(op, &PyString_Type, size); #ifdef CACHE_HASH op->ob_shash = -1; #endif #ifdef INTERN_STRINGS op->ob_sinterned = NULL; #endif for (i = 0; i < size; i += a->ob_size) memcpy(op->ob_sval+i, a->ob_sval, (int) a->ob_size); op->ob_sval[size] = '\0'; *************** *** 1498,1504 **** goto return_same; new_len = len + nfound*(sub_len - pat_len); ! new_s = (char *)malloc(new_len); if (new_s == NULL) return NULL; *out_len = new_len; --- 1496,1502 ---- goto return_same; new_len = len + nfound*(sub_len - pat_len); ! new_s = (char *)PyMem_MALLOC(new_len); if (new_s == NULL) return NULL; *out_len = new_len; *************** *** 1593,1599 **** } else { new = PyString_FromStringAndSize(new_s, out_len); ! free(new_s); } return new; } --- 1591,1597 ---- } else { new = PyString_FromStringAndSize(new_s, out_len); ! PyMem_FREE(new_s); } return new; } *************** *** 2273,2282 **** #endif _Py_ForgetReference(v); *pv = (PyObject *) ! realloc((char *)v, sizeof(PyStringObject) + newsize * sizeof(char)); if (*pv == NULL) { ! PyMem_DEL(v); PyErr_NoMemory(); return -1; } --- 2271,2280 ---- #endif _Py_ForgetReference(v); *pv = (PyObject *) ! PyObject_REALLOC((char *)v, sizeof(PyStringObject) + newsize * sizeof(char)); if (*pv == NULL) { ! PyObject_DEL(v); PyErr_NoMemory(); return -1; } diff -cr PyCVS/Objects/tupleobject.c PyMem/Objects/tupleobject.c *** PyCVS/Objects/tupleobject.c Sat Apr 29 00:24:07 2000 --- PyMem/Objects/tupleobject.c Sun Apr 30 01:20:11 2000 *************** *** 77,89 **** { free_tuples[size] = (PyTupleObject *) op->ob_item[0]; num_free_tuples[size]--; #ifdef COUNT_ALLOCS fast_tuple_allocs++; #endif - #ifdef Py_TRACE_REFS - op->ob_type = &PyTuple_Type; - op->ob_size = size; - #endif } else #endif --- 77,89 ---- { free_tuples[size] = (PyTupleObject *) op->ob_item[0]; num_free_tuples[size]--; + _Py_NewReference((PyObject *)op); + #ifdef Py_TRACE_REFS + PyObject_INIT_VAR(op, &PyTuple_Type, size); + #endif #ifdef COUNT_ALLOCS fast_tuple_allocs++; #endif } else #endif *************** *** 96,112 **** { return PyErr_NoMemory(); } ! ; ! op = (PyTupleObject *) malloc(nbytes); if (op == NULL) return PyErr_NoMemory(); ! op->ob_type = &PyTuple_Type; ! op->ob_size = size; } for (i = 0; i < size; i++) op->ob_item[i] = NULL; - _Py_NewReference((PyObject *)op); #if MAXSAVESIZE > 0 if (size == 0) { free_tuples[0] = op; --- 96,110 ---- { return PyErr_NoMemory(); } ! /* PyObject_NewVar is inlined */ ! op = (PyTupleObject *) PyObject_MALLOC(nbytes); if (op == NULL) return PyErr_NoMemory(); ! PyObject_INIT_VAR(op, &PyTuple_Type, size); } for (i = 0; i < size; i++) op->ob_item[i] = NULL; #if MAXSAVESIZE > 0 if (size == 0) { free_tuples[0] = op; *************** *** 193,199 **** } #endif } ! free((ANY *)op); done: Py_TRASHCAN_SAFE_END(op) } --- 191,197 ---- } #endif } ! PyObject_DEL(op); done: Py_TRASHCAN_SAFE_END(op) } *************** *** 530,540 **** #endif { sv = (PyTupleObject *) ! realloc((char *)v, sizeof(PyTupleObject) + newsize * sizeof(PyObject *)); *pv = (PyObject *) sv; if (sv == NULL) { ! PyMem_DEL(v); PyErr_NoMemory(); return -1; } --- 528,538 ---- #endif { sv = (PyTupleObject *) ! PyObject_REALLOC((char *)v, sizeof(PyTupleObject) + newsize * sizeof(PyObject *)); *pv = (PyObject *) sv; if (sv == NULL) { ! PyObject_DEL(v); PyErr_NoMemory(); return -1; } *************** *** 569,575 **** while (p) { q = p; p = (PyTupleObject *)(p->ob_item[0]); ! PyMem_DEL(q); } } #endif --- 567,573 ---- while (p) { q = p; p = (PyTupleObject *)(p->ob_item[0]); ! PyObject_DEL(q); } } #endif diff -cr PyCVS/Objects/unicodeobject.c PyMem/Objects/unicodeobject.c *** PyCVS/Objects/unicodeobject.c Sat Apr 29 00:24:07 2000 --- PyMem/Objects/unicodeobject.c Sun Apr 30 08:01:31 2000 *************** *** 200,213 **** unicode = unicode_freelist; unicode_freelist = *(PyUnicodeObject **)unicode_freelist; unicode_freelist_size--; ! unicode->ob_type = &PyUnicode_Type; ! _Py_NewReference((PyObject *)unicode); if (unicode->str) { /* Keep-Alive optimization: we only upsize the buffer, never downsize it. */ if ((unicode->length < length) && _PyUnicode_Resize(unicode, length)) { ! free(unicode->str); goto onError; } } --- 200,212 ---- unicode = unicode_freelist; unicode_freelist = *(PyUnicodeObject **)unicode_freelist; unicode_freelist_size--; ! PyObject_INIT(unicode, &PyUnicode_Type); if (unicode->str) { /* Keep-Alive optimization: we only upsize the buffer, never downsize it. */ if ((unicode->length < length) && _PyUnicode_Resize(unicode, length)) { ! PyMem_DEL(unicode->str); goto onError; } } *************** *** 233,239 **** onError: _Py_ForgetReference((PyObject *)unicode); ! PyMem_DEL(unicode); return NULL; } --- 232,238 ---- onError: _Py_ForgetReference((PyObject *)unicode); ! PyObject_DEL(unicode); return NULL; } *************** *** 243,249 **** if (unicode_freelist_size < MAX_UNICODE_FREELIST_SIZE) { /* Keep-Alive optimization */ if (unicode->length >= KEEPALIVE_SIZE_LIMIT) { ! free(unicode->str); unicode->str = NULL; unicode->length = 0; } --- 242,248 ---- if (unicode_freelist_size < MAX_UNICODE_FREELIST_SIZE) { /* Keep-Alive optimization */ if (unicode->length >= KEEPALIVE_SIZE_LIMIT) { ! PyMem_DEL(unicode->str); unicode->str = NULL; unicode->length = 0; } *************** *** 257,265 **** unicode_freelist_size++; } else { ! free(unicode->str); Py_XDECREF(unicode->utf8str); ! PyMem_DEL(unicode); } } --- 256,264 ---- unicode_freelist_size++; } else { ! PyMem_DEL(unicode->str); Py_XDECREF(unicode->utf8str); ! PyObject_DEL(unicode); } } *************** *** 4662,4670 **** PyUnicodeObject *v = u; u = *(PyUnicodeObject **)u; if (v->str) ! free(v->str); Py_XDECREF(v->utf8str); ! free(v); } Py_XDECREF(unicode_empty); } --- 4661,4669 ---- PyUnicodeObject *v = u; u = *(PyUnicodeObject **)u; if (v->str) ! PyMem_DEL(v->str); Py_XDECREF(v->utf8str); ! PyObject_DEL(v); } Py_XDECREF(unicode_empty); } diff -cr PyCVS/Objects/xxobject.c PyMem/Objects/xxobject.c *** PyCVS/Objects/xxobject.c Sat Apr 29 00:24:07 2000 --- PyMem/Objects/xxobject.c Sun Apr 30 08:02:58 2000 *************** *** 71,77 **** xxobject *xp; { Py_XDECREF(xp->x_attr); ! PyMem_DEL(xp); } static PyObject * --- 71,77 ---- xxobject *xp; { Py_XDECREF(xp->x_attr); ! PyObject_DEL(xp); } static PyObject * From Vladimir.Marangozov@inrialpes.fr Sun Apr 30 20:45:26 2000 From: Vladimir.Marangozov@inrialpes.fr (Vladimir Marangozov) Date: Sun, 30 Apr 2000 21:45:26 +0200 (CEST) Subject: [Patches] PyMem [7/8] - Modules/* Message-ID: <200004301945.VAA15135@python.inrialpes.fr> [ Modules/* ] Important: all object constructors and destructors in extension modules use the functions PyObject_New/Del. Some extensions are enabled by default, others aren't, so better be safe than sorry -- all PyObject_NEW/DEL have been lowercase'd because each one of these modules may not belong to the core. In terms of speed, this is fine, because there are no performance critical objects in there (i.e. with intense alloc/dealloc rates). Spread the word -- PyObject_NEW/DEL in extension modules is discouraged! However, all existing PyMem_NEW/DEL have been left unchanged. Fine by me. Someone may want to lowercase them too and see whether there's a performance drop -- I have no time to dig further in this direction... - Malloc cleanup + some "invisible bugs" corrected, like in nismodule.c It turns out that people have used PyMem_NEW/DEL by assuming that they correspond to standard malloc/free. Pfieu! Calls to "malloc" must be spelled in the code as "malloc", so if you're reading this and you're an author of an extension module in the standard distrbution, and you feel like you could be the author of an invisible bug, please double check your module. And if you're an author of a module that is not in the standard distribution, just do the same! I cannot track down invisible bugs. :-) -- Vladimir MARANGOZOV | Vladimir.Marangozov@inrialpes.fr http://sirac.inrialpes.fr/~marangoz | tel:(+33-4)76615277 fax:76615252 -- Disclaimer: I confirm that, to the best of my knowledge and belief, this contribution is free of any claims of third parties under copyright, patent or other rights or interests ("claims"). To the extent that I have any such claims, I hereby grant to CNRI a nonexclusive, irrevocable, royalty-free, worldwide license to reproduce, distribute, perform and/or display publicly, prepare derivative versions, and otherwise use this contribution as part of the Python software and its related documentation, or any derivative versions thereof, at no cost to CNRI or its licensed users, and to authorize others to do so. I acknowledge that CNRI may, at its sole discretion, decide whether or not to incorporate this contribution in the Python software and its related documentation. I further grant CNRI permission to use my name and other identifying information provided to CNRI by me for use in connection with the Python software and its related documentation. -------------------------------[ cut here ]--------------------------- diff -cr PyCVS/Modules/_localemodule.c PyMem/Modules/_localemodule.c *** PyCVS/Modules/_localemodule.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/_localemodule.c Sun Apr 30 03:37:37 2000 *************** *** 287,303 **** return NULL; /* assume no change in size, first */ n1=strlen(s)+1; ! buf=Py_Malloc(n1); ! if(!buf)return NULL; n2=strxfrm(buf,s,n1); if(n2>n1){ /* more space needed */ ! buf=Py_Realloc(buf,n2); ! if(!buf)return NULL; strxfrm(buf,s,n2); } result=PyString_FromString(buf); ! Py_Free(buf); return result; } --- 287,303 ---- return NULL; /* assume no change in size, first */ n1=strlen(s)+1; ! buf=PyMem_Malloc(n1); ! if(!buf)return PyErr_NoMemory(); n2=strxfrm(buf,s,n1); if(n2>n1){ /* more space needed */ ! buf=PyMem_Realloc(buf,n2); ! if(!buf)return PyErr_NoMemory(); strxfrm(buf,s,n2); } result=PyString_FromString(buf); ! PyMem_Free(buf); return result; } diff -cr PyCVS/Modules/_sre.c PyMem/Modules/_sre.c *** PyCVS/Modules/_sre.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/_sre.c Sun Apr 30 03:43:27 2000 *************** *** 848,854 **** &PyString_Type, &code, &groups, &groupindex)) return NULL; ! self = PyObject_NEW(PatternObject, &Pattern_Type); if (self == NULL) return NULL; --- 848,854 ---- &PyString_Type, &code, &groups, &groupindex)) return NULL; ! self = PyObject_New(PatternObject, &Pattern_Type); if (self == NULL) return NULL; *************** *** 886,892 **** if (status > 0) { /* create match object (with room for extra group marks) */ ! match = PyObject_NEW_VAR(MatchObject, &Match_Type, 2*pattern->groups); if (match == NULL) return NULL; --- 886,892 ---- if (status > 0) { /* create match object (with room for extra group marks) */ ! match = PyObject_NewVar(MatchObject, &Match_Type, 2*pattern->groups); if (match == NULL) return NULL; *************** *** 1002,1008 **** Py_XDECREF(self->code); Py_XDECREF(self->pattern); Py_XDECREF(self->groupindex); ! PyMem_DEL(self); } static PyObject* --- 1002,1008 ---- Py_XDECREF(self->code); Py_XDECREF(self->pattern); Py_XDECREF(self->groupindex); ! PyObject_Del(self); } static PyObject* *************** *** 1163,1169 **** { Py_XDECREF(self->string); Py_DECREF(self->pattern); ! PyMem_DEL(self); } static PyObject* --- 1163,1169 ---- { Py_XDECREF(self->string); Py_DECREF(self->pattern); ! PyObject_Del(self); } static PyObject* diff -cr PyCVS/Modules/_tkinter.c PyMem/Modules/_tkinter.c *** PyCVS/Modules/_tkinter.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/_tkinter.c Sun Apr 30 03:49:00 2000 *************** *** 469,475 **** TkappObject *v; char *argv0; ! v = PyObject_NEW(TkappObject, &Tkapp_Type); if (v == NULL) return NULL; --- 469,475 ---- TkappObject *v; char *argv0; ! v = PyObject_New(TkappObject, &Tkapp_Type); if (v == NULL) return NULL; *************** *** 1640,1646 **** { TkttObject *v; ! v = PyObject_NEW(TkttObject, &Tktt_Type); if (v == NULL) return NULL; --- 1640,1646 ---- { TkttObject *v; ! v = PyObject_New(TkttObject, &Tktt_Type); if (v == NULL) return NULL; *************** *** 1662,1668 **** Py_XDECREF(func); ! PyMem_DEL(self); } static PyObject * --- 1662,1668 ---- Py_XDECREF(func); ! PyObject_Del(self); } static PyObject * *************** *** 1910,1916 **** ENTER_TCL Tcl_DeleteInterp(Tkapp_Interp(self)); LEAVE_TCL ! PyMem_DEL(self); DisableEventHook(); } --- 1910,1916 ---- ENTER_TCL Tcl_DeleteInterp(Tkapp_Interp(self)); LEAVE_TCL ! PyObject_Del(self); DisableEventHook(); } diff -cr PyCVS/Modules/almodule.c PyMem/Modules/almodule.c *** PyCVS/Modules/almodule.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/almodule.c Sun Apr 30 06:45:25 2000 *************** *** 648,654 **** { alcobject *self; ! self = PyObject_NEW(alcobject, &Alctype); if (self == NULL) return NULL; /* XXXX Add your own initializers here */ --- 648,654 ---- { alcobject *self; ! self = PyObject_New(alcobject, &Alctype); if (self == NULL) return NULL; /* XXXX Add your own initializers here */ *************** *** 667,673 **** #else (void) ALfreeconfig(self->config); /* ignore errors */ #endif ! PyMem_DEL(self); } static PyObject * --- 667,673 ---- #else (void) ALfreeconfig(self->config); /* ignore errors */ #endif ! PyObject_Del(self); } static PyObject * *************** *** 1421,1427 **** { alpobject *self; ! self = PyObject_NEW(alpobject, &Alptype); if (self == NULL) return NULL; /* XXXX Add your own initializers here */ --- 1421,1427 ---- { alpobject *self; ! self = PyObject_New(alpobject, &Alptype); if (self == NULL) return NULL; /* XXXX Add your own initializers here */ *************** *** 1442,1448 **** ALcloseport(self->port); #endif } ! PyMem_DEL(self); } static PyObject * --- 1442,1448 ---- ALcloseport(self->port); #endif } ! PyObject_Del(self); } static PyObject * diff -cr PyCVS/Modules/arraymodule.c PyMem/Modules/arraymodule.c *** PyCVS/Modules/arraymodule.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/arraymodule.c Sun Apr 30 04:00:25 2000 *************** *** 346,352 **** if (nbytes / descr->itemsize != (size_t)size) { return PyErr_NoMemory(); } ! op = PyMem_NEW(arrayobject, 1); if (op == NULL) { return PyErr_NoMemory(); } --- 346,352 ---- if (nbytes / descr->itemsize != (size_t)size) { return PyErr_NoMemory(); } ! op = PyObject_NewVar(arrayobject, &Arraytype, size); if (op == NULL) { return PyErr_NoMemory(); } *************** *** 356,369 **** else { op->ob_item = PyMem_NEW(char, nbytes); if (op->ob_item == NULL) { ! PyMem_DEL(op); return PyErr_NoMemory(); } } - op->ob_type = &Arraytype; - op->ob_size = size; op->ob_descr = descr; - _Py_NewReference((PyObject *)op); return (PyObject *) op; } --- 356,366 ---- else { op->ob_item = PyMem_NEW(char, nbytes); if (op->ob_item == NULL) { ! PyObject_Del(op); return PyErr_NoMemory(); } } op->ob_descr = descr; return (PyObject *) op; } *************** *** 466,472 **** { if (op->ob_item != NULL) PyMem_DEL(op->ob_item); ! PyMem_DEL(op); } static int --- 463,469 ---- { if (op->ob_item != NULL) PyMem_DEL(op->ob_item); ! PyObject_Del(op); } static int diff -cr PyCVS/Modules/bsddbmodule.c PyMem/Modules/bsddbmodule.c *** PyCVS/Modules/bsddbmodule.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/bsddbmodule.c Sun Apr 30 04:06:15 2000 *************** *** 89,95 **** bsddbobject *dp; HASHINFO info; ! if ((dp = PyObject_NEW(bsddbobject, &Bsddbtype)) == NULL) return NULL; info.bsize = bsize; --- 89,95 ---- bsddbobject *dp; HASHINFO info; ! if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL) return NULL; info.bsize = bsize; *************** *** 143,149 **** bsddbobject *dp; BTREEINFO info; ! if ((dp = PyObject_NEW(bsddbobject, &Bsddbtype)) == NULL) return NULL; info.flags = btflags; --- 143,149 ---- bsddbobject *dp; BTREEINFO info; ! if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL) return NULL; info.flags = btflags; *************** *** 200,206 **** bsddbobject *dp; RECNOINFO info; ! if ((dp = PyObject_NEW(bsddbobject, &Bsddbtype)) == NULL) return NULL; info.flags = rnflags; --- 200,206 ---- bsddbobject *dp; RECNOINFO info; ! if ((dp = PyObject_New(bsddbobject, &Bsddbtype)) == NULL) return NULL; info.flags = rnflags; *************** *** 261,267 **** "Python bsddb: close errno %d in dealloc\n", errno); } ! PyMem_DEL(dp); } #ifdef WITH_THREAD --- 261,267 ---- "Python bsddb: close errno %d in dealloc\n", errno); } ! PyObject_Del(dp); } #ifdef WITH_THREAD diff -cr PyCVS/Modules/cPickle.c PyMem/Modules/cPickle.c *** PyCVS/Modules/cPickle.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/cPickle.c Sun Apr 30 04:10:32 2000 *************** *** 171,177 **** if (self->data) free(self->data); ! PyMem_DEL(self); } static PyTypeObject PdataType = { --- 171,177 ---- if (self->data) free(self->data); ! PyObject_Del(self); } static PyTypeObject PdataType = { *************** *** 186,192 **** Pdata_New() { Pdata *self; ! UNLESS (self = PyObject_NEW(Pdata, &PdataType)) return NULL; self->size=8; self->length=0; self->data=malloc(self->size * sizeof(PyObject*)); --- 186,192 ---- Pdata_New() { Pdata *self; ! UNLESS (self = PyObject_New(Pdata, &PdataType)) return NULL; self->size=8; self->length=0; self->data=malloc(self->size * sizeof(PyObject*)); *************** *** 2132,2138 **** newPicklerobject(PyObject *file, int bin) { Picklerobject *self; ! UNLESS (self = PyObject_NEW(Picklerobject, &Picklertype)) return NULL; self->fp = NULL; --- 2132,2138 ---- newPicklerobject(PyObject *file, int bin) { Picklerobject *self; ! UNLESS (self = PyObject_New(Picklerobject, &Picklertype)) return NULL; self->fp = NULL; *************** *** 2243,2249 **** free(self->write_buf); } ! PyMem_DEL(self); } --- 2243,2249 ---- free(self->write_buf); } ! PyObject_Del(self); } *************** *** 2885,2891 **** PyInstanceObject *inst; PyErr_Clear(); ! UNLESS (inst=PyObject_NEW(PyInstanceObject, &PyInstance_Type)) goto err; inst->in_class=(PyClassObject*)cls; Py_INCREF(cls); --- 2885,2891 ---- PyInstanceObject *inst; PyErr_Clear(); ! UNLESS (inst=PyObject_New(PyInstanceObject, &PyInstance_Type)) goto err; inst->in_class=(PyClassObject*)cls; Py_INCREF(cls); *************** *** 4036,4042 **** newUnpicklerobject(PyObject *f) { Unpicklerobject *self; ! UNLESS (self = PyObject_NEW(Unpicklerobject, &Unpicklertype)) return NULL; self->file = NULL; --- 4036,4042 ---- newUnpicklerobject(PyObject *f) { Unpicklerobject *self; ! UNLESS (self = PyObject_New(Unpicklerobject, &Unpicklertype)) return NULL; self->file = NULL; *************** *** 4141,4147 **** free(self->buf); } ! PyMem_DEL(self); } --- 4141,4147 ---- free(self->buf); } ! PyObject_Del(self); } diff -cr PyCVS/Modules/cStringIO.c PyMem/Modules/cStringIO.c *** PyCVS/Modules/cStringIO.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/cStringIO.c Sun Apr 30 04:13:56 2000 *************** *** 56,62 **** "\n" "This module provides a simple useful replacement for\n" "the StringIO module that is written in C. It does not provide the\n" ! "full generality if StringIO, but it provides anough for most\n" "applications and is especially useful in conjuction with the\n" "pickle module.\n" "\n" --- 56,62 ---- "\n" "This module provides a simple useful replacement for\n" "the StringIO module that is written in C. It does not provide the\n" ! "full generality if StringIO, but it provides enough for most\n" "applications and is especially useful in conjuction with the\n" "pickle module.\n" "\n" *************** *** 407,413 **** O_dealloc(Oobject *self) { if (self->buf != NULL) free(self->buf); ! PyMem_DEL(self); } static PyObject * --- 407,413 ---- O_dealloc(Oobject *self) { if (self->buf != NULL) free(self->buf); ! PyObject_Del(self); } static PyObject * *************** *** 465,471 **** newOobject(int size) { Oobject *self; ! self = PyObject_NEW(Oobject, &Otype); if (self == NULL) return NULL; self->pos=0; --- 465,471 ---- newOobject(int size) { Oobject *self; ! self = PyObject_New(Oobject, &Otype); if (self == NULL) return NULL; self->pos=0; *************** *** 536,542 **** static void I_dealloc(Iobject *self) { Py_XDECREF(self->pbuf); ! PyMem_DEL(self); } static PyObject * --- 536,542 ---- static void I_dealloc(Iobject *self) { Py_XDECREF(self->pbuf); ! PyObject_Del(self); } static PyObject * *************** *** 586,592 **** } buf = PyString_AS_STRING(s); size = PyString_GET_SIZE(s); ! UNLESS(self = PyObject_NEW(Iobject, &Itype)) return NULL; Py_INCREF(s); self->buf=buf; self->string_size=size; --- 586,592 ---- } buf = PyString_AS_STRING(s); size = PyString_GET_SIZE(s); ! UNLESS(self = PyObject_New(Iobject, &Itype)) return NULL; Py_INCREF(s); self->buf=buf; self->string_size=size; diff -cr PyCVS/Modules/cdmodule.c PyMem/Modules/cdmodule.c *** PyCVS/Modules/cdmodule.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/cdmodule.c Sun Apr 30 04:16:08 2000 *************** *** 447,453 **** { if (self->ob_cdplayer != NULL) CDclose(self->ob_cdplayer); ! PyMem_DEL(self); } static PyObject * --- 447,453 ---- { if (self->ob_cdplayer != NULL) CDclose(self->ob_cdplayer); ! PyObject_Del(self); } static PyObject * *************** *** 483,489 **** { cdplayerobject *p; ! p = PyObject_NEW(cdplayerobject, &CdPlayertype); if (p == NULL) return NULL; p->ob_cdplayer = cdp; --- 483,489 ---- { cdplayerobject *p; ! p = PyObject_New(cdplayerobject, &CdPlayertype); if (p == NULL) return NULL; p->ob_cdplayer = cdp; *************** *** 761,767 **** self->ob_cdcallbacks[i].ob_cdcallbackarg = NULL; } CDdeleteparser(self->ob_cdparser); ! PyMem_DEL(self); } static PyObject * --- 761,767 ---- self->ob_cdcallbacks[i].ob_cdcallbackarg = NULL; } CDdeleteparser(self->ob_cdparser); ! PyObject_Del(self); } static PyObject * *************** *** 799,805 **** cdparserobject *p; int i; ! p = PyObject_NEW(cdparserobject, &CdParsertype); if (p == NULL) return NULL; p->ob_cdparser = cdp; --- 799,805 ---- cdparserobject *p; int i; ! p = PyObject_New(cdparserobject, &CdParsertype); if (p == NULL) return NULL; p->ob_cdparser = cdp; diff -cr PyCVS/Modules/clmodule.c PyMem/Modules/clmodule.c *** PyCVS/Modules/clmodule.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/clmodule.c Sun Apr 30 04:18:47 2000 *************** *** 673,679 **** else clCloseDecompressor(SELF->ob_compressorHdl); } ! PyMem_DEL(self); } static PyObject * --- 673,679 ---- else clCloseDecompressor(SELF->ob_compressorHdl); } ! PyObject_Del(self); } static PyObject * *************** *** 713,719 **** if (!PyArg_Parse(args, "i", &scheme)) return NULL; ! new = PyObject_NEW(clobject, &Cltype); if (new == NULL) return NULL; --- 713,719 ---- if (!PyArg_Parse(args, "i", &scheme)) return NULL; ! new = PyObject_New(clobject, &Cltype); if (new == NULL) return NULL; diff -cr PyCVS/Modules/cursesmodule.c PyMem/Modules/cursesmodule.c *** PyCVS/Modules/cursesmodule.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/cursesmodule.c Sun Apr 30 04:25:13 2000 *************** *** 273,279 **** PyFileObject *in_fo; PyFileObject *out_fo; PyCursesScreenObject *xp; ! xp = PyObject_NEW(PyCursesScreenObject, &PyCursesScreen_Type); if (xp == NULL) return NULL; return (PyObject *)xp; --- 273,279 ---- PyFileObject *in_fo; PyFileObject *out_fo; PyCursesScreenObject *xp; ! xp = PyObject_New(PyCursesScreenObject, &PyCursesScreen_Type); if (xp == NULL) return NULL; return (PyObject *)xp; *************** *** 289,295 **** { PyCursesWindowObject *wo; ! wo = PyObject_NEW(PyCursesWindowObject, &PyCursesWindow_Type); if (wo == NULL) return NULL; wo->win = win; --- 289,295 ---- { PyCursesWindowObject *wo; ! wo = PyObject_New(PyCursesWindowObject, &PyCursesWindow_Type); if (wo == NULL) return NULL; wo->win = win; *************** *** 303,309 **** { if (wo->win != stdscr) delwin(wo->win); ! PyMem_DEL(wo); } static PyObject * --- 303,309 ---- { if (wo->win != stdscr) delwin(wo->win); ! PyObject_Del(wo); } static PyObject * *************** *** 1125,1131 **** WINDOW *pad; { PyCursesPadObject *po; ! po = PyObject_NEW(PyCursesPadObject, &PyCursesPad_Type); if (po == NULL) return NULL; po->pad = pad; --- 1125,1131 ---- WINDOW *pad; { PyCursesPadObject *po; ! po = PyObject_New(PyCursesPadObject, &PyCursesPad_Type); if (po == NULL) return NULL; po->pad = pad; diff -cr PyCVS/Modules/dbmmodule.c PyMem/Modules/dbmmodule.c *** PyCVS/Modules/dbmmodule.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/dbmmodule.c Sun Apr 30 04:25:55 2000 *************** *** 62,68 **** { dbmobject *dp; ! dp = PyObject_NEW(dbmobject, &Dbmtype); if (dp == NULL) return NULL; dp->di_size = -1; --- 62,68 ---- { dbmobject *dp; ! dp = PyObject_New(dbmobject, &Dbmtype); if (dp == NULL) return NULL; dp->di_size = -1; *************** *** 82,88 **** { if ( dp->di_dbm ) dbm_close(dp->di_dbm); ! PyMem_DEL(dp); } static int --- 82,88 ---- { if ( dp->di_dbm ) dbm_close(dp->di_dbm); ! PyObject_Del(dp); } static int diff -cr PyCVS/Modules/dlmodule.c PyMem/Modules/dlmodule.c *** PyCVS/Modules/dlmodule.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/dlmodule.c Sun Apr 30 04:27:30 2000 *************** *** 54,60 **** PyUnivPtr *handle; { dlobject *xp; ! xp = PyObject_NEW(dlobject, &Dltype); if (xp == NULL) return NULL; xp->dl_handle = handle; --- 54,60 ---- PyUnivPtr *handle; { dlobject *xp; ! xp = PyObject_New(dlobject, &Dltype); if (xp == NULL) return NULL; xp->dl_handle = handle; *************** *** 67,73 **** { if (xp->dl_handle != NULL) dlclose(xp->dl_handle); ! PyMem_DEL(xp); } static PyObject * --- 67,73 ---- { if (xp->dl_handle != NULL) dlclose(xp->dl_handle); ! PyObject_Del(xp); } static PyObject * diff -cr PyCVS/Modules/flmodule.c PyMem/Modules/flmodule.c *** PyCVS/Modules/flmodule.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/flmodule.c Sun Apr 30 04:30:00 2000 *************** *** 332,338 **** fl_free_object(g->ob_generic); Py_XDECREF(g->ob_callback); Py_XDECREF(g->ob_callback_arg); ! PyMem_DEL(g); } #define OFF(x) offsetof(FL_OBJECT, x) --- 332,338 ---- fl_free_object(g->ob_generic); Py_XDECREF(g->ob_callback); Py_XDECREF(g->ob_callback_arg); ! PyObject_Del(g); } #define OFF(x) offsetof(FL_OBJECT, x) *************** *** 461,467 **** PyMethodDef *methods; { genericobject *g; ! g = PyObject_NEW(genericobject, &GenericObjecttype); if (g == NULL) return NULL; g-> ob_generic = generic; --- 461,467 ---- PyMethodDef *methods; { genericobject *g; ! g = PyObject_New(genericobject, &GenericObjecttype); if (g == NULL) return NULL; g-> ob_generic = generic; *************** *** 1852,1858 **** if (f->ob_form->visible) fl_hide_form(f->ob_form); fl_free_form(f->ob_form); ! PyMem_DEL(f); } #define OFF(x) offsetof(FL_FORM, x) --- 1852,1858 ---- if (f->ob_form->visible) fl_hide_form(f->ob_form); fl_free_form(f->ob_form); ! PyObject_Del(f); } #define OFF(x) offsetof(FL_FORM, x) *************** *** 1931,1937 **** FL_FORM *form; { formobject *f; ! f = PyObject_NEW(formobject, &Formtype); if (f == NULL) return NULL; f->ob_form = form; --- 1931,1937 ---- FL_FORM *form; { formobject *f; ! f = PyObject_New(formobject, &Formtype); if (f == NULL) return NULL; f->ob_form = form; diff -cr PyCVS/Modules/fmmodule.c PyMem/Modules/fmmodule.c *** PyCVS/Modules/fmmodule.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/fmmodule.c Sun Apr 30 04:30:39 2000 *************** *** 59,65 **** "error creating new font handle"); return NULL; } ! fhp = PyObject_NEW(fhobject, &Fhtype); if (fhp == NULL) return NULL; fhp->fh_fh = fh; --- 59,65 ---- "error creating new font handle"); return NULL; } ! fhp = PyObject_New(fhobject, &Fhtype); if (fhp == NULL) return NULL; fhp->fh_fh = fh; *************** *** 196,202 **** fhobject *fhp; { fmfreefont(fhp->fh_fh); ! PyMem_DEL(fhp); } static PyTypeObject Fhtype = { --- 196,202 ---- fhobject *fhp; { fmfreefont(fhp->fh_fh); ! PyObject_Del(fhp); } static PyTypeObject Fhtype = { diff -cr PyCVS/Modules/gdbmmodule.c PyMem/Modules/gdbmmodule.c *** PyCVS/Modules/gdbmmodule.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/gdbmmodule.c Sun Apr 30 04:32:18 2000 *************** *** 93,99 **** { dbmobject *dp; ! dp = PyObject_NEW(dbmobject, &Dbmtype); if (dp == NULL) return NULL; dp->di_size = -1; --- 93,99 ---- { dbmobject *dp; ! dp = PyObject_New(dbmobject, &Dbmtype); if (dp == NULL) return NULL; dp->di_size = -1; *************** *** 117,123 **** { if ( dp->di_dbm ) gdbm_close(dp->di_dbm); ! PyMem_DEL(dp); } static int --- 117,123 ---- { if ( dp->di_dbm ) gdbm_close(dp->di_dbm); ! PyObject_Del(dp); } static int diff -cr PyCVS/Modules/getpath.c PyMem/Modules/getpath.c *** PyCVS/Modules/getpath.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/getpath.c Sun Apr 30 04:35:02 2000 *************** *** 529,535 **** bufsz += strlen(exec_prefix) + 1; /* This is the only malloc call in this file */ ! buf = malloc(bufsz); if (buf == NULL) { /* We can't exit, so print a warning and limp along */ --- 529,535 ---- bufsz += strlen(exec_prefix) + 1; /* This is the only malloc call in this file */ ! buf = PyMem_Malloc(bufsz); if (buf == NULL) { /* We can't exit, so print a warning and limp along */ diff -cr PyCVS/Modules/linuxaudiodev.c PyMem/Modules/linuxaudiodev.c *** PyCVS/Modules/linuxaudiodev.c Sat Apr 29 00:24:07 2000 --- PyMem/Modules/linuxaudiodev.c Sun Apr 30 04:38:45 2000 *************** *** 104,110 **** } /* Create and initialize the object */ ! if ((xp = PyObject_NEW(lad_t, &Ladtype)) == NULL) { close(fd); return NULL; } --- 104,110 ---- } /* Create and initialize the object */ ! if ((xp = PyObject_New(lad_t, &Ladtype)) == NULL) { close(fd); return NULL; } *************** *** 118,124 **** lad_dealloc(lad_t *xp) { close(xp->x_fd); ! PyMem_DEL(xp); } static PyObject * --- 118,124 ---- lad_dealloc(lad_t *xp) { close(xp->x_fd); ! PyObject_Del(xp); } static PyObject * diff -cr PyCVS/Modules/main.c PyMem/Modules/main.c *** PyCVS/Modules/main.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/main.c Sun Apr 30 04:40:41 2000 *************** *** 124,130 **** /* -c is the last option; following arguments that look like options are left for the the command to interpret. */ ! command = malloc(strlen(optarg) + 2); if (command == NULL) Py_FatalError( "not enough memory to copy -c argument"); --- 124,130 ---- /* -c is the last option; following arguments that look like options are left for the the command to interpret. */ ! command = PyMem_Malloc(strlen(optarg) + 2); if (command == NULL) Py_FatalError( "not enough memory to copy -c argument"); *************** *** 277,283 **** if (command) { sts = PyRun_SimpleString(command) != 0; ! free(command); } else { if (filename == NULL && stdin_is_interactive) { --- 277,283 ---- if (command) { sts = PyRun_SimpleString(command) != 0; ! PyMem_Free(command); } else { if (filename == NULL && stdin_is_interactive) { diff -cr PyCVS/Modules/md5module.c PyMem/Modules/md5module.c *** PyCVS/Modules/md5module.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/md5module.c Sun Apr 30 04:42:06 2000 *************** *** 56,62 **** { md5object *md5p; ! md5p = PyObject_NEW(md5object, &MD5type); if (md5p == NULL) return NULL; --- 56,62 ---- { md5object *md5p; ! md5p = PyObject_New(md5object, &MD5type); if (md5p == NULL) return NULL; *************** *** 71,77 **** md5_dealloc(md5p) md5object *md5p; { ! PyMem_DEL(md5p); } --- 71,77 ---- md5_dealloc(md5p) md5object *md5p; { ! PyObject_Del(md5p); } diff -cr PyCVS/Modules/mmapmodule.c PyMem/Modules/mmapmodule.c *** PyCVS/Modules/mmapmodule.c Sat Apr 29 00:24:07 2000 --- PyMem/Modules/mmapmodule.c Sun Apr 30 04:48:32 2000 *************** *** 69,75 **** } #endif /* UNIX */ ! PyMem_DEL(m_obj); } static PyObject * --- 69,75 ---- } #endif /* UNIX */ ! PyObject_Del(m_obj); } static PyObject * *************** *** 706,712 **** ) return NULL; ! m_obj = PyObject_NEW (mmap_object, &mmap_object_type); if (m_obj == NULL) {return NULL;} m_obj->size = (size_t) map_size; m_obj->pos = (size_t) 0; --- 706,712 ---- ) return NULL; ! m_obj = PyObject_New (mmap_object, &mmap_object_type); if (m_obj == NULL) {return NULL;} m_obj->size = (size_t) map_size; m_obj->pos = (size_t) 0; *************** *** 757,763 **** fseek(&_iob[fileno], 0, SEEK_SET); } ! m_obj = PyObject_NEW (mmap_object, &mmap_object_type); if (fh) { m_obj->file_handle = fh; --- 757,763 ---- fseek(&_iob[fileno], 0, SEEK_SET); } ! m_obj = PyObject_New (mmap_object, &mmap_object_type); if (fh) { m_obj->file_handle = fh; diff -cr PyCVS/Modules/mpzmodule.c PyMem/Modules/mpzmodule.c *** PyCVS/Modules/mpzmodule.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/mpzmodule.c Sun Apr 30 04:49:32 2000 *************** *** 123,129 **** #ifdef MPZ_DEBUG fputs( "mpz_object() called...\n", stderr ); #endif /* def MPZ_DEBUG */ ! mpzp = PyObject_NEW(mpzobject, &MPZtype); if (mpzp == NULL) return NULL; --- 123,129 ---- #ifdef MPZ_DEBUG fputs( "mpz_object() called...\n", stderr ); #endif /* def MPZ_DEBUG */ ! mpzp = PyObject_New(mpzobject, &MPZtype); if (mpzp == NULL) return NULL; *************** *** 285,291 **** fputs( "mpz_dealloc() called...\n", stderr ); #endif /* def MPZ_DEBUG */ mpz_clear(&mpzp->mpz); ! PyMem_DEL(mpzp); } /* mpz_dealloc() */ --- 285,291 ---- fputs( "mpz_dealloc() called...\n", stderr ); #endif /* def MPZ_DEBUG */ mpz_clear(&mpzp->mpz); ! PyObject_Del(mpzp); } /* mpz_dealloc() */ diff -cr PyCVS/Modules/newmodule.c PyMem/Modules/newmodule.c *** PyCVS/Modules/newmodule.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/newmodule.c Sun Apr 30 04:51:01 2000 *************** *** 49,55 **** &PyClass_Type, &klass, &PyDict_Type, &dict)) return NULL; ! inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type); if (inst == NULL) return NULL; Py_INCREF(klass); --- 49,55 ---- &PyClass_Type, &klass, &PyDict_Type, &dict)) return NULL; ! inst = PyObject_New(PyInstanceObject, &PyInstance_Type); if (inst == NULL) return NULL; Py_INCREF(klass); diff -cr PyCVS/Modules/nismodule.c PyMem/Modules/nismodule.c *** PyCVS/Modules/nismodule.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/nismodule.c Sun Apr 30 05:01:16 2000 *************** *** 353,363 **** if (list->stat != NIS_TRUE) goto finally; ! PyMem_DEL(server); return list->maps; finally: ! PyMem_DEL(server); return NULL; } --- 353,363 ---- if (list->stat != NIS_TRUE) goto finally; ! free(server); return list->maps; finally: ! free(server); return NULL; } diff -cr PyCVS/Modules/parsermodule.c PyMem/Modules/parsermodule.c *** PyCVS/Modules/parsermodule.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/parsermodule.c Sun Apr 30 05:38:03 2000 *************** *** 295,301 **** static PyObject* parser_newastobject(node *ast, int type) { ! PyAST_Object* o = PyObject_NEW(PyAST_Object, &PyAST_Type); if (o != 0) { o->ast_node = ast; --- 295,301 ---- static PyObject* parser_newastobject(node *ast, int type) { ! PyAST_Object* o = PyObject_New(PyAST_Object, &PyAST_Type); if (o != 0) { o->ast_node = ast; *************** *** 317,323 **** parser_free(PyAST_Object *ast) { PyNode_Free(ast->ast_node); ! PyMem_DEL(ast); } --- 317,323 ---- parser_free(PyAST_Object *ast) { PyNode_Free(ast->ast_node); ! PyObject_Del(ast); } *************** *** 790,799 **** PyObject *temp = PySequence_GetItem(elem, 1); /* check_terminal_tuple() already verified it's a string */ ! strn = (char *)malloc(PyString_GET_SIZE(temp) + 1); if (strn != NULL) (void) strcpy(strn, PyString_AS_STRING(temp)); ! Py_XDECREF(temp); if (PyObject_Length(elem) == 3) { PyObject* temp = PySequence_GetItem(elem, 2); --- 790,799 ---- PyObject *temp = PySequence_GetItem(elem, 1); /* check_terminal_tuple() already verified it's a string */ ! strn = (char *)PyMem_MALLOC(PyString_GET_SIZE(temp) + 1); if (strn != NULL) (void) strcpy(strn, PyString_AS_STRING(temp)); ! Py_DECREF(temp); if (PyObject_Length(elem) == 3) { PyObject* temp = PySequence_GetItem(elem, 2); diff -cr PyCVS/Modules/pcremodule.c PyMem/Modules/pcremodule.c *** PyCVS/Modules/pcremodule.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/pcremodule.c Sun Apr 30 05:39:56 2000 *************** *** 79,85 **** PyObject *arg; { PcreObject *self; ! self = PyObject_NEW(PcreObject, &Pcre_Type); if (self == NULL) return NULL; self->regex = NULL; --- 79,85 ---- PyObject *arg; { PcreObject *self; ! self = PyObject_New(PcreObject, &Pcre_Type); if (self == NULL) return NULL; self->regex = NULL; *************** *** 95,101 **** { if (self->regex) (pcre_free)(self->regex); if (self->regex_extra) (pcre_free)(self->regex_extra); ! PyMem_DEL(self); } --- 95,101 ---- { if (self->regex) (pcre_free)(self->regex); if (self->regex_extra) (pcre_free)(self->regex_extra); ! PyObject_Del(self); } diff -cr PyCVS/Modules/pyexpat.c PyMem/Modules/pyexpat.c *** PyCVS/Modules/pyexpat.c Sat Apr 29 00:24:07 2000 --- PyMem/Modules/pyexpat.c Sun Apr 30 05:44:08 2000 *************** *** 471,477 **** int i; xmlparseobject *self; ! self = PyObject_NEW(xmlparseobject, &Xmlparsetype); if (self == NULL) return NULL; --- 471,477 ---- int i; xmlparseobject *self; ! self = PyObject_New(xmlparseobject, &Xmlparsetype); if (self == NULL) return NULL; *************** *** 512,518 **** for( i=0; handler_info[i].name!=NULL; i++ ){ Py_XDECREF( self->handlers[i] ); } ! PyMem_DEL(self); } static int handlername2int( const char *name ){ --- 512,518 ---- for( i=0; handler_info[i].name!=NULL; i++ ){ Py_XDECREF( self->handlers[i] ); } ! PyObject_Del(self); } static int handlername2int( const char *name ){ diff -cr PyCVS/Modules/readline.c PyMem/Modules/readline.c *** PyCVS/Modules/readline.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/readline.c Sun Apr 30 05:53:32 2000 *************** *** 377,383 **** char *prompt; { int n; ! char *p; RETSIGTYPE (*old_inthandler)(); old_inthandler = signal(SIGINT, onintr); if (setjmp(jbuf)) { --- 377,383 ---- char *prompt; { int n; ! char *p, *q; RETSIGTYPE (*old_inthandler)(); old_inthandler = signal(SIGINT, onintr); if (setjmp(jbuf)) { *************** *** 391,398 **** rl_event_hook = PyOS_InputHook; p = readline(prompt); signal(SIGINT, old_inthandler); if (p == NULL) { ! p = malloc(1); if (p != NULL) *p = '\0'; return p; --- 391,400 ---- rl_event_hook = PyOS_InputHook; p = readline(prompt); signal(SIGINT, old_inthandler); + + /* We must return a buffer allocated with PyMem_Malloc. */ if (p == NULL) { ! p = PyMem_Malloc(1); if (p != NULL) *p = '\0'; return p; *************** *** 400,409 **** n = strlen(p); if (n > 0) add_history(p); ! if ((p = realloc(p, n+2)) != NULL) { p[n] = '\n'; p[n+1] = '\0'; } return p; } --- 402,417 ---- n = strlen(p); if (n > 0) add_history(p); ! /* Copy the malloc'ed buffer into a PyMem_Malloc'ed one and ! release the original. */ ! q = p; ! p = PyMem_Malloc(n+2); ! if (p != NULL) { ! strncpy(p, q, n); p[n] = '\n'; p[n+1] = '\0'; } + free(q); return p; } diff -cr PyCVS/Modules/regexmodule.c PyMem/Modules/regexmodule.c *** PyCVS/Modules/regexmodule.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/regexmodule.c Sun Apr 30 06:35:56 2000 *************** *** 64,76 **** reg_dealloc(re) regexobject *re; { ! PyMem_XDEL(re->re_patbuf.buffer); Py_XDECREF(re->re_translate); Py_XDECREF(re->re_lastok); Py_XDECREF(re->re_groupindex); Py_XDECREF(re->re_givenpat); Py_XDECREF(re->re_realpat); ! PyMem_DEL(re); } static PyObject * --- 64,77 ---- reg_dealloc(re) regexobject *re; { ! if (re->re_patbuf.buffer) ! PyMem_DEL(re->re_patbuf.buffer); Py_XDECREF(re->re_translate); Py_XDECREF(re->re_lastok); Py_XDECREF(re->re_groupindex); Py_XDECREF(re->re_givenpat); Py_XDECREF(re->re_realpat); ! PyObject_Del(re); } static PyObject * *************** *** 418,424 **** "translation table must be 256 bytes"); return NULL; } ! re = PyObject_NEW(regexobject, &Regextype); if (re != NULL) { char *error; re->re_patbuf.buffer = NULL; --- 419,425 ---- "translation table must be 256 bytes"); return NULL; } ! re = PyObject_New(regexobject, &Regextype); if (re != NULL) { char *error; re->re_patbuf.buffer = NULL; diff -cr PyCVS/Modules/rotormodule.c PyMem/Modules/rotormodule.c *** PyCVS/Modules/rotormodule.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/rotormodule.c Sun Apr 30 06:44:01 2000 *************** *** 178,184 **** { Rotorobj *xp; ! xp = PyObject_NEW(Rotorobj, &Rotor_Type); if (xp == NULL) return NULL; set_key(xp, key); --- 178,184 ---- { Rotorobj *xp; ! xp = PyObject_New(Rotorobj, &Rotor_Type); if (xp == NULL) return NULL; set_key(xp, key); *************** *** 204,213 **** return xp; finally: ! PyMem_XDEL(xp->e_rotor); ! PyMem_XDEL(xp->d_rotor); ! PyMem_XDEL(xp->positions); ! PyMem_XDEL(xp->advances); Py_DECREF(xp); return (Rotorobj*)PyErr_NoMemory(); } --- 204,217 ---- return xp; finally: ! if (xp->e_rotor) ! PyMem_DEL(xp->e_rotor); ! if (xp->d_rotor) ! PyMem_DEL(xp->d_rotor); ! if (xp->positions) ! PyMem_DEL(xp->positions); ! if (xp->advances) ! PyMem_DEL(xp->advances); Py_DECREF(xp); return (Rotorobj*)PyErr_NoMemory(); } *************** *** 473,483 **** rotor_dealloc(xp) Rotorobj *xp; { ! PyMem_XDEL(xp->e_rotor); ! PyMem_XDEL(xp->d_rotor); ! PyMem_XDEL(xp->positions); ! PyMem_XDEL(xp->advances); ! PyMem_DEL(xp); } static PyObject * --- 477,491 ---- rotor_dealloc(xp) Rotorobj *xp; { ! if (xp->e_rotor) ! PyMem_DEL(xp->e_rotor); ! if (xp->d_rotor) ! PyMem_DEL(xp->d_rotor); ! if (xp->positions) ! PyMem_DEL(xp->positions); ! if (xp->advances) ! PyMem_DEL(xp->advances); ! PyObject_Del(xp); } static PyObject * diff -cr PyCVS/Modules/selectmodule.c PyMem/Modules/selectmodule.c *** PyCVS/Modules/selectmodule.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/selectmodule.c Sun Apr 30 06:42:55 2000 *************** *** 278,286 **** wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 3); efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 3); if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) { ! PyMem_XDEL(rfd2obj); ! PyMem_XDEL(wfd2obj); ! PyMem_XDEL(efd2obj); return NULL; } #endif --- 278,286 ---- wfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 3); efd2obj = PyMem_NEW(pylist, FD_SETSIZE + 3); if (rfd2obj == NULL || wfd2obj == NULL || efd2obj == NULL) { ! if (rfd2obj) PyMem_DEL(rfd2obj); ! if (wfd2obj) PyMem_DEL(wfd2obj); ! if (efd2obj) PyMem_DEL(efd2obj); return NULL; } #endif diff -cr PyCVS/Modules/shamodule.c PyMem/Modules/shamodule.c *** PyCVS/Modules/shamodule.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/shamodule.c Sun Apr 30 06:06:17 2000 *************** *** 380,386 **** static SHAobject * newSHAobject() { ! return (SHAobject *)PyObject_NEW(SHAobject, &SHAtype); } /* Internal methods for a hashing object */ --- 380,386 ---- static SHAobject * newSHAobject() { ! return (SHAobject *)PyObject_New(SHAobject, &SHAtype); } /* Internal methods for a hashing object */ *************** *** 389,395 **** SHA_dealloc(ptr) PyObject *ptr; { ! PyMem_DEL(ptr); } --- 389,395 ---- SHA_dealloc(ptr) PyObject *ptr; { ! PyObject_Del(ptr); } diff -cr PyCVS/Modules/socketmodule.c PyMem/Modules/socketmodule.c *** PyCVS/Modules/socketmodule.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/socketmodule.c Sun Apr 30 06:13:35 2000 *************** *** 389,395 **** { PySocketSockObject *s; PySocketSock_Type.ob_type = &PyType_Type; ! s = PyObject_NEW(PySocketSockObject, &PySocketSock_Type); if (s != NULL) { s->sock_fd = fd; s->sock_family = family; --- 389,395 ---- { PySocketSockObject *s; PySocketSock_Type.ob_type = &PyType_Type; ! s = PyObject_New(PySocketSockObject, &PySocketSock_Type); if (s != NULL) { s->sock_fd = fd; s->sock_family = family; *************** *** 1368,1374 **** { if (s->sock_fd != -1) (void) SOCKETCLOSE(s->sock_fd); ! PyMem_DEL(s); } --- 1368,1374 ---- { if (s->sock_fd != -1) (void) SOCKETCLOSE(s->sock_fd); ! PyObject_Del(s); } *************** *** 1948,1954 **** meth=SSLv2_client_method(); #endif ! self = PyObject_NEW(SSLObject, &SSL_Type); /* Create new object */ if (self == NULL){ PyErr_SetObject(SSLErrorObject, PyString_FromString("newSSLObject error")); --- 1948,1954 ---- meth=SSLv2_client_method(); #endif ! self = PyObject_New(SSLObject, &SSL_Type); /* Create new object */ if (self == NULL){ PyErr_SetObject(SSLErrorObject, PyString_FromString("newSSLObject error")); *************** *** 1962,1968 **** if (self->ctx == NULL) { PyErr_SetObject(SSLErrorObject, PyString_FromString("SSL_CTX_new error")); ! PyMem_DEL(self); return NULL; } --- 1962,1968 ---- if (self->ctx == NULL) { PyErr_SetObject(SSLErrorObject, PyString_FromString("SSL_CTX_new error")); ! PyObject_Del(self); return NULL; } *************** *** 1971,1977 **** PyErr_SetObject(SSLErrorObject, PyString_FromString( "Both the key & certificate files must be specified")); ! PyMem_DEL(self); return NULL; } --- 1971,1977 ---- PyErr_SetObject(SSLErrorObject, PyString_FromString( "Both the key & certificate files must be specified")); ! PyObject_Del(self); return NULL; } *************** *** 1983,1989 **** PyErr_SetObject(SSLErrorObject, PyString_FromString( "SSL_CTX_use_PrivateKey_file error")); ! PyMem_DEL(self); return NULL; } --- 1983,1989 ---- PyErr_SetObject(SSLErrorObject, PyString_FromString( "SSL_CTX_use_PrivateKey_file error")); ! PyObject_Del(self); return NULL; } *************** *** 1993,1999 **** PyErr_SetObject(SSLErrorObject, PyString_FromString( "SSL_CTX_use_certificate_chain_file error")); ! PyMem_DEL(self); return NULL; } } --- 1993,1999 ---- PyErr_SetObject(SSLErrorObject, PyString_FromString( "SSL_CTX_use_certificate_chain_file error")); ! PyObject_Del(self); return NULL; } } *************** *** 2008,2014 **** /* Actually negotiate SSL connection */ PyErr_SetObject(SSLErrorObject, PyString_FromString("SSL_connect error")); ! PyMem_DEL(self); return NULL; } self->ssl->debug = 1; --- 2008,2014 ---- /* Actually negotiate SSL connection */ PyErr_SetObject(SSLErrorObject, PyString_FromString("SSL_connect error")); ! PyObject_Del(self); return NULL; } self->ssl->debug = 1; *************** *** 2079,2085 **** SSL_free(self->ssl); Py_XDECREF(self->x_attr); Py_XDECREF(self->Socket); ! PyMem_DEL(self); } static PyObject *SSL_getattr(SSLObject *self, char *name) --- 2079,2085 ---- SSL_free(self->ssl); Py_XDECREF(self->x_attr); Py_XDECREF(self->Socket); ! PyObject_Del(self); } static PyObject *SSL_getattr(SSLObject *self, char *name) diff -cr PyCVS/Modules/stdwinmodule.c PyMem/Modules/stdwinmodule.c *** PyCVS/Modules/stdwinmodule.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/stdwinmodule.c Sun Apr 30 06:17:59 2000 *************** *** 271,277 **** Py_DECREF(dp->d_ref); dp->d_ref = NULL; } ! free((char *)dp); } static PyObject * --- 271,277 ---- Py_DECREF(dp->d_ref); dp->d_ref = NULL; } ! PyObject_Del(dp); } static PyObject * *************** *** 829,835 **** int left, top, right, bottom; { textobject *tp; ! tp = PyObject_NEW(textobject, &Texttype); if (tp == NULL) return NULL; tp->t_attr = NULL; --- 829,835 ---- int left, top, right, bottom; { textobject *tp; ! tp = PyObject_New(textobject, &Texttype); if (tp == NULL) return NULL; tp->t_attr = NULL; *************** *** 853,859 **** tefree(tp->t_text); Py_XDECREF(tp->t_attr); Py_XDECREF(tp->t_ref); ! PyMem_DEL(tp); } static PyObject * --- 853,859 ---- tefree(tp->t_text); Py_XDECREF(tp->t_attr); Py_XDECREF(tp->t_ref); ! PyObject_Del(tp); } static PyObject * *************** *** 1190,1196 **** menu = wmenucreate(id + IDOFFSET, title); if (menu == NULL) return (menuobject *) PyErr_NoMemory(); ! mp = PyObject_NEW(menuobject, &Menutype); if (mp != NULL) { mp->m_menu = menu; mp->m_id = id + IDOFFSET; --- 1190,1196 ---- menu = wmenucreate(id + IDOFFSET, title); if (menu == NULL) return (menuobject *) PyErr_NoMemory(); ! mp = PyObject_New(menuobject, &Menutype); if (mp != NULL) { mp->m_menu = menu; mp->m_id = id + IDOFFSET; *************** *** 1216,1222 **** if (mp->m_menu != NULL) wmenudelete(mp->m_menu); Py_XDECREF(mp->m_attr); ! PyMem_DEL(mp); } static PyObject * --- 1216,1222 ---- if (mp->m_menu != NULL) wmenudelete(mp->m_menu); Py_XDECREF(mp->m_attr); ! PyObject_Del(mp); } static PyObject * *************** *** 1386,1392 **** bitmap = wnewbitmap(width, height); if (bitmap == NULL) return (bitmapobject *) PyErr_NoMemory(); ! bp = PyObject_NEW(bitmapobject, &Bitmaptype); if (bp != NULL) { bp->b_bitmap = bitmap; bp->b_attr = NULL; --- 1386,1392 ---- bitmap = wnewbitmap(width, height); if (bitmap == NULL) return (bitmapobject *) PyErr_NoMemory(); ! bp = PyObject_New(bitmapobject, &Bitmaptype); if (bp != NULL) { bp->b_bitmap = bitmap; bp->b_attr = NULL; *************** *** 1405,1411 **** if (bp->b_bitmap != NULL) wfreebitmap(bp->b_bitmap); Py_XDECREF(bp->b_attr); ! PyMem_DEL(bp); } static PyObject * --- 1405,1411 ---- if (bp->b_bitmap != NULL) wfreebitmap(bp->b_bitmap); Py_XDECREF(bp->b_attr); ! PyObject_Del(bp); } static PyObject * *************** *** 1554,1560 **** Py_DECREF(wp->w_title); if (wp->w_attr != NULL) Py_DECREF(wp->w_attr); ! free((char *)wp); } static PyObject * --- 1554,1560 ---- Py_DECREF(wp->w_title); if (wp->w_attr != NULL) Py_DECREF(wp->w_attr); ! PyObject_Del(wp); } static PyObject * *************** *** 1585,1591 **** PyErr_SetString(StdwinError, "already drawing"); return NULL; } ! dp = PyObject_NEW(drawingobject, &Drawingtype); if (dp == NULL) return NULL; Drawing = dp; --- 1585,1591 ---- PyErr_SetString(StdwinError, "already drawing"); return NULL; } ! dp = PyObject_New(drawingobject, &Drawingtype); if (dp == NULL) return NULL; Drawing = dp; *************** *** 1986,1992 **** PyErr_SetString(StdwinError, "creating too many windows"); return NULL; } ! wp = PyObject_NEW(windowobject, &Windowtype); if (wp == NULL) return NULL; Py_INCREF(title); --- 1986,1992 ---- PyErr_SetString(StdwinError, "creating too many windows"); return NULL; } ! wp = PyObject_New(windowobject, &Windowtype); if (wp == NULL) return NULL; Py_INCREF(title); diff -cr PyCVS/Modules/stropmodule.c PyMem/Modules/stropmodule.c *** PyCVS/Modules/stropmodule.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/stropmodule.c Sun Apr 30 06:20:53 2000 *************** *** 1152,1158 **** goto return_same; new_len = len + nfound*(sub_len - pat_len); ! new_s = (char *)malloc(new_len); if (new_s == NULL) return NULL; *out_len = new_len; --- 1152,1158 ---- goto return_same; new_len = len + nfound*(sub_len - pat_len); ! new_s = (char *)PyMem_MALLOC(new_len); if (new_s == NULL) return NULL; *out_len = new_len; *************** *** 1225,1231 **** } else { new = PyString_FromStringAndSize(new_s, out_len); ! free(new_s); } return new; } --- 1225,1231 ---- } else { new = PyString_FromStringAndSize(new_s, out_len); ! PyMem_FREE(new_s); } return new; } diff -cr PyCVS/Modules/sunaudiodev.c PyMem/Modules/sunaudiodev.c *** PyCVS/Modules/sunaudiodev.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/sunaudiodev.c Sun Apr 30 06:23:26 2000 *************** *** 139,145 **** PyMem_DEL(ctldev); /* Create and initialize the object */ ! xp = PyObject_NEW(sadobject, &Sadtype); if (xp == NULL) { close(fd); return NULL; --- 139,145 ---- PyMem_DEL(ctldev); /* Create and initialize the object */ ! xp = PyObject_New(sadobject, &Sadtype); if (xp == NULL) { close(fd); return NULL; *************** *** 158,164 **** sadobject *xp; { close(xp->x_fd); ! PyMem_DEL(xp); } static PyObject * --- 158,164 ---- sadobject *xp; { close(xp->x_fd); ! PyObject_Del(xp); } static PyObject * *************** *** 412,418 **** static sadstatusobject * sads_alloc() { ! return PyObject_NEW(sadstatusobject, &Sadstatustype); } static void --- 412,418 ---- static sadstatusobject * sads_alloc() { ! return PyObject_New(sadstatusobject, &Sadstatustype); } static void diff -cr PyCVS/Modules/svmodule.c PyMem/Modules/svmodule.c *** PyCVS/Modules/svmodule.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/svmodule.c Sun Apr 30 06:25:02 2000 *************** *** 340,346 **** Py_DECREF(self->ob_svideo); self->ob_svideo = NULL; } ! PyMem_DEL(self); } static PyObject * --- 340,346 ---- Py_DECREF(self->ob_svideo); self->ob_svideo = NULL; } ! PyObject_Del(self); } static PyObject * *************** *** 374,380 **** { captureobject *p; ! p = PyObject_NEW(captureobject, &Capturetype); if (p == NULL) return NULL; p->ob_svideo = self; --- 374,380 ---- { captureobject *p; ! p = PyObject_New(captureobject, &Capturetype); if (p == NULL) return NULL; p->ob_svideo = self; *************** *** 994,1000 **** { if (self->ob_svideo != NULL) (void) svCloseVideo(self->ob_svideo); ! PyMem_DEL(self); } static PyObject * --- 994,1000 ---- { if (self->ob_svideo != NULL) (void) svCloseVideo(self->ob_svideo); ! PyObject_Del(self); } static PyObject * *************** *** 1026,1032 **** { svobject *p; ! p = PyObject_NEW(svobject, &Svtype); if (p == NULL) return NULL; p->ob_svideo = svp; --- 1026,1032 ---- { svobject *p; ! p = PyObject_New(svobject, &Svtype); if (p == NULL) return NULL; p->ob_svideo = svp; diff -cr PyCVS/Modules/threadmodule.c PyMem/Modules/threadmodule.c *** PyCVS/Modules/threadmodule.c Sat Apr 29 00:24:06 2000 --- PyMem/Modules/threadmodule.c Sun Apr 30 06:27:33 2000 *************** *** 58,69 **** newlockobject() { lockobject *self; ! self = PyObject_NEW(lockobject, &Locktype); if (self == NULL) return NULL; self->lock_lock = PyThread_allocate_lock(); if (self->lock_lock == NULL) { ! PyMem_DEL(self); self = NULL; PyErr_SetString(ThreadError, "can't allocate lock"); } --- 58,69 ---- newlockobject() { lockobject *self; ! self = PyObject_New(lockobject, &Locktype); if (self == NULL) return NULL; self->lock_lock = PyThread_allocate_lock(); if (self->lock_lock == NULL) { ! PyObject_Del(self); self = NULL; PyErr_SetString(ThreadError, "can't allocate lock"); } *************** *** 79,85 **** PyThread_release_lock(self->lock_lock); PyThread_free_lock(self->lock_lock); ! PyMem_DEL(self); } static PyObject * --- 79,85 ---- PyThread_release_lock(self->lock_lock); PyThread_free_lock(self->lock_lock); ! PyObject_Del(self); } static PyObject * diff -cr PyCVS/Modules/xxmodule.c PyMem/Modules/xxmodule.c *** PyCVS/Modules/xxmodule.c Sat Apr 29 00:24:07 2000 --- PyMem/Modules/xxmodule.c Sun Apr 30 06:32:10 2000 *************** *** 62,68 **** PyObject *arg; { XxoObject *self; ! self = PyObject_NEW(XxoObject, &Xxo_Type); if (self == NULL) return NULL; self->x_attr = NULL; --- 62,68 ---- PyObject *arg; { XxoObject *self; ! self = PyObject_New(XxoObject, &Xxo_Type); if (self == NULL) return NULL; self->x_attr = NULL; *************** *** 76,82 **** XxoObject *self; { Py_XDECREF(self->x_attr); ! PyMem_DEL(self); } static PyObject * --- 76,82 ---- XxoObject *self; { Py_XDECREF(self->x_attr); ! PyObject_Del(self); } static PyObject * diff -cr PyCVS/Modules/zlibmodule.c PyMem/Modules/zlibmodule.c *** PyCVS/Modules/zlibmodule.c Sat Apr 29 00:24:07 2000 --- PyMem/Modules/zlibmodule.c Sun Apr 30 06:34:28 2000 *************** *** 46,52 **** PyTypeObject *type; { compobject *self; ! self = PyObject_NEW(compobject, type); if (self == NULL) return NULL; self->is_initialised = 0; --- 46,52 ---- PyTypeObject *type; { compobject *self; ! self = PyObject_New(compobject, type); if (self == NULL) return NULL; self->is_initialised = 0; *************** *** 369,375 **** if (self->is_initialised) deflateEnd(&self->zst); Py_XDECREF(self->unused_data); ! PyMem_DEL(self); } static void --- 369,375 ---- if (self->is_initialised) deflateEnd(&self->zst); Py_XDECREF(self->unused_data); ! PyObject_Del(self); } static void *************** *** 378,384 **** { inflateEnd(&self->zst); Py_XDECREF(self->unused_data); ! PyMem_DEL(self); } static char comp_compress__doc__[] = --- 378,384 ---- { inflateEnd(&self->zst); Py_XDECREF(self->unused_data); ! PyObject_Del(self); } static char comp_compress__doc__[] = From Vladimir.Marangozov@inrialpes.fr Sun Apr 30 20:46:52 2000 From: Vladimir.Marangozov@inrialpes.fr (Vladimir Marangozov) Date: Sun, 30 Apr 2000 21:46:52 +0200 (CEST) Subject: [Patches] PyMem [8/8] - Final words + TODO Message-ID: <200004301946.VAA15158@python.inrialpes.fr> Final words ----------- Py_Malloc/Realloc/Free + PyMem_XDEL are gone. Support for Py_Malloc/Realloc/Free is dropped. They were hardly ever used. For source code compatibility, they are defined as PyMem_Malloc/Realloc/Free PyMem_XDEL is defined as PyMem_DEL. ANSI C free(NULL) has no effect, so this should be safe. The new interfaces are in place. The distribution compiles flawlessly on my Linux RH 6.2 and AIX 4.1, and passes OK the test suite. I've been able to change easily the Python mallocs and have tested all existing malloc permutations: +-----------+-----------+ | malloc1 | malloc2 | malloc1/malloc2 are +------------------------+-----------+-----------+ two different malloc | PyCore_MALLOC | X | | impementations that | PyCore_OBJECT_MALLOC | X | | may operate on the same +------------------------+-----------+-----------| or on different heaps. | PyCore_MALLOC | | X | | PyCore_OBJECT_MALLOC | | X | Each one of them can +------------------------+-----------+-----------| be std C malloc. Both | PyCore_MALLOC | X | | are, by default. | PyCore_OBJECT_MALLOC | | X | +------------------------+-----------+-----------| | PyCore_MALLOC | | X | | PyCore_OBJECT_MALLOC | X | | +------------------------+-----------+-----------+ TODO topics ----------- 1) Integration of custom malloc libs in the build process. For instance, when the core malloc is changed, the link of pgen (in Parser) fails because of dependencies. The link of pgen would probably need to be deferred for the "link phase" of the distrib, after the compile in all subdirectories. Also, there has to be an automatic way of adding custom malloc libraries to the link phase (for now, this has to be done manually). I can't be bothered with this right now, though... 2) Invisible bugs 3) Malloc cleanup omissions or bugs in the distrib (nah, shouldn't be) 4) Write what's missing in the Extending/Embedding docs. -- Vladimir MARANGOZOV | Vladimir.Marangozov@inrialpes.fr http://sirac.inrialpes.fr/~marangoz | tel:(+33-4)76615277 fax:76615252