From: Ingo Schwarze <schwarze@usta.de>
To: tech@mdocml.bsd.lv
Subject: [PATCH] .nr for mdoc(7)
Date: Wed, 16 Jun 2010 04:11:28 +0200 [thread overview]
Message-ID: <20100616021128.GA14898@iris.usta.de> (raw)
Hi,
while waiting for more feedback on my badly nested blocks patch,
i have written another patch to pour more shit soup over Kristaps'
beautiful abstract syntax tree. Let's see whether it works as
a fertilizer. :)
The point is, groff knows two macros that switch mdoc(7)
into SYNOPSIS mode (with all the consequences):
.Sh SYNOPSIS
and
.Sh MY_FANCY_CUSTOM_SECTION
.nr nS 1
Actually, groff implements the former in terms of the latter,
but the latter is also used directly, in particular in large
numbers of kernel manuals in OpenBSD.
I see no real alternative to implementing .nr.
I is not an option to rename all those sections to SYNOPSIS,
because manuals having ten SYNOPSIS sections look bad,
nor to move all the .Ft/.Fn combos to the SYNOPSIS.
These manuals really require SYNOPSIS mode in custom sections.
Now, of course, .nr is the low-level generic "set numeric register"
roff instruction. But it can not be handled by Kristaps'
roff preprocessor; instead, it must be handled inside the
syntax tree: It only affects nodes following it, and only
up to the next .nr nS instruction or up to the end of the .Sh.
So, it can't be fully parsed without knowing about the high-level
mdoc(7) language, and its effects also take place on the high
level.
Here are a few more related observations:
* The whole concept of .nr does not agree very well with the
concept of an AST. Rather, it is all about keeping global
state in a linear flow of tokens. Whence the shit soup.
* So far, i only implemented .nr for mdoc(7) and not for man(7),
just because i do not know of any practical use in man(7).
Extending the concept to man(7) would not be difficult in case
it turns out to be needed: The roff_reg bits are ready to
be shared.
* The .nr macro needs to take effect both at once, while parsing,
because some parser functions behave differently in the
SYNOPSIS, and later while rendering, because modifying the
rendering is what the SYNOPSIS mode is ultimately aiming at.
Thus, the same code is needed both in mdoc_action and mdoc_term.
For that code, i provide an interface in roff_mdoc.h and
an implementation in roff_mdoc.c, such that it can be called
from both places.
* As the point is to let .nr nS switch SYNOPSIS mode,
all tests for SEC_SYNOPSIS must be moved to test for
roff_nr_geti(ROFF_nr_nS) instead. Fortunately, these
tests are not that numerous.
* There are three more .nr n* switches for other sections,
working in exactly the same way as nS. To keep the patch
small, i have not moved those yet, but i expect that move
to be very simple.
* I have not yet moved mdoc_html to use the roff_mdoc functions,
but i expect that switch to be mechanical.
* The function roff_mdoc_nr() really requires strtonum(3).
Since range checking is required there, implementing that
code in terms of strtol(3) would essentially amount to
copying the strtonum(3) source code into roff_mdoc_nr(),
roughly doubling the size of the function and badly
obfuscating it. I guess we need to handle strtonum(3)
in the same way as strlcpy(3) and strlcat(3), but didn't
write the compat glue yet: So far, this patch is based
on the OpenBSD tree.
* The roff_reg code could evolve into a full-fleshed roff
register implementation including user-defined registers,
in case it turns out we need that. So far, the roff_reg.c
implementation only supports predefined registers, but i
designed the roff_reg.h interface such that the interface
does not need to be changed in case we want user-defined
registers later.
* In groff, the main use of user-defined registers is in .if;
in mandoc, that won't be of much use, because the effects will
be limited to preprocessor filtering, and high-level macros can't
change the value of registers on the preprocessor level.
But i'm not going to worry about that architectural inconvenience
right now.
Thoughts?
Yours,
Ingo
Index: Makefile
===================================================================
RCS file: /cvs/src/usr.bin/mandoc/Makefile,v
retrieving revision 1.40
diff -u -p -r1.40 Makefile
--- Makefile 10 Jun 2010 22:50:10 -0000 1.40
+++ Makefile 16 Jun 2010 00:45:48 -0000
@@ -10,7 +10,7 @@ CFLAGS+=-W -Wall -Wstrict-prototypes
CFLAGS+=-Wno-unused-parameter
.endif
-SRCS= roff.c mandoc.c
+SRCS= roff.c roff_reg.c roff_mdoc.c mandoc.c
SRCS+= mdoc_macro.c mdoc.c mdoc_hash.c mdoc_strings.c \
mdoc_argv.c mdoc_validate.c mdoc_action.c lib.c att.c \
arch.c vol.c msec.c st.c
Index: mdoc.c
===================================================================
RCS file: /cvs/src/usr.bin/mandoc/mdoc.c,v
retrieving revision 1.56
diff -u -p -r1.56 mdoc.c
--- mdoc.c 6 Jun 2010 20:30:08 -0000 1.56
+++ mdoc.c 16 Jun 2010 00:45:49 -0000
@@ -65,7 +65,7 @@ const char *const __mdoc_macronames[MDOC
/* LINTED */
"Dx", "%Q", "br", "sp",
/* LINTED */
- "%U", "Ta"
+ "%U", "Ta", "nr"
};
const char *const __mdoc_argnames[MDOC_ARG_MAX] = {
Index: mdoc.h
===================================================================
RCS file: /cvs/src/usr.bin/mandoc/mdoc.h,v
retrieving revision 1.27
diff -u -p -r1.27 mdoc.h
--- mdoc.h 6 Jun 2010 20:30:08 -0000 1.27
+++ mdoc.h 16 Jun 2010 00:45:49 -0000
@@ -150,6 +150,7 @@ enum mdoct {
MDOC_sp,
MDOC__U,
MDOC_Ta,
+ MDOC_nr,
MDOC_MAX
};
Index: mdoc_action.c
===================================================================
RCS file: /cvs/src/usr.bin/mandoc/mdoc_action.c,v
retrieving revision 1.40
diff -u -p -r1.40 mdoc_action.c
--- mdoc_action.c 6 Jun 2010 20:30:08 -0000 1.40
+++ mdoc_action.c 16 Jun 2010 00:45:51 -0000
@@ -27,6 +27,8 @@
#include "mandoc.h"
#include "libmdoc.h"
#include "libmandoc.h"
+#include "roff_reg.h"
+#include "roff_mdoc.h"
#define POST_ARGS struct mdoc *m, struct mdoc_node *n
#define PRE_ARGS struct mdoc *m, struct mdoc_node *n
@@ -55,6 +57,7 @@ static int post_dt(POST_ARGS);
static int post_lb(POST_ARGS);
static int post_li(POST_ARGS);
static int post_nm(POST_ARGS);
+static int post_nr(POST_ARGS);
static int post_os(POST_ARGS);
static int post_pa(POST_ARGS);
static int post_prol(POST_ARGS);
@@ -191,6 +194,7 @@ static const struct actions mdoc_actions
{ NULL, NULL }, /* sp */
{ NULL, NULL }, /* %U */
{ NULL, NULL }, /* Ta */
+ { NULL, post_nr }, /* nr */
};
#define RSORD_MAX 14
@@ -450,6 +454,9 @@ post_sh(POST_ARGS)
if (SEC_NONE == m->lastnamed || SEC_CUSTOM != sec)
m->lastnamed = sec;
+ /* Set or clear the roff section registers. */
+ roff_mdoc_sh(n);
+
/* Some sections only live in certain manual sections. */
switch ((m->lastsec = sec)) {
@@ -1063,5 +1070,15 @@ post_rs(POST_ARGS)
nn->next = n->body->child;
n->body->child = nn;
}
+ return(1);
+}
+
+
+/* ARGSUSED */
+static int
+post_nr(POST_ARGS)
+{
+
+ roff_mdoc_nr(n);
return(1);
}
Index: mdoc_argv.c
===================================================================
RCS file: /cvs/src/usr.bin/mandoc/mdoc_argv.c,v
retrieving revision 1.30
diff -u -p -r1.30 mdoc_argv.c
--- mdoc_argv.c 6 Jun 2010 20:30:08 -0000 1.30
+++ mdoc_argv.c 16 Jun 2010 00:45:54 -0000
@@ -207,6 +207,7 @@ static int mdoc_argflags[MDOC_MAX] = {
0, /* sp */
0, /* %U */
0, /* Ta */
+ 0, /* nr */
};
Index: mdoc_html.c
===================================================================
RCS file: /cvs/src/usr.bin/mandoc/mdoc_html.c,v
retrieving revision 1.21
diff -u -p -r1.21 mdoc_html.c
--- mdoc_html.c 8 Jun 2010 00:11:47 -0000 1.21
+++ mdoc_html.c 16 Jun 2010 00:45:55 -0000
@@ -254,6 +254,7 @@ static const struct htmlmdoc mdocs[MDOC_
{mdoc_sp_pre, NULL}, /* sp */
{mdoc__x_pre, mdoc__x_post}, /* %U */
{NULL, NULL}, /* Ta */
+ {NULL, NULL}, /* nr */
};
Index: mdoc_macro.c
===================================================================
RCS file: /cvs/src/usr.bin/mandoc/mdoc_macro.c,v
retrieving revision 1.46
diff -u -p -r1.46 mdoc_macro.c
--- mdoc_macro.c 6 Jun 2010 20:30:08 -0000 1.46
+++ mdoc_macro.c 16 Jun 2010 00:45:56 -0000
@@ -24,6 +24,7 @@
#include "mandoc.h"
#include "libmdoc.h"
#include "libmandoc.h"
+#include "roff_reg.h"
enum rew {
REWIND_REWIND,
@@ -183,6 +184,7 @@ const struct mdoc_macro __mdoc_macros[MD
{ in_line_eoln, 0 }, /* sp */
{ in_line_eoln, 0 }, /* %U */
{ phrase_ta, MDOC_CALLABLE | MDOC_PARSED }, /* Ta */
+ { in_line_eoln, MDOC_IGNDELIM }, /* nr */
};
const struct mdoc_macro * const mdoc_macros = __mdoc_macros;
@@ -1600,7 +1602,7 @@ ctx_synopsis(MACRO_PROT_ARGS)
nl = MDOC_NEWLINE & m->flags;
/* If we're not in the SYNOPSIS, go straight to in-line. */
- if (SEC_SYNOPSIS != m->lastsec)
+ if (0 == roff_nr_geti(ROFF_nr_nS))
return(in_line(m, tok, line, ppos, pos, buf));
/* If we're a nested call, same place. */
Index: mdoc_term.c
===================================================================
RCS file: /cvs/src/usr.bin/mandoc/mdoc_term.c,v
retrieving revision 1.87
diff -u -p -r1.87 mdoc_term.c
--- mdoc_term.c 10 Jun 2010 22:50:10 -0000 1.87
+++ mdoc_term.c 16 Jun 2010 00:45:59 -0000
@@ -29,6 +30,8 @@
#include "mdoc.h"
#include "chars.h"
#include "main.h"
+#include "roff_reg.h"
+#include "roff_mdoc.h"
#define INDENT 5
#define HALFINDENT 3
@@ -115,6 +118,7 @@ static int termp_li_pre(DECL_ARGS);
static int termp_lk_pre(DECL_ARGS);
static int termp_nd_pre(DECL_ARGS);
static int termp_nm_pre(DECL_ARGS);
+static int termp_nr_pre(DECL_ARGS);
static int termp_ns_pre(DECL_ARGS);
static int termp_op_pre(DECL_ARGS);
static int termp_pf_pre(DECL_ARGS);
@@ -256,6 +260,7 @@ static const struct termact termacts[MDO
{ termp_sp_pre, NULL }, /* sp */
{ termp_under_pre, termp____post }, /* %U */
{ NULL, NULL }, /* Ta */
+ { termp_nr_pre, NULL }, /* nr */
};
@@ -1324,7 +1329,7 @@ synopsis_pre(struct termp *p, const stru
* Obviously, if we're not in a SYNOPSIS or no prior macros
* exist, do nothing.
*/
- if (NULL == n->prev || SEC_SYNOPSIS != n->sec)
+ if (NULL == n->prev || 0 == roff_nr_geti(ROFF_nr_nS))
return;
/*
@@ -1430,6 +1435,10 @@ termp_sh_pre(DECL_ARGS)
default:
break;
}
+
+ /* Set or clear the roff section registers. */
+ roff_mdoc_sh(n);
+
return(1);
}
@@ -1589,7 +1598,7 @@ termp_fn_pre(DECL_ARGS)
term_word(p, ")");
- if (SEC_SYNOPSIS == n->sec)
+ if (roff_nr_geti(ROFF_nr_nS))
term_word(p, ";");
return(0);
@@ -1874,7 +1883,7 @@ termp_in_pre(DECL_ARGS)
synopsis_pre(p, n);
- if (SEC_SYNOPSIS == n->sec && MDOC_LINE & n->flags) {
+ if (roff_nr_geti(ROFF_nr_nS) && MDOC_LINE & n->flags) {
term_fontpush(p, TERMFONT_BOLD);
term_word(p, "#include");
term_word(p, "<");
@@ -1892,14 +1901,15 @@ termp_in_pre(DECL_ARGS)
static void
termp_in_post(DECL_ARGS)
{
+ int synopsis = roff_nr_geti(ROFF_nr_nS);
- if (SEC_SYNOPSIS == n->sec)
+ if (synopsis)
term_fontpush(p, TERMFONT_BOLD);
p->flags |= TERMP_NOSPACE;
term_word(p, ">");
- if (SEC_SYNOPSIS == n->sec)
+ if (synopsis)
term_fontpop(p);
}
@@ -2041,7 +2051,7 @@ termp_fo_post(DECL_ARGS)
p->flags |= TERMP_NOSPACE;
term_word(p, ")");
- if (SEC_SYNOPSIS == n->sec) {
+ if (roff_nr_geti(ROFF_nr_nS)) {
p->flags |= TERMP_NOSPACE;
term_word(p, ";");
}
@@ -2154,6 +2164,16 @@ termp_lk_pre(DECL_ARGS)
term_word(p, nn->string);
term_fontpop(p);
+ return(0);
+}
+
+
+/* ARGSUSED */
+static int
+termp_nr_pre(DECL_ARGS)
+{
+
+ roff_mdoc_nr(n);
return(0);
}
Index: mdoc_validate.c
===================================================================
RCS file: /cvs/src/usr.bin/mandoc/mdoc_validate.c,v
retrieving revision 1.60
diff -u -p -r1.60 mdoc_validate.c
--- mdoc_validate.c 6 Jun 2010 20:30:08 -0000 1.60
+++ mdoc_validate.c 16 Jun 2010 00:46:00 -0000
@@ -68,6 +68,8 @@ static int eerr_eq1(POST_ARGS);
static int eerr_ge1(POST_ARGS);
static int eerr_le1(POST_ARGS);
static int ewarn_ge1(POST_ARGS);
+static int ewarn_ge2(POST_ARGS);
+static int ewarn_le3(POST_ARGS);
static int herr_eq0(POST_ARGS);
static int herr_ge1(POST_ARGS);
static int hwarn_eq1(POST_ARGS);
@@ -116,6 +118,7 @@ static v_post posts_it[] = { post_it, N
static v_post posts_lb[] = { eerr_eq1, post_lb, NULL };
static v_post posts_nd[] = { berr_ge1, NULL };
static v_post posts_nm[] = { post_nm, NULL };
+static v_post posts_nr[] = { ewarn_ge2, ewarn_le3, NULL };
static v_post posts_notext[] = { eerr_eq0, NULL };
static v_post posts_rs[] = { berr_ge1, herr_eq0, post_rs, NULL };
static v_post posts_sh[] = { herr_ge1, bwarn_ge1, post_sh, NULL };
@@ -265,6 +268,7 @@ const struct valids mdoc_valids[MDOC_MAX
{ NULL, posts_sp }, /* sp */
{ NULL, posts_text1 }, /* %U */
{ NULL, NULL }, /* Ta */
+ { NULL, posts_nr }, /* nr */
};
@@ -392,6 +396,8 @@ CHECK_CHILD_DEFN(warn, lt, <) /* warn_
CHECK_BODY_DEFN(ge1, warn, warn_child_gt, 0) /* bwarn_ge1() */
CHECK_BODY_DEFN(ge1, err, err_child_gt, 0) /* berr_ge1() */
CHECK_ELEM_DEFN(ge1, warn, warn_child_gt, 0) /* ewarn_ge1() */
+CHECK_ELEM_DEFN(ge2, warn, warn_child_gt, 1) /* ewarn_ge2() */
+CHECK_ELEM_DEFN(le3, warn, warn_child_lt, 4) /* ewarn_le3() */
CHECK_ELEM_DEFN(eq1, err, err_child_eq, 1) /* eerr_eq1() */
CHECK_ELEM_DEFN(le1, err, err_child_lt, 2) /* eerr_le1() */
CHECK_ELEM_DEFN(eq0, err, err_child_eq, 0) /* eerr_eq0() */
Index: roff_mdoc.c
===================================================================
RCS file: roff_mdoc.c
diff -N roff_mdoc.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ roff_mdoc.c 16 Jun 2010 00:46:00 -0000
@@ -0,0 +1,58 @@
+/* $Id: roff.c,v 1.4 2010/06/06 20:30:08 schwarze Exp $ */
+/*
+ * Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/limits.h>
+#include <stdlib.h>
+
+#include "mandoc.h"
+#include "mdoc.h"
+#include "roff_reg.h"
+#include "roff_mdoc.h"
+
+
+int
+roff_mdoc_nr(const struct mdoc_node *n)
+{
+ struct mdoc_node *nn;
+ const char *ep;
+ char *name;
+ int i;
+
+ /* Ignore unspecified registers. */
+ if (NULL == (nn = n->child))
+ return 0;
+ name = nn->string;
+
+ /* Ignore unspecified values. */
+ if (NULL == (nn = nn->next))
+ return 0;
+
+ /* Ignore invalid and out-of-range values. */
+ i = strtonum(nn->string, INT_MIN, INT_MAX, &ep);
+ if (ep)
+ return 0;
+
+ /* Ignore invalid registers. */
+ return roff_nr_setn(name, i);
+}
+
+
+int
+roff_mdoc_sh(const struct mdoc_node *n)
+{
+ return roff_nr_seti(ROFF_nr_nS, SEC_SYNOPSIS == n->sec ? 1 : 0);
+}
Index: roff_mdoc.h
===================================================================
RCS file: roff_mdoc.h
diff -N roff_mdoc.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ roff_mdoc.h 16 Jun 2010 00:46:00 -0000
@@ -0,0 +1,27 @@
+/* $Id: roff.h,v 1.2 2010/05/20 00:58:02 schwarze Exp $ */
+/*
+ * Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef ROFF_MDOC_H
+#define ROFF_MDOC_H
+
+__BEGIN_DECLS
+
+int roff_mdoc_nr(const struct mdoc_node *);
+int roff_mdoc_sh(const struct mdoc_node *);
+
+__END_DECLS
+
+#endif /*!ROFF_MDOC_H*/
Index: roff_reg.c
===================================================================
RCS file: roff_reg.c
diff -N roff_reg.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ roff_reg.c 16 Jun 2010 00:46:00 -0000
@@ -0,0 +1,75 @@
+/* $Id: roff.c,v 1.4 2010/06/06 20:30:08 schwarze Exp $ */
+/*
+ * Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <string.h>
+
+#include "roff_reg.h"
+
+static int roff_nr_reg[ROFF_nr_MAX];
+static const char * const roff_nr_names[ROFF_nr_MAX] = {
+ "nS",
+};
+
+
+int
+roff_nr_index(const char *name)
+{
+ int i;
+
+ for (i = 0; i < ROFF_nr_MAX; i++)
+ if (0 == strcmp(name, roff_nr_names[i]))
+ return i;
+
+ return ROFF_nr_ERR;
+}
+
+const char *
+roff_nr_name(int i)
+{
+ if (i < 0 || i >= ROFF_nr_MAX)
+ return NULL;
+ return roff_nr_names[i];
+}
+
+int
+roff_nr_geti(int i)
+{
+ if (i < 0 || i >= ROFF_nr_MAX)
+ return 0;
+ return roff_nr_reg[i];
+}
+
+int
+roff_nr_getn(const char *name)
+{
+ return roff_nr_geti(roff_nr_index(name));
+}
+
+int
+roff_nr_seti(int i, int value)
+{
+ if (i < 0 || i >= ROFF_nr_MAX)
+ return 0;
+ roff_nr_reg[i] = value;
+ return 1;
+}
+
+int
+roff_nr_setn(const char *name, int value)
+{
+ return roff_nr_seti(roff_nr_index(name), value);
+}
Index: roff_reg.h
===================================================================
RCS file: roff_reg.h
diff -N roff_reg.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ roff_reg.h 16 Jun 2010 00:46:00 -0000
@@ -0,0 +1,35 @@
+/* $Id: roff.h,v 1.2 2010/05/20 00:58:02 schwarze Exp $ */
+/*
+ * Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef ROFF_REG_H
+#define ROFF_REG_H
+
+#define ROFF_nr_ERR -1
+#define ROFF_nr_nS 0
+#define ROFF_nr_MAX 1
+
+__BEGIN_DECLS
+
+int roff_nr_index(const char *);
+const char *roff_nr_name(int);
+int roff_nr_geti(int);
+int roff_nr_getn(const char *);
+int roff_nr_seti(int, int);
+int roff_nr_setn(const char *, int);
+
+__END_DECLS
+
+#endif /*!ROFF_REG_H*/
--
To unsubscribe send an email to tech+unsubscribe@mdocml.bsd.lv
next reply other threads:[~2010-06-16 2:11 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-06-16 2:11 Ingo Schwarze [this message]
[not found] <20100626122711.GA15113@iris.usta.de>
2010-06-26 15:32 ` [PATCH] .nr for mdoc(7)] Kristaps Dzonsons
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100616021128.GA14898@iris.usta.de \
--to=schwarze@usta.de \
--cc=tech@mdocml.bsd.lv \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).