[Python-Dev] [Python-checkins] cpython: Issue #14127: Add ns= parameter to utime, futimes, and lutimes. (original) (raw)

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 /* HAVEUNAME */

+static int +splitpylongtosandns(PyObject *pylong, timet *s, long *ns) +{ +    int result = 0; +    PyObject *divmod; +    divmod = PyNumberDivmod(pylong, billion); +    if (!divmod) +        goto exit; +    *s = PyLongAsTimet(PyTupleGETITEM(divmod, 0)); +    if ((*s == -1) && PyErrOccurred()) +        goto exit; +    *ns = PyLongAsLong(PyTupleGETITEM(divmod, 1)); +    if ((*s == -1) && PyErrOccurred()) +        goto exit; + +    result = 1; +exit: +    PyXDECREF(divmod); +    return result; +} + + +typedef int (*parameterconvertert)(PyObject *, void *); + +typedef struct { +    /* input only */ +    char pathformat; +    parameterconvertert converter; +    char *functionname; +    char *firstargumentname; +    PyObject *args; +    PyObject *kwargs; + +    /* input/output */ +    PyObject **path; + +    /* output only */ +    int now; +    timet atimes; +    long   atimens; +    timet mtimes; +    long   mtimens; +} utimearguments; + _+#define DECLAREUA(ua, fname) _ _+    utimearguments ua; _ _+    memset(&ua, 0, sizeof(ua)); _ _+    ua.functionname = fname; _ _+    ua.args = args; _ _+    ua.kwargs = kwargs; _ _+    ua.firstargumentname = "path"; _ + +/* UATOFILETIME doesn't declare atime and mtime for you */ _+#define UATOFILETIME(ua, atime, mtime) _ _+    timettoFILETIME(ua.atimes, ua.atimens, &atime); _ +    timettoFILETIME(ua.mtimes, ua.mtimens, &mtime) + +/* the rest of these macros declare the output variable for you */ _+#define UATOTIMESPEC(ua, ts) _ _+    struct timespec ts[2]; _ _+    ts[0].tvsec = ua.atimes; _ _+    ts[0].tvnsec = ua.atimens; _ _+    ts[1].tvsec = ua.mtimes; _ +    ts[1].tvnsec = ua.mtimens + _+#define UATOTIMEVAL(ua, tv) _ _+    struct timeval tv[2]; _ _+    tv[0].tvsec = ua.atimes; _ _+    tv[0].tvusec = ua.atimens / 1000; _ _+    tv[1].tvsec = ua.mtimes; _ +    tv[1].tvusec = ua.mtimens / 1000 + _+#define UATOUTIMBUF(ua, u) _ _+    struct utimbuf u; _ _+    utimbuf.actime = ua.atimes; _ +    utimbuf.modtime = ua.mtimes + _+#define UATOTIMET(ua, timet) _ _+    timet timet[2]; _ _+    timet[0] = ua.atimes; _ +    timet[1] = ua.mtimes + + +/* + * utimereadtimearguments() processes arguments for the utime + * family of functions. + * returns zero on failure. + */ +static int +utimereadtimearguments(utimearguments *ua) +{ +    PyObject *times = NULL; +    PyObject *ns = NULL; +    char format[24]; +    char *kwlist[4]; +    char **kw = kwlist; +    int returnvalue; + +    *kw++ = ua->firstargumentname; +    *kw++ = "times"; +    *kw++ = "ns"; +    *kw = NULL; + +    sprintf(format, "%c%s|O$O:%s", +            ua->pathformat, +            ua->converter ? "&" : "", +            ua->functionname); + +    if (ua->converter) +        returnvalue = PyArgParseTupleAndKeywords(ua->args, ua->kwargs, +            format, kwlist, ua->converter, ua->path, &times, &ns); +    else +        returnvalue = PyArgParseTupleAndKeywords(ua->args, ua->kwargs, +            format, kwlist, ua->path, &times, &ns); + +    if (!returnvalue) +        return 0; + +    if (times && ns) { +        PyErrFormat(PyExcRuntimeError,

Why not a ValueError or TypeError?

+                     "%s: you may specify either 'times'" +                     " or 'ns' but not both", +                     ua->functionname); +        return 0; +    } + +    if (times && (times != PyNone)) {

Conditions in parenthesis like this is not style.

+        if (!PyTupleCheckExact(times) || (PyTupleSize(times) != 2)) { +            PyErrFormat(PyExcTypeError, +                         "%s: 'time' must be either" +                         " a valid tuple of two ints or None", +                         ua->functionname); +            return 0; +        } +        ua->now = 0; +        return (PyTimeObjectToTimespec(PyTupleGETITEM(times, 0), +                    &(ua->atimes), &(ua->atimens)) != -1) +            && (PyTimeObjectToTimespec(PyTupleGETITEM(times, 1),

Put && on previous line like Python.

+                    &(ua->mtimes), &(ua->mtimens)) != -1); +    } + +    if (ns) { +        if (!PyTupleCheckExact(ns) || (PyTupleSize(ns) != 2)) { +            PyErrFormat(PyExcTypeError, +                         "%s: 'ns' must be a valid tuple of two ints", +                         ua->functionname); +            return 0; +        } +        ua->now = 0; +        return (splitpylongtosandns(PyTupleGETITEM(ns, 0), +                    &(ua->atimes), &(ua->atimens))) +            && (splitpylongtosandns(PyTupleGETITEM(ns, 1), +                    &(ua->mtimes), &(ua->mtimens))); +    } + +    /* 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