
benjamin at python
May 3, 2012, 10:07 PM
Post #1 of 7
(133 views)
Permalink
|
|
Re: [Python-checkins] cpython: Issue #14127: Add ns= parameter to utime, futimes, and lutimes.
|
|
2012/5/3 larry.hastings <python-checkins [at] python>: > 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 [at] python http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/list-python-dev%40lists.gossamer-threads.com
|