summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2009-11-02 06:22:44 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2009-11-02 06:22:44 +0000
commitd612b79e06155082b6342af68940fa671568998d (patch)
treec823b0d3420b6f66b76bf2249667aab2ed2ca0c2
parent768ae2f18e90273f3a363fe0374c8dc61ecff26b (diff)
downloadmandoc-d612b79e06155082b6342af68940fa671568998d.tar.gz
Added mandoc_a2time() for proper date conversion.
Fitted TH and Dd handlers to use mandoc_a2time(). Documented date syntax for -man, fixed documentation for -mdoc.
-rw-r--r--html.c3
-rw-r--r--libmandoc.h5
-rw-r--r--man.756
-rw-r--r--man_action.c43
-rw-r--r--man_validate.c2
-rw-r--r--mandoc.c62
-rw-r--r--mdoc.729
-rw-r--r--mdoc_action.c7
-rw-r--r--mdoc_strings.c26
-rw-r--r--mdoc_validate.c4
10 files changed, 135 insertions, 102 deletions
diff --git a/html.c b/html.c
index 44988858..094cc86e 100644
--- a/html.c
+++ b/html.c
@@ -322,7 +322,8 @@ print_encode(struct html *h, const char *p)
sz = strcspn(p, "\\<>&");
fwrite(p, 1, sz, stdout);
- p += (int)sz;
+ p += /* LINTED */
+ sz;
if ('\\' == *p) {
print_escape(h, &p);
diff --git a/libmandoc.h b/libmandoc.h
index 5f9ad688..dc91a200 100644
--- a/libmandoc.h
+++ b/libmandoc.h
@@ -24,6 +24,11 @@ void *mandoc_calloc(size_t, size_t);
char *mandoc_strdup(const char *);
void *mandoc_malloc(size_t);
void *mandoc_realloc(void *, size_t);
+time_t mandoc_a2time(int, const char *);
+#define MTIME_CANONICAL (1 << 0)
+#define MTIME_REDUCED (1 << 1)
+#define MTIME_MDOCDATE (1 << 2)
+#define MTIME_ISO_8601 (1 << 3)
__END_DECLS
diff --git a/man.7 b/man.7
index fedc0524..95d20d0f 100644
--- a/man.7
+++ b/man.7
@@ -119,6 +119,23 @@ from input. These are later re-added, if applicable, by a front-end
utility such as
.Xr mandoc 1 .
.
+.Ss Dates
+The
+.Sx \&TH
+macro is the only
+.Nm
+macro that requires a date. The form for this date is the ISO-8601
+standard
+.Cm YYYY-MM-DD .
+.
+.Ss Scaling Widths
+Many macros support scaled widths for their arguments, such as
+stipulating a two-inch list indentation with the following:
+.Bd -literal -offset indent
+\&.Bl -tag -width 2i
+.Ed
+.
+.
.Ss Scaling Widths
Many macros support scaled widths for their arguments, such as
stipulating a two-inch paragraph indentation with the following:
@@ -202,7 +219,7 @@ Beyond
at least one macro or text node must appear in the document. Documents
are generally structured as follows:
.Bd -literal -offset indent
-\&.TH FOO 1 "13 Aug 2009"
+\&.TH FOO 1 2009-10-10
\&.
\&.SH NAME
\efBfoo\efR \e(en a description goes here
@@ -614,26 +631,29 @@ subsequent sub-section, section, or end of file. The paragraph
left-margin width is re-set to the default.
.Ss \&TH
Sets the title of the manual page with the following syntax:
-.Bd -literal -offset indent
-\&.TH title section [date [source [volume]]]
-.Ed
-.
.Pp
-At least the
-.Va title
-and
-.Va section
+.D1 \. Ns Sx \&TH No Cm title msec Op Cm date Op Cm src Op Cm vol
+.Pp
+At least the upper-case document title
+.Cm title
+and numeric manual section
+.Cm msec
arguments must be provided. The
-.Va date
-argument should be formatted as
-.Qq %b [%d] %Y
-format, described in
-.Xr strptime 3 .
-The
-.Va source
+.Cm date
+argument should be formatted as described in
+.Sx Dates :
+if it does not conform, the current date is used instead. The
+.Cm src
string specifies the organisation providing the utility. The
-.Va volume
-replaces the default rendered volume as dictated by the manual section.
+.Cm vol
+string replaces the default rendered volume, which is dictated by the
+manual section.
+.Pp
+Examples:
+.Bd -literal -offset indent
+\&.TH CVS 5 "1992-02-12" GNU
+.Ed
+.
.Ss \&TP
Begin a paragraph where the head, if exceeding the indentation width, is
followed by a newline; if not, the body follows on the same line after a
diff --git a/man_action.c b/man_action.c
index 19e11e39..aa56dda6 100644
--- a/man_action.c
+++ b/man_action.c
@@ -66,11 +66,6 @@ const struct actions man_actions[MAN_MAX] = {
{ NULL }, /* PD */
};
-static time_t man_atotime(const char *);
-#ifdef __linux__
-extern char *strptime(const char *, const char *, struct tm *);
-#endif
-
int
man_action_post(struct man *m)
@@ -156,13 +151,18 @@ post_TH(struct man *m)
/* TITLE MSEC ->DATE<- SOURCE VOL */
- if (NULL == (n = n->next))
- m->meta.date = time(NULL);
- else if (0 == (m->meta.date = man_atotime(n->string))) {
- if ( ! man_nwarn(m, n, WDATE))
- return(0);
+ n = n->next;
+ if (n) {
+ m->meta.date = mandoc_a2time
+ (MTIME_ISO_8601, n->string);
+
+ if (0 == m->meta.date) {
+ if ( ! man_nwarn(m, n, WDATE))
+ return(0);
+ m->meta.date = time(NULL);
+ }
+ } else
m->meta.date = time(NULL);
- }
/* TITLE MSEC DATE ->SOURCE<- VOL */
@@ -195,24 +195,3 @@ post_TH(struct man *m)
man_node_freelist(n);
return(1);
}
-
-
-static time_t
-man_atotime(const char *p)
-{
- struct tm tm;
- char *pp;
-
- memset(&tm, 0, sizeof(struct tm));
-
- if ((pp = strptime(p, "%b %d %Y", &tm)) && 0 == *pp)
- return(mktime(&tm));
- if ((pp = strptime(p, "%d %b %Y", &tm)) && 0 == *pp)
- return(mktime(&tm));
- if ((pp = strptime(p, "%b %d, %Y", &tm)) && 0 == *pp)
- return(mktime(&tm));
- if ((pp = strptime(p, "%b %Y", &tm)) && 0 == *pp)
- return(mktime(&tm));
-
- return(0);
-}
diff --git a/man_validate.c b/man_validate.c
index 85a6f387..3c5944fa 100644
--- a/man_validate.c
+++ b/man_validate.c
@@ -56,7 +56,7 @@ static v_check pres_bline[] = { check_bline, NULL };
static const struct man_valid man_valids[MAN_MAX] = {
{ pres_bline, posts_eq0 }, /* br */
- { pres_bline, posts_ge2_le5 }, /* TH */
+ { pres_bline, posts_ge2_le5 }, /* TH */ /* FIXME: make sure capitalised. */
{ pres_bline, posts_sec }, /* SH */
{ pres_bline, posts_sec }, /* SS */
{ pres_bline, posts_par }, /* TP */
diff --git a/mandoc.c b/mandoc.c
index b9d554af..1099ca4d 100644
--- a/mandoc.c
+++ b/mandoc.c
@@ -14,6 +14,10 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#if defined(__linux__) || defined(__MINT__)
+# define _GNU_SOURCE /* strptime() */
+#endif
+
#include <sys/types.h>
#include <assert.h>
@@ -21,9 +25,13 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <time.h>
#include "libmandoc.h"
+static int a2time(time_t *, const char *, const char *);
+
+
int
mandoc_special(const char *p)
{
@@ -163,3 +171,57 @@ mandoc_strdup(const char *ptr)
return(p);
}
+
+
+static int
+a2time(time_t *t, const char *fmt, const char *p)
+{
+ struct tm tm;
+ char *pp;
+
+ memset(&tm, 0, sizeof(struct tm));
+
+ pp = strptime(p, fmt, &tm);
+ if (NULL != pp && '\0' == *pp) {
+ *t = mktime(&tm);
+ return(1);
+ }
+
+ return(0);
+}
+
+
+/*
+ * Convert from a manual date string (see mdoc(7) and man(7)) into a
+ * date according to the stipulated date type.
+ */
+time_t
+mandoc_a2time(int flags, const char *p)
+{
+ time_t t;
+
+ if (MTIME_MDOCDATE & flags) {
+ if (0 == strcmp(p, "$" "Mdocdate$"))
+ return(time(NULL));
+ if (a2time(&t, "$" "Mdocdate: %b %d %Y $", p))
+ return(t);
+ }
+
+ if (MTIME_CANONICAL & flags || MTIME_REDUCED & flags)
+ if (a2time(&t, "%b %d, %Y", p))
+ return(t);
+
+ if (MTIME_ISO_8601 & flags)
+ if (a2time(&t, "%Y-%m-%d", p))
+ return(t);
+
+ if (MTIME_REDUCED & flags) {
+ if (a2time(&t, "%d, %Y", p))
+ return(t);
+ if (a2time(&t, "%Y", p))
+ return(t);
+ }
+
+ return(0);
+}
+
diff --git a/mdoc.7 b/mdoc.7
index 7e676092..eeed1f16 100644
--- a/mdoc.7
+++ b/mdoc.7
@@ -212,9 +212,8 @@ In free-form mode, quotes are regarded as opaque text.
.Ss Dates
There are several macros in
.Nm
-that require a date argument. The
-.Em canonical form
-for dates is the American format:
+that require a date argument. The canonical form for dates is the
+American format:
.Pp
.D1 Cm Month Day , Year
.Pp
@@ -226,26 +225,16 @@ value is the full month name. The
.Cm Year
value is the full four-digit year.
.Pp
-The
-.Em non-canonical form
-is the same as the canonical form, but without the comma between the
-.Cm Day
-and
-.Cm Year
-field.
+Reduced form dates are broken-down canonical form dates:
.Pp
-Lastly,
-.Em reduced form
-dates range from only a
-.Cm Year
-to the full canonical or non-canonical form.
+.D1 Cm Month , Year
+.D1 Cm Year
.Pp
Some examples of valid dates follow:
.Pp
.D1 "May, 2009" Pq reduced form
.D1 "2009" Pq reduced form
.D1 "May 20, 2009" Pq canonical form
-.D1 "May 20 2009" Pq non-canonical form
.
.Ss Scaling Widths
Many macros support scaled widths for their arguments, such as
@@ -710,10 +699,9 @@ this macro is not implemented in
.Ss \&%D
Publication date of an
.Sx \&Rs
-block. This should follow the reduced syntax for
+block. This should follow the reduced or canonical form syntax
+described in
.Sx Dates .
-Canonical or non-canonical form is not necessary since publications are
-often referenced only by year, or month and year.
.
.Ss \&%I
Publisher or issuer name of an
@@ -1152,9 +1140,10 @@ The
field may be either
.Ar $\&Mdocdate$ ,
which signifies the current manual revision date dictated by
-.Xr cvs 1
+.Xr cvs 1 ,
or instead a valid canonical date as specified by
.Sx Dates .
+If a date does not conform, the current date is used instead.
.Pp
Examples:
.Bd -literal -offset indent
diff --git a/mdoc_action.c b/mdoc_action.c
index d41f5073..3cd0332c 100644
--- a/mdoc_action.c
+++ b/mdoc_action.c
@@ -818,8 +818,7 @@ post_ar(POST_ARGS)
/*
- * Parse the date field in `Dd', primarily through mdoc_atotime().
- * FIXME: push mdoc_atotime() into here.
+ * Parse the date field in `Dd'.
*/
static int
post_dd(POST_ARGS)
@@ -829,7 +828,9 @@ post_dd(POST_ARGS)
if ( ! concat(m, buf, n->child, DATESIZ))
return(0);
- m->meta.date = mdoc_atotime(buf);
+ m->meta.date = mandoc_a2time
+ (MTIME_MDOCDATE | MTIME_CANONICAL, buf);
+
if (0 == m->meta.date) {
if ( ! mdoc_nwarn(m, n, EBADDATE))
return(0);
diff --git a/mdoc_strings.c b/mdoc_strings.c
index 1962a6ca..44413cbc 100644
--- a/mdoc_strings.c
+++ b/mdoc_strings.c
@@ -56,10 +56,6 @@ static const struct mdoc_secname secnames[SECNAME_MAX] = {
{ "SECURITY CONSIDERATIONS", SEC_SECURITY }
};
-#ifdef __linux__
-extern char *strptime(const char *, const char *, struct tm *);
-#endif
-
int
mdoc_iscdelim(char p)
@@ -125,28 +121,6 @@ mdoc_atosec(const char *p)
}
-time_t
-mdoc_atotime(const char *p)
-{
- struct tm tm;
- char *pp;
-
- memset(&tm, 0, sizeof(struct tm));
-
- if (0 == strcmp(p, "$" "Mdocdate$"))
- return(time(NULL));
- if ((pp = strptime(p, "$" "Mdocdate: %b %d %Y $", &tm)) && 0 == *pp)
- return(mktime(&tm));
- /* XXX - this matches "June 1999", which is wrong. */
- if ((pp = strptime(p, "%b %d %Y", &tm)) && 0 == *pp)
- return(mktime(&tm));
- if ((pp = strptime(p, "%b %d, %Y", &tm)) && 0 == *pp)
- return(mktime(&tm));
-
- return(0);
-}
-
-
/* FIXME: move this into an editable .in file. */
size_t
mdoc_macro2len(int macro)
diff --git a/mdoc_validate.c b/mdoc_validate.c
index 088bb09a..4a4b834b 100644
--- a/mdoc_validate.c
+++ b/mdoc_validate.c
@@ -194,7 +194,7 @@ const struct valids mdoc_valids[MDOC_MAX] = {
{ NULL, posts_xr }, /* Xr */
{ NULL, posts_text }, /* %A */
{ NULL, posts_text }, /* %B */ /* FIXME: can be used outside Rs/Re. */
- { NULL, posts_text }, /* %D */
+ { NULL, posts_text }, /* %D */ /* FIXME: check date with mandoc_a2time(). */
{ NULL, posts_text }, /* %I */
{ NULL, posts_text }, /* %J */
{ NULL, posts_text }, /* %N */
@@ -808,6 +808,8 @@ static int
pre_dt(PRE_ARGS)
{
+ /* FIXME: make sure is capitalised. */
+
if (0 == mdoc->meta.date || mdoc->meta.os)
if ( ! mdoc_nwarn(mdoc, n, EPROLOOO))
return(0);