[Python-checkins] CVS: python/dist/src/Python errors.c,2.41,2.42

Guido van Rossum guido@cnri.reston.va.us
Thu, 17 Feb 2000 10:19:18 -0500 (EST)


Update of /projects/cvsroot/python/dist/src/Python
In directory eric:/projects/python/develop/guido/src/Python

Modified Files:
	errors.c 
Log Message:
Patch by Mark Hammond:

* Changes to a recent patch by Chris Tismer to errors.c.  Chris' patch
always used FormatMessage() to get the error message passing the error code
from errno - but errno and FormatMessage use a different numbering scheme.
The main reason the patch looked OK was that ENOFILE==ERROR_FILE_NOT_FOUND -
but that is about the only shared error code :-).  The MS CRT docs tell you
to use _sys_errlist()/_sys_nerr.  My patch does also this, and adds a very
similar function specifically for win32 error codes.


Index: errors.c
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Python/errors.c,v
retrieving revision 2.41
retrieving revision 2.42
diff -C2 -r2.41 -r2.42
*** errors.c	1999/04/21 15:27:31	2.41
--- errors.c	2000/02/17 15:19:15	2.42
***************
*** 290,293 ****
--- 290,296 ----
  	char *s;
  	int i = errno;
+ #ifdef MS_WIN32
+ 	char *s_buf = NULL;
+ #endif
  #ifdef EINTR
  	if (i == EINTR && PyErr_CheckSignals())
***************
*** 301,318 ****
  #else
  	{
! 		int len = FormatMessage(
! 			FORMAT_MESSAGE_ALLOCATE_BUFFER |
! 			FORMAT_MESSAGE_FROM_SYSTEM |
! 			FORMAT_MESSAGE_IGNORE_INSERTS,
! 			NULL,	/* no message source */
! 			i,
! 			MAKELANGID(LANG_NEUTRAL,
! 				   SUBLANG_DEFAULT), /* Default language */
! 			(LPTSTR) &s,
! 			0,	/* size not used */
! 			NULL);	/* no args */
! 		/* remove trailing cr/lf and dots */
! 		while (len > 0 && s[len-1] <= '.')
! 			s[--len] = '\0';
  	}
  #endif
--- 304,333 ----
  #else
  	{
! 		/* Note that the Win32 errors do not lineup with the
! 		   errno error.  So if the error is in the MSVC error
! 		   table, we use it, otherwise we assume it really _is_ 
! 		   a Win32 error code
! 		*/
! 		if (i < _sys_nerr) {
! 			s = _sys_errlist[i];
! 		}
! 		else {
! 			int len = FormatMessage(
! 				FORMAT_MESSAGE_ALLOCATE_BUFFER |
! 				FORMAT_MESSAGE_FROM_SYSTEM |
! 				FORMAT_MESSAGE_IGNORE_INSERTS,
! 				NULL,	/* no message source */
! 				i,
! 				MAKELANGID(LANG_NEUTRAL,
! 					   SUBLANG_DEFAULT),
! 				           /* Default language */
! 				(LPTSTR) &s_buf,
! 				0,	/* size not used */
! 				NULL);	/* no args */
! 			s = s_buf;
! 			/* remove trailing cr/lf and dots */
! 			while (len > 0 && (s[len-1] <= ' ' || s[len-1] == '.'))
! 				s[--len] = '\0';
! 		}
  	}
  #endif
***************
*** 326,330 ****
  	}
  #ifdef MS_WIN32
! 	LocalFree(s);
  #endif
  	return NULL;
--- 341,345 ----
  	}
  #ifdef MS_WIN32
! 	LocalFree(s_buf);
  #endif
  	return NULL;
***************
*** 338,341 ****
--- 353,401 ----
  	return PyErr_SetFromErrnoWithFilename(exc, NULL);
  }
+ 
+ #ifdef MS_WINDOWS 
+ /* Windows specific error code handling */
+ PyObject *PyErr_SetFromWindowsErrWithFilename(
+ 	int ierr, 
+ 	const char *filename)
+ {
+ 	int len;
+ 	char *s;
+ 	PyObject *v;
+ 	DWORD err = (DWORD)ierr;
+ 	if (err==0) err = GetLastError();
+ 	len = FormatMessage(
+ 		/* Error API error */
+ 		FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ 		FORMAT_MESSAGE_FROM_SYSTEM |
+ 		FORMAT_MESSAGE_IGNORE_INSERTS,
+ 		NULL,	/* no message source */
+ 		err,
+ 		MAKELANGID(LANG_NEUTRAL,
+ 		SUBLANG_DEFAULT), /* Default language */
+ 		(LPTSTR) &s,
+ 		0,	/* size not used */
+ 		NULL);	/* no args */
+ 	/* remove trailing cr/lf and dots */
+ 	while (len > 0 && (s[len-1] <= ' ' || s[len-1] == '.'))
+ 		s[--len] = '\0';
+ 	if (filename != NULL && Py_UseClassExceptionsFlag)
+ 		v = Py_BuildValue("(iss)", err, s, filename);
+ 	else
+ 		v = Py_BuildValue("(is)", err, s);
+ 	if (v != NULL) {
+ 		PyErr_SetObject(PyExc_EnvironmentError, v);
+ 		Py_DECREF(v);
+ 	}
+ 	LocalFree(s);
+ 	return NULL;
+ }
+ 
+ PyObject *PyErr_SetFromWindowsErr(int ierr)
+ {
+ 	return PyErr_SetFromWindowsErrWithFilename(ierr, NULL);
+ 
+ }
+ #endif /* MS_WINDOWS */
  
  void