[Python-checkins] python/nondist/sandbox/datetime datetime.c,1.76,1.77 doc.txt,1.56,1.57 test_datetime.py,1.70,1.71

tim_one@users.sourceforge.net tim_one@users.sourceforge.net
2002年12月15日 19:34:23 -0800


Update of /cvsroot/python/python/nondist/sandbox/datetime
In directory sc8-pr-cvs1:/tmp/cvs-serv22530
Modified Files:
	datetime.c doc.txt test_datetime.py 
Log Message:
Whew -- the C implementation of strftime is complete. Messy as hell,
but complete.
Index: datetime.c
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.c,v
retrieving revision 1.76
retrieving revision 1.77
diff -C2 -d -r1.76 -r1.77
*** datetime.c	16 Dec 2002 00:50:10 -0000	1.76
--- datetime.c	16 Dec 2002 03:34:20 -0000	1.77
***************
*** 766,771 ****
 }
 
 /* I sure don't want to reproduce the strftime code from the time module,
! * so this imports the module and calls it. Most of the hair is due to
 * giving special meanings to the %z and %Z format codes via a preprocessing
 * step on the format string.
--- 766,808 ----
 }
 
+ /* Add an hours & minutes UTC offset string to buf. buf has no more than
+ * buflen bytes remaining. The UTC offset is gotten by calling
+ * tzinfo.uctoffset(tzinfoarg). If that returns None, 0円 is stored into
+ * *buf, and that's all. Else the returned value is checked for sanity (an
+ * integer in range), and if that's OK it's converted to an hours & minutes
+ * string of the form
+ * sign HH sep MM
+ * Returns 0 if everything is OK. If the return value from utcoffset() is
+ * bogus, an appropriate exception is set and -1 is returned.
+ */
+ static int
+ format_utcoffset(char *buf, int buflen, const char *sep,
+ 		PyObject *tzinfo, PyObject *tzinfoarg)
+ {
+ 	int offset;
+ 	int hours;
+ 	int minutes;
+ 	char sign;
+ 	int none;
+ 
+ 	offset = call_utcoffset(tzinfo, tzinfoarg, &none);
+ 	if (offset == -1 && PyErr_Occurred())
+ 		return -1;
+ 	if (none) {
+ 		*buf = '0円';
+ 		return 0;
+ 	}
+ 	sign = '+';
+ 	if (offset < 0) {
+ 		sign = '-';
+ 		offset = - offset;
+ 	}
+ 	hours = divmod(offset, 60, &minutes);
+ 	PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
+ 	return 0;
+ }
+ 
 /* I sure don't want to reproduce the strftime code from the time module,
! * so this imports the module and calls it. All the hair is due to
 * giving special meanings to the %z and %Z format codes via a preprocessing
 * step on the format string.
***************
*** 774,790 ****
 wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple)
 {
! 	PyObject *time;
! 	PyObject *result;
 
 	assert(object && format && timetuple);
 	assert(PyString_Check(format));
 
! 	time = PyImport_ImportModule("time");
! 	if (time == NULL)
! 		return NULL;
 
! 	result = PyObject_CallMethod(time, "strftime", "OO",
! 				 format, timetuple);
! 	Py_DECREF(time);
 	return result;
 }
--- 811,976 ----
 wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple)
 {
! 	PyObject *result = NULL;	/* guilty until proved innocent */
! 
! 	PyObject *zreplacement = NULL;	/* py string, replacement for %z */
! 	PyObject *Zreplacement = NULL;	/* py string, replacement for %Z */
! 
! 	char *pin;	/* pointer to next char in input format */
! 	char ch;	/* next char in input format */
! 
! 	PyObject *newfmt = NULL;	/* py string, the output format */
! 	char *pnew;	/* pointer to available byte in output format */
! 	char totalnew;	/* number bytes total in output format buffer,
! 			 exclusive of trailing 0円 */
! 	char usednew;	/* number bytes used so far in output format buffer */
! 
! 	char *ptoappend; /* pointer to string to append to output buffer */
! 	int ntoappend;	/* # of bytes to append to output buffer */
! 
! 	char buf[100];	/* scratch buffer */
 
 	assert(object && format && timetuple);
 	assert(PyString_Check(format));
 
