Download raw body.
mandoc lint flag ordering
With the patch to sort rsync.1 flags, I thought it might be nice if
mandoc -T lint warned on out of order flags. Is this a reasonable
lint to add?
If so, the below patch is a first stab that is not ready for commit.
Aside from style being off, there are a number of open questions.
How should state be kept between items? Is a static acceptable?
How should the last seen flag be reset between lists? The El macro
doesn't seem to be visited by mdoc_validate.
strcasecmp then strcmp works for alphabetic flags, but is probably wrong
for some symbols and multi-digit flags. Is there a better sort order?
Some man pages (e.g. grep, seq) list long only options after short
rather than interleaving long and short options. Should the lint ignore
those cases?
I doubt the child/next chasing to find the flag text is right.
The simple nit->head->child->child->string fails for cases like
apply.1: .It Fl Ns Ar #
pkill.1: .It Fl Ar signal
I don't know what to do for cases like indent.1: .It Fl \&bc , nbc
diff --git mandoc.h mandoc.h
index 1349fc033de..5ba234cd21e 100644
--- mandoc.h
+++ mandoc.h
@@ -69,6 +69,7 @@ enum mandocerr {
MANDOCERR_BX, /* consider using OS macro: macro */
MANDOCERR_ER_ORDER, /* errnos out of order: Er ... */
MANDOCERR_ER_REP, /* duplicate errno: Er ... */
+ MANDOCERR_FL_ORDER, /* flags out of order: ... after ... */
MANDOCERR_XR_BAD, /* referenced manual not found: Xr name sec */
MANDOCERR_DELIM, /* trailing delimiter: macro ... */
MANDOCERR_DELIM_NB, /* no blank before trailing delimiter: macro ... */
diff --git mandoc_msg.c mandoc_msg.c
index 08dc63cf7ad..72101436459 100644
--- mandoc_msg.c
+++ mandoc_msg.c
@@ -66,6 +66,7 @@ static const char *const type_message[MANDOCERR_MAX] = {
"consider using OS macro",
"errnos out of order",
"duplicate errno",
+ "flags out of order",
"referenced manual not found",
"trailing delimiter",
"no blank before trailing delimiter",
diff --git mdoc_validate.c mdoc_validate.c
index 2a7b29ecc14..d07baf1218b 100644
--- mdoc_validate.c
+++ mdoc_validate.c
@@ -293,6 +293,7 @@ static const char * const secnames[SEC__MAX] = {
};
static int fn_prio = TAG_STRONG;
+static char *last_flag = NULL;
/* Validate the subtree rooted at mdoc->last. */
@@ -310,6 +311,10 @@ mdoc_validate(struct roff_man *mdoc)
n = mdoc->last;
switch (n->tok) {
+ case MDOC_Bl:
+ free(last_flag);
+ last_flag = NULL;
+ break;
case MDOC_Lp:
n->tok = MDOC_Pp;
break;
@@ -1714,8 +1719,9 @@ post_xx(POST_ARGS)
static void
post_it(POST_ARGS)
{
- struct roff_node *nbl, *nit, *nch;
- int i, cols;
+ struct roff_node *nbl, *nit, *nch, *np;
+ const char *flag_str;
+ int i, cmp, cols;
enum mdoc_list lt;
post_prevpar(mdoc);
@@ -1737,6 +1743,32 @@ post_it(POST_ARGS)
mandoc_msg(MANDOCERR_IT_NOHEAD,
nit->line, nit->pos, "Bl -%s It",
mdoc_argnames[nbl->args->argv[0].arg]);
+ else if (nit->head->child->tok == MDOC_Fl) {
+ np = nit->head->child;
+ while (np->string == NULL) {
+ if (np->child != NULL)
+ np = np->child;
+ else if (np->next != NULL)
+ np = np->next;
+ else
+ break;
+
+ }
+ flag_str = np->string;
+ if (flag_str == NULL)
+ flag_str = "";
+ if (flag_str[0] == '-')
+ flag_str++;
+ if (last_flag != NULL) {
+ cmp = strcasecmp(last_flag, flag_str);
+ if (cmp > 0 ||
+ (cmp == 0 && strcmp(last_flag, flag_str) > 0))
+ mandoc_msg(MANDOCERR_FL_ORDER, np->line,
+ np->pos, "%s after %s", flag_str, last_flag);
+ free(last_flag);
+ }
+ last_flag = mandoc_strdup(flag_str);
+ }
break;
case LIST_bullet:
case LIST_dash:
mandoc lint flag ordering