about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPaul Ackersviller <packersv@users.sourceforge.net>2007-12-10 00:25:15 +0000
committerPaul Ackersviller <packersv@users.sourceforge.net>2007-12-10 00:25:15 +0000
commitd359cf68253e3f7c667d3746aaf469843521a6b1 (patch)
tree1265c793833ca9650b6949062905b88d361691b6
parent0c4f0daed6ff991058274c8396675f85c23606eb (diff)
downloadzsh-d359cf68253e3f7c667d3746aaf469843521a6b1.tar.gz
zsh-d359cf68253e3f7c667d3746aaf469843521a6b1.tar.xz
zsh-d359cf68253e3f7c667d3746aaf469843521a6b1.zip
Merge of 24197: interface to ztrftime() for insufficient memory was broken.
-rw-r--r--ChangeLog5
-rw-r--r--Src/Modules/datetime.c133
-rw-r--r--Src/utils.c8
3 files changed, 142 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 2b40cb0e8..0ba193293 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2007-12-09  Peter Stephenson  <p.w.stephenson@ntlworld.com>
+
+	* 24197, Src/utils.c, Src/Modules/datetime.c: interface to
+	ztrftime() for insufficient memory was broken.
+
 2007-12-08  Clint Adams  <clint@zsh.org>
 
 	* 24188: Completion/Unix/Command/_id: completion for GNU id.
diff --git a/Src/Modules/datetime.c b/Src/Modules/datetime.c
new file mode 100644
index 000000000..276cd5d24
--- /dev/null
+++ b/Src/Modules/datetime.c
@@ -0,0 +1,133 @@
+/*
+ * datetime.c - parameter and command interface to date and time utilities
+ *
+ * This file is part of zsh, the Z shell.
+ *
+ * Copyright (c) 2002 Peter Stephenson, Clint Adams
+ * All rights reserved.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and to distribute modified versions of this software for any
+ * purpose, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * In no event shall Peter Stephenson, Clint Adams or the Zsh Development Group
+ * be liable to any party for direct, indirect, special, incidental, or
+ * consequential damages arising out of the use of this software and its
+ * documentation, even if Peter Stephenson, Clint Adams and the Zsh
+ * Development Group have been advised of the possibility of such damage.
+ *
+ * Peter Stephenson, Clint Adams and the Zsh Development Group specifically
+ * disclaim any warranties, including, but not limited to, the implied
+ * warranties of merchantability and fitness for a particular purpose.
+ * The software provided hereunder is on an "as is" basis, and Peter
+ * Stephenson, Clint Adams and the Zsh Development Group have no obligation
+ * to provide maintenance, support, updates, enhancements, or modifications.
+ *
+ */
+
+#include "datetime.mdh"
+#include "datetime.pro"
+#include <time.h>
+
+static int
+bin_strftime(char *nam, char **argv, Options ops, UNUSED(int func))
+{
+    int bufsize, x;
+    char *endptr = NULL, *scalar = NULL, *buffer;
+    time_t secs;
+    struct tm *t;
+
+    if (OPT_ISSET(ops,'s')) {
+	scalar = OPT_ARG(ops, 's');
+	if (!isident(scalar)) {
+	    zwarnnam(nam, "not an identifier: %s", scalar, 0);
+	    return 1;
+	}
+    }
+
+    secs = (time_t)strtoul(argv[1], &endptr, 10);
+    if (secs == (time_t)ULONG_MAX) {
+	zwarnnam(nam, "%s: %e", argv[1], errno);
+	return 1;
+    } else if (*endptr != '\0') {
+	zwarnnam(nam, "%s: invalid decimal number", argv[1], 0);
+	return 1;
+    }
+
+    t = localtime(&secs);
+    bufsize = strlen(argv[0]) * 8;
+    buffer = zalloc(bufsize);
+
+    for (x=0; x < 4; x++) {
+        if (ztrftime(buffer, bufsize, argv[0], t) >= 0)
+	    break;
+	buffer = zrealloc(buffer, bufsize *= 2);
+    }
+
+    if (scalar) {
+	setsparam(scalar, ztrdup(buffer));
+    } else {
+	printf("%s\n", buffer);
+    }
+    zfree(buffer, bufsize);
+
+    return 0;
+}
+
+static zlong
+getcurrentsecs()
+{
+    return (zlong) time(NULL);
+}
+
+static struct builtin bintab[] = {
+    BUILTIN("strftime",    0, bin_strftime,    2,   2, 0, "s:", NULL),
+};
+
+static const struct gsu_integer epochseconds_gsu =
+{ getcurrentsecs, NULL, stdunsetfn };
+
+static struct paramdef patab[] = {
+    PARAMDEF("EPOCHSECONDS", PM_INTEGER|PM_SPECIAL|PM_READONLY,
+		    NULL, &epochseconds_gsu),
+};
+
+/**/
+int
+setup_(UNUSED(Module m))
+{
+    return 0;
+}
+
+/**/
+int
+boot_(Module m)
+{
+    return !(addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)) |
+	     addparamdefs(m->nam, patab, sizeof(patab)/sizeof(*patab))
+	    );
+}
+
+/**/
+int
+cleanup_(Module m)
+{
+    Param pm;
+
+    deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
+    pm = (Param) paramtab->getnode(paramtab, "EPOCHSECONDS");
+    if (pm && (pm->flags & PM_SPECIAL)) {
+	pm->flags &= ~PM_READONLY;
+	unsetparam_pm(pm, 0, 1);
+    }
+    return 0;
+}
+
+/**/
+int
+finish_(UNUSED(Module m))
+{
+    return 0;
+}
diff --git a/Src/utils.c b/Src/utils.c
index 2bc48b6bd..3df4dd6f8 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -1852,7 +1852,7 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm)
 	     * Fix up some longer cases specially when we get to them.
 	     */
 	    if (ztrftimebuf(&bufsize, 2))
-		return 0;
+		return -1;
 	    switch (*fmt++) {
 	    case 'd':
 		*buf++ = '0' + tm->tm_mday / 10;
@@ -1910,12 +1910,12 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm)
 #ifndef HAVE_STRFTIME
 	    case 'a':
 		if (ztrftimebuf(&bufsize, strlen(astr[tm->tm_wday]) - 2))
-		    return 0;
+		    return -1;
 		strucpy(&buf, astr[tm->tm_wday]);
 		break;
 	    case 'b':
 		if (ztrftimebuf(&bufsize, strlen(estr[tm->tm_mon]) - 2))
-		    return 0;
+		    return -1;
 		strucpy(&buf, estr[tm->tm_mon]);
 		break;
 	    case 'p':
@@ -1950,7 +1950,7 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm)
 	    }
 	} else {
 	    if (ztrftimebuf(&bufsize, 1))
-		return 0;
+		return -1;
 	    *buf++ = *fmt++;
 	}
     *buf = '\0';