2012/5/3 larry.hastings <python-check...@python.org>: > diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c > --- a/Modules/posixmodule.c > +++ b/Modules/posixmodule.c > @@ -3572,28 +3572,194 @@ > #endif /* HAVE_UNAME */ > > > +static int > +split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns) > +{ > + int result = 0; > + PyObject *divmod; > + divmod = PyNumber_Divmod(py_long, billion); > + if (!divmod) > + goto exit; > + *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0)); > + if ((*s == -1) && PyErr_Occurred()) > + goto exit; > + *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1)); > + if ((*s == -1) && PyErr_Occurred()) > + goto exit; > + > + result = 1; > +exit: > + Py_XDECREF(divmod); > + return result; > +} > + > + > +typedef int (*parameter_converter_t)(PyObject *, void *); > + > +typedef struct { > + /* input only */ > + char path_format; > + parameter_converter_t converter; > + char *function_name; > + char *first_argument_name; > + PyObject *args; > + PyObject *kwargs; > + > + /* input/output */ > + PyObject **path; > + > + /* output only */ > + int now; > + time_t atime_s; > + long atime_ns; > + time_t mtime_s; > + long mtime_ns; > +} utime_arguments; > + > +#define DECLARE_UA(ua, fname) \ > + utime_arguments ua; \ > + memset(&ua, 0, sizeof(ua)); \ > + ua.function_name = fname; \ > + ua.args = args; \ > + ua.kwargs = kwargs; \ > + ua.first_argument_name = "path"; \ > + > +/* UA_TO_FILETIME doesn't declare atime and mtime for you */ > +#define UA_TO_FILETIME(ua, atime, mtime) \ > + time_t_to_FILE_TIME(ua.atime_s, ua.atime_ns, &atime); \ > + time_t_to_FILE_TIME(ua.mtime_s, ua.mtime_ns, &mtime) > + > +/* the rest of these macros declare the output variable for you */ > +#define UA_TO_TIMESPEC(ua, ts) \ > + struct timespec ts[2]; \ > + ts[0].tv_sec = ua.atime_s; \ > + ts[0].tv_nsec = ua.atime_ns; \ > + ts[1].tv_sec = ua.mtime_s; \ > + ts[1].tv_nsec = ua.mtime_ns > + > +#define UA_TO_TIMEVAL(ua, tv) \ > + struct timeval tv[2]; \ > + tv[0].tv_sec = ua.atime_s; \ > + tv[0].tv_usec = ua.atime_ns / 1000; \ > + tv[1].tv_sec = ua.mtime_s; \ > + tv[1].tv_usec = ua.mtime_ns / 1000 > + > +#define UA_TO_UTIMBUF(ua, u) \ > + struct utimbuf u; \ > + utimbuf.actime = ua.atime_s; \ > + utimbuf.modtime = ua.mtime_s > + > +#define UA_TO_TIME_T(ua, timet) \ > + time_t timet[2]; \ > + timet[0] = ua.atime_s; \ > + timet[1] = ua.mtime_s > + > + > +/* > + * utime_read_time_arguments() processes arguments for the utime > + * family of functions. > + * returns zero on failure. > + */ > +static int > +utime_read_time_arguments(utime_arguments *ua) > +{ > + PyObject *times = NULL; > + PyObject *ns = NULL; > + char format[24]; > + char *kwlist[4]; > + char **kw = kwlist; > + int return_value; > + > + *kw++ = ua->first_argument_name; > + *kw++ = "times"; > + *kw++ = "ns"; > + *kw = NULL; > + > + sprintf(format, "%c%s|O$O:%s", > + ua->path_format, > + ua->converter ? "&" : "", > + ua->function_name); > + > + if (ua->converter) > + return_value = PyArg_ParseTupleAndKeywords(ua->args, ua->kwargs, > + format, kwlist, ua->converter, ua->path, ×, &ns); > + else > + return_value = PyArg_ParseTupleAndKeywords(ua->args, ua->kwargs, > + format, kwlist, ua->path, ×, &ns); > + > + if (!return_value) > + return 0; > + > + if (times && ns) { > + PyErr_Format(PyExc_RuntimeError,
Why not a ValueError or TypeError? > + "%s: you may specify either 'times'" > + " or 'ns' but not both", > + ua->function_name); > + return 0; > + } > + > + if (times && (times != Py_None)) { Conditions in parenthesis like this is not style. > + if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) { > + PyErr_Format(PyExc_TypeError, > + "%s: 'time' must be either" > + " a valid tuple of two ints or None", > + ua->function_name); > + return 0; > + } > + ua->now = 0; > + return (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0), > + &(ua->atime_s), &(ua->atime_ns)) != -1) > + && (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1), Put && on previous line like Python. > + &(ua->mtime_s), &(ua->mtime_ns)) != -1); > + } > + > + if (ns) { > + if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) { > + PyErr_Format(PyExc_TypeError, > + "%s: 'ns' must be a valid tuple of two ints", > + ua->function_name); > + return 0; > + } > + ua->now = 0; > + return (split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0), > + &(ua->atime_s), &(ua->atime_ns))) > + && (split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1), > + &(ua->mtime_s), &(ua->mtime_ns))); > + } > + > + /* either times=None, or neither times nor ns was specified. use "now". > */ > + ua->now = 1; > + return 1; > +} -- Regards, Benjamin _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com