[Zope-CVS] CVS: Packages/Spread - spreadmodule.c:1.13

Guido van Rossum guido@python.org
Thu, 20 Dec 2001 12:21:47 -0500


Update of /cvs-repository/Packages/Spread
In directory cvs.zope.org:/tmp/cvs-serv13759

Modified Files:
	spreadmodule.c 
Log Message:
Refactor the error handling routines spread_too_short_error() and
spread_error(), as well as the constant-initialization code in
initspread(), to use more data and less code, and use Py_BuildValue()
when appropriate.


=== Packages/Spread/spreadmodule.c 1.12 => 1.13 ===
 };
 
-/* Useful human-readable error messages for the various error codes
-   defined in sp.h.  The error codes there are negative.  The
-   absolute value of the errors is the index into error_messages.
-*/
+/* Error handling routines below */
 
-#define MAKE_STRING(S) PyString_FromStringAndSize(S, sizeof(S) - 1)
-
-/* Three error handling routines below */
-
-static void spread_too_short_error(int err, int svc_type, int msg_type,
-				   int needed)
+static void
+spread_too_short_error(int err, int svc_type, int msg_type, int needed)
 {
 	PyObject *val;
-	PyObject *reason;
+	char *message;
 
 	switch (err) {
 	case BUFFER_TOO_SHORT:
-		reason = MAKE_STRING("The supplied buffer was too short");
+		message = "The supplied buffer was too short";
 		break;
 	case GROUPS_TOO_SHORT:
-		reason = MAKE_STRING("The supplied groups list was too short");
+		message = "The supplied groups list was too short";
 		break;
 	default:
-		reason = MAKE_STRING("Unrecognized error");
+		message = "Unrecognized error";
 	}
-	if (!reason)
-		return;
 
-	val = Py_BuildValue("iNiii", err, reason, svc_type, msg_type,
+	val = Py_BuildValue("isiii", err, message, svc_type, msg_type,
 			    needed < 0 ? -needed : 0);
 	if (val)
 		PyErr_SetObject(SpreadError, val);
@@ -731,100 +722,144 @@
 /* spread_error(): helper function for setting exceptions from SP_xxx
    return value */
 
-static PyObject *spread_error(int err)
+static PyObject *
+spread_error(int err)
 {
-	PyObject *code, *reason, *tuple;
-
-	code = PyInt_FromLong(err);
-	if (code == NULL)
-		return NULL;
+	char *message = NULL;
+	PyObject *val;
 
-	/* It would be better if spread provided an API function to map
-	   these to error strings.  SP_error() merely prints a string,
+	/* XXX It would be better if spread provided an API function to
+	   map these to error strings.  SP_error() merely prints a string,
 	   which is useful in only limited circumstances. */
 	switch (err) {
 	case ILLEGAL_SPREAD:
-		reason = MAKE_STRING("Illegal spread was provided");
+		message = "Illegal spread was provided";
 		break;
 	case COULD_NOT_CONNECT:
-		reason = MAKE_STRING("Could not connect. Is Spread running?");
+		message = "Could not connect. Is Spread running?";
 		break;
 	case REJECT_QUOTA:
-		reason = MAKE_STRING("Connection rejected, to many users");
+		message = "Connection rejected, to many users";
 		break;
 	case REJECT_NO_NAME:
-		reason = MAKE_STRING(
-			"Connection rejected, no name was supplied");
+		message = "Connection rejected, no name was supplied";
 		break;
 	case REJECT_ILLEGAL_NAME:
-		reason = MAKE_STRING("Connection rejected, illegal name");
+		message = "Connection rejected, illegal name";
 		break;
 	case REJECT_NOT_UNIQUE:
-		reason = MAKE_STRING("Connection rejected, name not unique");
+		message = "Connection rejected, name not unique";
 		break;
 	case REJECT_VERSION:
-		reason = MAKE_STRING(
-			"Connection rejected, library does not fit daemon");
+		message = "Connection rejected, library does not fit daemon";
 		break;
 	case CONNECTION_CLOSED:
-		reason = MAKE_STRING("Connection closed by spread");
+		message = "Connection closed by spread";
 		break;
 	case REJECT_AUTH:
-		reason = MAKE_STRING(
-			"Connection rejected, authentication failed");
+		message = "Connection rejected, authentication failed";
 		break;
 	case ILLEGAL_SESSION:
-		reason = MAKE_STRING("Illegal session was supplied");
+		message = "Illegal session was supplied";
 		break;
 	case ILLEGAL_SERVICE:
-		reason = MAKE_STRING("Illegal service request");
+		message = "Illegal service request";
 		break;
 	case ILLEGAL_MESSAGE:
-		reason = MAKE_STRING("Illegal message");
+		message = "Illegal message";
 		break;
 	case ILLEGAL_GROUP:
-		reason = MAKE_STRING("Illegal group");
+		message = "Illegal group";
 		break;
 	case BUFFER_TOO_SHORT:
-		reason = MAKE_STRING("The supplied buffer was too short");
+		message = "The supplied buffer was too short";
 		break;
 	case GROUPS_TOO_SHORT:
-		reason = MAKE_STRING("The supplied groups list was too short");
+		message = "The supplied groups list was too short";
 		break;
 	case MESSAGE_TOO_LONG:
-		reason = MAKE_STRING("The message body + group names "
-				     "was too large to fit in a message");
+		message = "The message body + group names "
+			  "was too large to fit in a message";
 		break;
 	default:
-		reason = MAKE_STRING("unrecognized error");
-	}
-	if (reason == NULL) {
-		Py_DECREF(code);
-		return NULL;
+		message = "unrecognized error";
 	}
 
-	tuple = PyTuple_New(2);
-	if (tuple == NULL) {
-		Py_DECREF(code);
-		Py_DECREF(reason);
-		return NULL;
+	val = Py_BuildValue("is", err, message);
+	if (val) {
+		PyErr_SetObject(SpreadError, val);
+		Py_DECREF(val);
 	}
-	PyTuple_SET_ITEM(tuple, 0, code);
-	PyTuple_SET_ITEM(tuple, 1, reason);
 
-	PyErr_SetObject(SpreadError, tuple);
 	return NULL;
 }
 
-/* Initialization function for the module (*must* be called initspread) */
+/* Table of symbolic constants defined by Spread.
+   (Programmatically generated from sp.h.) */
+
+static struct constdef {
+	char *name;
+	int value;
+} spread_constants[] = {
+	{"LOW_PRIORITY", LOW_PRIORITY},
+	{"MEDIUM_PRIORITY", MEDIUM_PRIORITY},
+	{"HIGH_PRIORITY", HIGH_PRIORITY},
+	{"DEFAULT_SPREAD_PORT", DEFAULT_SPREAD_PORT},
+	{"SPREAD_VERSION", SPREAD_VERSION},
+	{"MAX_GROUP_NAME", MAX_GROUP_NAME},
+	{"MAX_PRIVATE_NAME", MAX_PRIVATE_NAME},
+	{"MAX_PROC_NAME", MAX_PROC_NAME},
+	{"UNRELIABLE_MESS", UNRELIABLE_MESS},
+	{"RELIABLE_MESS", RELIABLE_MESS},
+	{"FIFO_MESS", FIFO_MESS},
+	{"CAUSAL_MESS", CAUSAL_MESS},
+	{"AGREED_MESS", AGREED_MESS},
+	{"SAFE_MESS", SAFE_MESS},
+	{"REGULAR_MESS", REGULAR_MESS},
+	{"SELF_DISCARD", SELF_DISCARD},
+	{"DROP_RECV", DROP_RECV},
+	{"REG_MEMB_MESS", REG_MEMB_MESS},
+	{"TRANSITION_MESS", TRANSITION_MESS},
+	{"CAUSED_BY_JOIN", CAUSED_BY_JOIN},
+	{"CAUSED_BY_LEAVE", CAUSED_BY_LEAVE},
+	{"CAUSED_BY_DISCONNECT", CAUSED_BY_DISCONNECT},
+	{"CAUSED_BY_NETWORK", CAUSED_BY_NETWORK},
+	{"MEMBERSHIP_MESS", MEMBERSHIP_MESS},
+	{"ENDIAN_RESERVED", ENDIAN_RESERVED},
+	{"RESERVED", RESERVED},
+	{"REJECT_MESS", REJECT_MESS},
+	{"ACCEPT_SESSION", ACCEPT_SESSION},
+	{"ILLEGAL_SPREAD", ILLEGAL_SPREAD},
+	{"COULD_NOT_CONNECT", COULD_NOT_CONNECT},
+	{"REJECT_QUOTA", REJECT_QUOTA},
+	{"REJECT_NO_NAME", REJECT_NO_NAME},
+	{"REJECT_ILLEGAL_NAME", REJECT_ILLEGAL_NAME},
+	{"REJECT_NOT_UNIQUE", REJECT_NOT_UNIQUE},
+	{"REJECT_VERSION", REJECT_VERSION},
+	{"CONNECTION_CLOSED", CONNECTION_CLOSED},
+	{"REJECT_AUTH", REJECT_AUTH},
+	{"ILLEGAL_SESSION", ILLEGAL_SESSION},
+	{"ILLEGAL_SERVICE", ILLEGAL_SERVICE},
+	{"ILLEGAL_MESSAGE", ILLEGAL_MESSAGE},
+	{"ILLEGAL_GROUP", ILLEGAL_GROUP},
+	{"BUFFER_TOO_SHORT", BUFFER_TOO_SHORT},
+	{"GROUPS_TOO_SHORT", GROUPS_TOO_SHORT},
+	{"MESSAGE_TOO_LONG", MESSAGE_TOO_LONG},
+	{NULL}
+};
+
+/* Initialization function for the module */
 
 DL_EXPORT(void)
-	initspread(void)
+initspread(void)
 {
 	PyObject *m;
+	struct constdef *p;
 
 	/* Create the module and add the functions */
 	m = Py_InitModule("spread", spread_methods);
+	if (m == NULL)
+		return;
 
 	/* Initialize the type of the new type object here; doing it here
 	 * is required for portability to Windows without requiring C++. */
@@ -832,68 +867,35 @@
 	RegularMsg_Type.ob_type = &PyType_Type;
 	MembershipMsg_Type.ob_type = &PyType_Type;
 
-	/* XXX AddObject() DECREFs its third argument */
+	/* PyModule_AddObject() DECREFs its third argument */
 	Py_INCREF(&Mailbox_Type);
+	if (PyModule_AddObject(m, "MailboxType",
+			       (PyObject *)&Mailbox_Type) < 0)
+		return;
 	Py_INCREF(&RegularMsg_Type);
+	if (PyModule_AddObject(m, "RegularMsgType",
+			       (PyObject *)&RegularMsg_Type) < 0)
+		return;
 	Py_INCREF(&MembershipMsg_Type);
-	PyModule_AddObject(m, "MailboxType", (PyObject *)&Mailbox_Type);
-	PyModule_AddObject(m, "RegularMsgType", (PyObject *)&RegularMsg_Type);
-	PyModule_AddObject(m, "MembershipMsgType",
-			   (PyObject *)&MembershipMsg_Type);
+	if (PyModule_AddObject(m, "MembershipMsgType",
+			       (PyObject *)&MembershipMsg_Type) < 0)
+		return;
 
-	/* Add some symbolic constants to the module */
+	/* Create the exception, if necessary */
 	if (SpreadError == NULL) {
 		SpreadError = PyErr_NewException("spread.error", NULL, NULL);
 		if (SpreadError == NULL)
 			return;
 	}
+
+	/* Add the exception to the module */
 	Py_INCREF(SpreadError);
-	PyModule_AddObject(m, "error", SpreadError);
+	if (PyModule_AddObject(m, "error", SpreadError) < 0)
+		return;
 
-	/* programmatically generated from sp.h */
-	PyModule_AddIntConstant(m, "LOW_PRIORITY", LOW_PRIORITY);
-	PyModule_AddIntConstant(m, "MEDIUM_PRIORITY", MEDIUM_PRIORITY);
-	PyModule_AddIntConstant(m, "HIGH_PRIORITY", HIGH_PRIORITY);
-	PyModule_AddIntConstant(m, "DEFAULT_SPREAD_PORT", DEFAULT_SPREAD_PORT);
-	PyModule_AddIntConstant(m, "SPREAD_VERSION", SPREAD_VERSION);
-	PyModule_AddIntConstant(m, "MAX_GROUP_NAME", MAX_GROUP_NAME);
-	PyModule_AddIntConstant(m, "MAX_PRIVATE_NAME", MAX_PRIVATE_NAME);
-	PyModule_AddIntConstant(m, "MAX_PROC_NAME", MAX_PROC_NAME);
-	PyModule_AddIntConstant(m, "UNRELIABLE_MESS", UNRELIABLE_MESS);
-	PyModule_AddIntConstant(m, "RELIABLE_MESS", RELIABLE_MESS);
-	PyModule_AddIntConstant(m, "FIFO_MESS", FIFO_MESS);
-	PyModule_AddIntConstant(m, "CAUSAL_MESS", CAUSAL_MESS);
-	PyModule_AddIntConstant(m, "AGREED_MESS", AGREED_MESS);
-	PyModule_AddIntConstant(m, "SAFE_MESS", SAFE_MESS);
-	PyModule_AddIntConstant(m, "REGULAR_MESS", REGULAR_MESS);
-	PyModule_AddIntConstant(m, "SELF_DISCARD", SELF_DISCARD);
-	PyModule_AddIntConstant(m, "DROP_RECV", DROP_RECV);
-	PyModule_AddIntConstant(m, "REG_MEMB_MESS", REG_MEMB_MESS);
-	PyModule_AddIntConstant(m, "TRANSITION_MESS", TRANSITION_MESS);
-	PyModule_AddIntConstant(m, "CAUSED_BY_JOIN", CAUSED_BY_JOIN);
-	PyModule_AddIntConstant(m, "CAUSED_BY_LEAVE", CAUSED_BY_LEAVE);
-	PyModule_AddIntConstant(m, "CAUSED_BY_DISCONNECT",
-				CAUSED_BY_DISCONNECT);
-	PyModule_AddIntConstant(m, "CAUSED_BY_NETWORK", CAUSED_BY_NETWORK);
-	PyModule_AddIntConstant(m, "MEMBERSHIP_MESS", MEMBERSHIP_MESS);
-	PyModule_AddIntConstant(m, "ENDIAN_RESERVED", ENDIAN_RESERVED);
-	PyModule_AddIntConstant(m, "RESERVED", RESERVED);
-	PyModule_AddIntConstant(m, "REJECT_MESS", REJECT_MESS);
-	PyModule_AddIntConstant(m, "ACCEPT_SESSION", ACCEPT_SESSION);
-	PyModule_AddIntConstant(m, "ILLEGAL_SPREAD", ILLEGAL_SPREAD);
-	PyModule_AddIntConstant(m, "COULD_NOT_CONNECT", COULD_NOT_CONNECT);
-	PyModule_AddIntConstant(m, "REJECT_QUOTA", REJECT_QUOTA);
-	PyModule_AddIntConstant(m, "REJECT_NO_NAME", REJECT_NO_NAME);
-	PyModule_AddIntConstant(m, "REJECT_ILLEGAL_NAME", REJECT_ILLEGAL_NAME);
-	PyModule_AddIntConstant(m, "REJECT_NOT_UNIQUE", REJECT_NOT_UNIQUE);
-	PyModule_AddIntConstant(m, "REJECT_VERSION", REJECT_VERSION);
-	PyModule_AddIntConstant(m, "CONNECTION_CLOSED", CONNECTION_CLOSED);
-	PyModule_AddIntConstant(m, "REJECT_AUTH", REJECT_AUTH);
-	PyModule_AddIntConstant(m, "ILLEGAL_SESSION", ILLEGAL_SESSION);
-	PyModule_AddIntConstant(m, "ILLEGAL_SERVICE", ILLEGAL_SERVICE);
-	PyModule_AddIntConstant(m, "ILLEGAL_MESSAGE", ILLEGAL_MESSAGE);
-	PyModule_AddIntConstant(m, "ILLEGAL_GROUP", ILLEGAL_GROUP);
-	PyModule_AddIntConstant(m, "BUFFER_TOO_SHORT", BUFFER_TOO_SHORT);
-	PyModule_AddIntConstant(m, "GROUPS_TOO_SHORT", GROUPS_TOO_SHORT);
-	PyModule_AddIntConstant(m, "MESSAGE_TOO_LONG", MESSAGE_TOO_LONG);
+	/* Add the Spread symbolic constants to the module */
+	for (p = spread_constants; p->name != NULL; p++) {
+		if (PyModule_AddIntConstant(m, p->name, p->value) < 0)
+			return;
+	}
 }