! 	/* Scan the input format, looking for %z and %Z escapes, building
! 	 * a new format.
! 	 */
! 	totalnew = PyString_Size(format);	/* realistic if no %z/%Z */
! 	newfmt = PyString_FromStringAndSize(NULL, totalnew);
! 	if (newfmt == NULL) goto Done;
! 	pnew = PyString_AsString(newfmt);
! 	usednew = 0;
 
! 	pin = PyString_AsString(format);
! 	while ((ch = *pin++) != '0円') {
! 		if (ch != '%') {
! 			buf[0] = ch;
! 			ptoappend = buf;
! 			ntoappend = 1;
! 			goto Append;
! 		}
! 		if ((ch = *pin++) == '0円') {
! 			/* There's a lone trailing %; doesn't make sense. */
! 			PyErr_SetString(PyExc_ValueError, "strftime format "
! 					"ends with raw %");
! 			goto Done;
! 		}
! 		if (ch != 'z' && ch != 'Z') {
! 			buf[0] = '%';
! 			buf[1] = ch;
! 			ptoappend = buf;
! 			ntoappend = 2;
! 			goto Append;
! 		}
! 		if (ch == 'z') {
! 			if (zreplacement == NULL) {
! 				/* format utcoffset */
! 				PyObject *tzinfo = Py_None;
! 				zreplacement = PyString_FromString("");
! 				if (zreplacement == NULL) goto Done;
! 				if (PyDateTimeTZ_Check(object))
! 					tzinfo = ((PyDateTime_DateTimeTZ *)
! 						 object)->tzinfo;
! 				else if (PyTimeTZ_Check(object))
! 					tzinfo = ((PyDateTime_TimeTZ *)
! 						 object)->tzinfo;
! 				if (tzinfo != Py_None) {
! 					if (format_utcoffset(buf,
! 							 (int)sizeof(buf),
! 							 "",
! 							 tzinfo,
! 							 object) < 0)
! 						goto Done;
! 					Py_DECREF(zreplacement);
! 					zreplacement = PyString_FromString(buf);
! 					if (zreplacement == NULL) goto Done;
! 				}
! 			}
! 			assert(zreplacement != NULL);
! 			ptoappend = PyString_AsString(zreplacement);
! 			ntoappend = PyString_Size(zreplacement);
! 			goto Append;
! 		}
! 		assert(ch == 'Z');
! 		/* format tzname */
! 		if (Zreplacement == NULL) {
! 			Zreplacement = PyString_FromString("");
! 			if (Zreplacement == NULL) goto Done;
! 			if (PyObject_HasAttrString(object, "tzname")) {
! 				PyObject *temp;
! 				temp = PyObject_CallMethod(object, "tzname",
! 							 "()");
! 				if (temp == NULL) goto Done;
! 				if (temp != Py_None && !PyString_Check(temp)) {
! 					PyErr_Format(PyExc_TypeError,
! 						"tzname() must return None "
! 						"or a string, not '%s'",
! 						temp->ob_type->tp_name);
! 					Py_DECREF(temp);
! 					goto Done;
! 				}
! 				if (temp != Py_None) {
! 					assert(PyString_Check(temp));
! 					/* Since the tzname is getting stuffed
! 					 * into the format, we have to double
! 					 * any % signs so that strftime
! 					 * doesn't treat them as format
! 					 * codes.
! 					 */
! 					Py_DECREF(Zreplacement);
! 					Zreplacement = PyObject_CallMethod(
! 								temp,
! 								"replace",
! 								"ss",
! 								"%", "%%");
! 					Py_DECREF(temp);
! 					if (Zreplacement == NULL) goto Done;
! 				}
! 				else
! 					Py_DECREF(temp);
! 			}
! 		}
! 		assert(Zreplacement != NULL);
! 		ptoappend = PyString_AsString(Zreplacement);
! 		ntoappend = PyString_Size(Zreplacement);
! 
! Append:
! 		/* Append the ntoappend chars starting at ptoappend to
! 		 * the new format.
! 		 */
! 		assert(ntoappend >= 0);
! 		if (ntoappend == 0)
! 			continue;
! 		while (usednew + ntoappend > totalnew) {
! 			int bigger = totalnew << 1;
! 			if ((bigger >> 1) != totalnew) { /* overflow */
! 				PyErr_NoMemory();
! 				goto Done;
! 			}
! 			if (_PyString_Resize(&newfmt, bigger) < 0)
! 				goto Done;
! 			totalnew = bigger;
! 			pnew = PyString_AsString(newfmt) + usednew;
! 		}
! 		memcpy(pnew, ptoappend, ntoappend);
! 		pnew += ntoappend;
! 		usednew += ntoappend;
! 		assert(usednew <= totalnew);
! 	} /* end while() */
! 
! 	if (_PyString_Resize(&newfmt, usednew) < 0)
! 		goto Done;
! 	{
! 		PyObject *time = PyImport_ImportModule("time");
! 		if (time == NULL)
! 			goto Done;
! 		result = PyObject_CallMethod(time, "strftime", "OO",
! 					 newfmt, timetuple);
! 		Py_DECREF(time);
! 	}
! Done:
! 	Py_XDECREF(zreplacement);
! 	Py_XDECREF(Zreplacement);
! 	Py_XDECREF(newfmt);
 	return result;
 }
