summaryrefslogtreecommitdiffstatshomepage
path: root/main.c
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2009-03-22 19:01:11 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2009-03-22 19:01:11 +0000
commit7f5e6c325d7501f482f01a516a4bcd4fcde4d255 (patch)
tree82470d31e8b8c11cf36a23770b8151da394dd3ea /main.c
parent161e91f1e1aba8f876c65a8533432516e2dce548 (diff)
downloadmandoc-7f5e6c325d7501f482f01a516a4bcd4fcde4d255.tar.gz
mandoc-7f5e6c325d7501f482f01a516a4bcd4fcde4d255.tar.zst
mandoc-7f5e6c325d7501f482f01a516a4bcd4fcde4d255.zip
Stripping of Xo/Xc macros in main.c (ifdef STRIP_XO).
Diffstat (limited to 'main.c')
-rw-r--r--main.c84
1 files changed, 82 insertions, 2 deletions
diff --git a/main.c b/main.c
index 773700e9..889b3387 100644
--- a/main.c
+++ b/main.c
@@ -1,4 +1,4 @@
-/* $Id: main.c,v 1.7 2009/03/20 21:58:38 kristaps Exp $ */
+/* $Id: main.c,v 1.8 2009/03/22 19:01:11 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@openbsd.org>
*
@@ -264,6 +264,9 @@ fdesc(struct buf *blk, struct buf *ln,
ssize_t ssz;
struct stat st;
int j, i, pos, lnn;
+#ifdef STRIP_XO
+ int macro, xo, xeoln;
+#endif
/*
* Two buffers: ln and buf. buf is the input buffer, optimised
@@ -288,6 +291,9 @@ fdesc(struct buf *blk, struct buf *ln,
/*
* Fill buf with file blocksize and parse newlines into ln.
*/
+#ifdef STRIP_XO
+ macro = xo = xeoln = 0;
+#endif
for (lnn = 1, pos = 0; ; ) {
if (-1 == (ssz = read(fd, blk->buf, sz))) {
@@ -305,6 +311,66 @@ fdesc(struct buf *blk, struct buf *ln,
}
if ('\n' != blk->buf[i]) {
+ /*
+ * Ugly of uglies. Here we handle the
+ * dreaded `Xo/Xc' scoping. Cover the
+ * eyes of any nearby children. This
+ * makes `Xo/Xc' enclosures look like
+ * one huge line.
+ */
+#ifdef STRIP_XO
+ /*
+ * First, note whether we're in a macro
+ * line.
+ */
+ if (0 == pos && '.' == blk->buf[i])
+ macro = 1;
+
+ /*
+ * If we're in an `Xo' context and just
+ * nixed a newline, remove the control
+ * character for new macro lines:
+ * they're going to show up as all part
+ * of the same line.
+ */
+ if (xo && xeoln && '.' == blk->buf[i]) {
+ xeoln = 0;
+ continue;
+ }
+ xeoln = 0;
+
+ /*
+ * If we've parsed `Xo', enter an xo
+ * context. `Xo' must be in a parsable
+ * state. This is the ugly part. IT IS
+ * NOT SMART ENOUGH TO HANDLE ESCAPED
+ * WHITESPACE.
+ */
+ if (macro && pos && 'o' == blk->buf[i]) {
+ if (xo && 'X' == ln->buf[pos - 1]) {
+ if (' ' == ln->buf[pos - 2])
+ xo++;
+ } else if ('X' == ln->buf[pos - 1]) {
+ if (2 == pos && '.' == ln->buf[pos - 2])
+ xo++;
+ else if (' ' == ln->buf[pos - 2])
+ xo++;
+ }
+ }
+
+ /*
+ * If we're parsed `Xc', leave an xo
+ * context if one's already pending.
+ * `Xc' must be in a parsable state.
+ * THIS IS NOT SMART ENOUGH TO HANDLE
+ * ESCAPED WHITESPACE.
+ */
+ if (macro && pos && 'c' == blk->buf[i])
+ if (xo && 'X' == ln->buf[pos - 1])
+ if (' ' == ln->buf[pos - 2])
+ xo--;
+#endif /* STRIP_XO */
+
ln->buf[pos++] = blk->buf[i];
continue;
}
@@ -323,11 +389,25 @@ fdesc(struct buf *blk, struct buf *ln,
}
}
+#ifdef STRIP_XO
+ /*
+ * If we're in an xo context, put a space in
+ * place of the newline and continue parsing.
+ * Mark that we just did a newline.
+ */
+ if (xo) {
+ xeoln = 1;
+ ln->buf[pos++] = ' ';
+ lnn++;
+ continue;
+ }
+#endif /* STRIP_XO */
+
ln->buf[pos] = 0;
if ( ! mdoc_parseln(mdoc, lnn, ln->buf))
return(0);
lnn++;
- pos = 0;
+ macro = pos = 0;
}
}