tech@mandoc.bsd.lv
 help / color / mirror / Atom feed
* [PATCH] .nr for mdoc(7)
@ 2010-06-16  2:11 Ingo Schwarze
  0 siblings, 0 replies; 2+ messages in thread
From: Ingo Schwarze @ 2010-06-16  2:11 UTC (permalink / raw)
  To: tech

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

^ permalink raw reply	[flat|nested] 2+ messages in thread
[parent not found: <20100626122711.GA15113@iris.usta.de>]

end of thread, other threads:[~2010-06-26 15:22 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-06-16  2:11 [PATCH] .nr for mdoc(7) Ingo Schwarze
     [not found] <20100626122711.GA15113@iris.usta.de>
2010-06-26 15:32 ` [PATCH] .nr for mdoc(7)] Kristaps Dzonsons

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).