discuss@mandoc.bsd.lv
 help / color / mirror / Atom feed
* Mdocdate
@ 2015-11-12  9:25 Dag-Erling Smørgrav
  2015-11-12 21:31 ` Mdocdate Ingo Schwarze
  0 siblings, 1 reply; 11+ messages in thread
From: Dag-Erling Smørgrav @ 2015-11-12  9:25 UTC (permalink / raw)
  To: discuss

[-- Attachment #1: Type: text/plain, Size: 2327 bytes --]

The attached patch improves the Mdocdate code and updates the
documentation to match.

 - in a2time():

   Skip past "$Mdocdate: " if it exists instead of relying on the caller
   to specify it in the format string.

   Accept trailing text after a successful match (e.g. "$").

   If the first character after a successful match is 'Z', use UTC
   instead of the local time zone.

 - in time2a():

   Use a sufficiently large stack buffer and mandoc_strdup() instead of
   trying to guess at the correct length.

 - in mandoc_normdate():

   Fix several logic errors (inverted tests), add a test for the
   Subversion %d format, and simplify the code.

 - in the man page:

   Document how to use Mdocdate with Subversion.

Given the following test cases:

% cat tests
February 7 2036
February  7 2036
February 07 2036
February 7, 2036
February  7, 2036
February 07, 2036
Feb 7 2036
Feb  7 2036
Feb 07 2036
Feb 7, 2036
Feb  7, 2036
Feb 07, 2036
2036-02-07
2036-02-7
2036-2-07
2036-2-7
$Mdocdate: February 7 2036 $
$Mdocdate: 2036-02-07 06:28:16Z $

The current code (1.13.3) produces the following output:

% while read d ; do echo ".Dd $d" | mandoc | tail -1 ; done <tests
                                February 7 2036
                                February 7 2036
                               February 07 2036
                               February 7, 2036
                               February 7, 2036
                               February 7, 2036
                                  Feb 7 2036
                                  Feb 7 2036
                                  Feb 07 2036
                               February 7, 2036
                               February 7, 2036
                               February 7, 2036
                                  2036-02-07
                                   2036-02-7
                                   2036-2-07
                                   2036-2-7
                               February 7, 2036
                       $Mdocdate: 2036-02-07 06:28:16Z $

My version produces the same output for all cases:

% while read d ; do echo ".Dd $d" | ./mandoc | tail -1 ; done <tests | uniq
                               February 7, 2036

DES
--
Dag-Erling Smørgrav - des@des.no


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: mdocdate.diff --]
[-- Type: text/x-patch, Size: 2611 bytes --]

--- mandoc.c.orig
+++ mandoc.c
@@ -468,13 +468,15 @@
 	char		*pp;
 
 	memset(&tm, 0, sizeof(struct tm));
+	if (strncmp(p, "$" "Mdocdate: ", 11) == 0)
+		p += 11;
 
 	pp = NULL;
 #if HAVE_STRPTIME
 	pp = strptime(p, fmt, &tm);
 #endif
-	if (NULL != pp && '\0' == *pp) {
-		*t = mktime(&tm);
+	if (NULL != pp) {
+		*t = ('Z' == *p) ? timegm(&tm) : mktime(&tm);
 		return(1);
 	}
 
@@ -485,59 +487,32 @@
 time2a(time_t t)
 {
 	struct tm	*tm;
-	char		*buf, *p;
-	size_t		 ssz;
-	int		 isz;
+	char		 buf[32];
 
 	tm = localtime(&t);
-	if (tm == NULL)
-		return(NULL);
-
-	/*
-	 * Reserve space:
-	 * up to 9 characters for the month (September) + blank
-	 * up to 2 characters for the day + comma + blank
-	 * 4 characters for the year and a terminating '\0'
-	 */
-	p = buf = mandoc_malloc(10 + 4 + 4 + 1);
-
-	if (0 == (ssz = strftime(p, 10 + 1, "%B ", tm)))
-		goto fail;
-	p += (int)ssz;
-
-	if (-1 == (isz = snprintf(p, 4 + 1, "%d, ", tm->tm_mday)))
-		goto fail;
-	p += isz;
-
-	if (0 == strftime(p, 4 + 1, "%Y", tm))
-		goto fail;
-	return(buf);
-
-fail:
-	free(buf);
-	return(NULL);
+	if (tm == NULL || 0 == strftime(buf, sizeof buf, "%B %d, %Y", tm))
+		return (NULL);
+	return(mandoc_strdup(buf));
 }
 
 char *
 mandoc_normdate(struct mparse *parse, char *in, int ln, int pos)
 {
-	char		*out;
 	time_t		 t;
 
-	if (NULL == in || '\0' == *in ||
-	    0 == strcmp(in, "$" "Mdocdate$")) {
+	if (NULL == in || '\0' == *in || 0 == strcmp(in, "$" "Mdocdate$")) {
 		mandoc_msg(MANDOCERR_DATE_MISSING, parse, ln, pos, NULL);
-		time(&t);
+		return(time2a(time(NULL)));
 	}
-	else if (a2time(&t, "%Y-%m-%d", in))
-		t = 0;
-	else if (!a2time(&t, "$" "Mdocdate: %b %d %Y $", in) &&
-	    !a2time(&t, "%b %d, %Y", in)) {
+	else if (a2time(&t, "%Y-%m-%d %H:%M:%S", in) ||
+	    a2time(&t, "%Y-%m-%d", in) || a2time(&t, "%b %d, %Y", in) ||
+	    a2time(&t, "%b %d %Y", in)) {
+		return(time2a(t));
+	}
+	else {
 		mandoc_msg(MANDOCERR_DATE_BAD, parse, ln, pos, in);
-		t = 0;
+		return(mandoc_strdup(in));
 	}
-	out = t ? time2a(t) : NULL;
-	return(out ? out : mandoc_strdup(in));
 }
 
 int
--- mdoc.7.orig
+++ mdoc.7
@@ -1225,6 +1225,12 @@
 the special string
 .Dq $\&Mdocdate$
 can be given as an argument.
+The same effect can be achieved with
+.Xr svn 1
+by setting the
+.Va svn:keywords
+property to
+.Li Mdocdate=%d .
 .It
 The traditional, purely numeric
 .Xr man 7
@@ -1240,7 +1246,10 @@
 Examples:
 .Dl \&.Dd $\&Mdocdate$
 .Dl \&.Dd $\&Mdocdate: July 21 2007$
+.Dl \&.Dd $\&Mdocdate: 2007-07-21 12:34:56Z foo $
 .Dl \&.Dd July 21, 2007
+.Dl \&.Dd July 21  2007
+.Dl \&.Dd 2007-07-21
 .Pp
 See also
 .Sx \&Dt

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2015-11-23 20:47 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-12  9:25 Mdocdate Dag-Erling Smørgrav
2015-11-12 21:31 ` Mdocdate Ingo Schwarze
2015-11-12 23:06   ` Mdocdate Ingo Schwarze
2015-11-13  5:52   ` Mdocdate Dag-Erling Smørgrav
2015-11-14  1:22     ` Mdocdate Ingo Schwarze
2015-11-14 15:02       ` Mdocdate Steffen Nurpmeso
2015-11-15  1:51         ` Mdocdate Ingo Schwarze
2015-11-16 13:35           ` Mdocdate Steffen Nurpmeso
2015-11-17  9:12             ` Mdocdate Svyatoslav Mishyn
2015-11-17 10:35               ` Mdocdate Steffen Nurpmeso
2015-11-23 20:48   ` Mdocdate Michael Dexter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).