[Python-Dev] [Python-checkins] cpython: Issue #14127: Add ns= parameter to utime, futimes, and lutimes.
Benjamin Peterson
benjamin at python.org
Fri May 4 07:07:04 CEST 2012
2012/5/3 larry.hastings <python-checkins at 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
More information about the Python-Dev
mailing list