***************
*** 812,852 ****
 	if (us)
 		PyOS_snprintf(buffer + 8, bufflen - 8, ".%06d", us);
- }
- 
- /* Add an hours & minutes UTC offset string to buf. buf has no more than
- * buflen bytes remaining. The UTC offset is gotten by calling
- * tzinfo.uctoffset(tzinfoarg). If that returns None, 0円 is stored into
- * *buf, and that's all. Else the returned value is checked for sanity (an
- * integer in range), and if that's OK it's converted to an hours & minutes
- * string of the form
- * sign HH sep MM
- * Returns 0 if everything is OK. If the return value from utcoffset() is
- * bogus, an appropriate exception is set and -1 is returned.
- */
- static int
- format_utcoffset(char *buf, int buflen, const char *sep,
- 		PyObject *tzinfo, PyObject *tzinfoarg)
- {
- 	int offset;
- 	int hours;
- 	int minutes;
- 	char sign;
- 	int none;
- 
- 	offset = call_utcoffset(tzinfo, tzinfoarg, &none);
- 	if (offset == -1 && PyErr_Occurred())
- 		return -1;
- 	if (none) {
- 		*buf = '0円';
- 		return 0;
- 	}
- 	sign = '+';
- 	if (offset < 0) {
- 		sign = '-';
- 		offset = - offset;
- 	}
- 	hours = divmod(offset, 60, &minutes);
- 	PyOS_snprintf(buf, buflen, "%c%02d%s%02d", sign, hours, sep, minutes);
- 	return 0;
 }
 
--- 998,1001 ----
Index: doc.txt
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/doc.txt,v
retrieving revision 1.56
retrieving revision 1.57
diff -C2 -d -r1.56 -r1.57
*** doc.txt	16 Dec 2002 00:25:34 -0000	1.56
--- doc.txt	16 Dec 2002 03:34:21 -0000	1.57
***************
*** 3,10 ****
 - The Python implementation is missing docstrings in many places.
 
- - The custom %z and %Z format codes for timetz and datetimetz
- .strftime needs a C implementation (yuck). More generally,
- %z and %Z are plain busted in the C implementation.
- 
 - LaTeXize the docs.
 
--- 3,6 ----
***************
*** 14,17 ****
--- 10,18 ----
 CLOSED
 ======
+ - The custom %z and %Z format codes for timetz and datetimetz
+ .strftime needs a C implementation (yuck). More generally,
+ %z and %Z are plain busted in the C implementation.
+ Done.
+ 
 - datetimetz needs a C implementation. This seems "almost done". I
 suspect I'm missing some untested method(s) still in the Python
Index: test_datetime.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v
retrieving revision 1.70
retrieving revision 1.71
diff -C2 -d -r1.70 -r1.71
*** test_datetime.py	16 Dec 2002 00:25:34 -0000	1.70
--- test_datetime.py	16 Dec 2002 03:34:21 -0000	1.71
***************
*** 13,18 ****
 import unittest
 
- # XXX strftime is broken in the C implementation, when using %z or %Z.
- 
 # Import the right implementation, under name "datetime".
 TESTING_C = 'c' in sys.argv
--- 13,16 ----

AltStyle によって変換されたページ (->オリジナル) /