aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2018-12-18 22:00:02 +0000
committerIngo Schwarze <schwarze@openbsd.org>2018-12-18 22:00:02 +0000
commit5bc970f9a1ac9d2e79813a5f47afc896c49d0653 (patch)
tree3b694d475731e01c6d1718be9673fc336c0fc76a
parent0feeec8b7ee122eca332de3af7c2f791fdba8ee6 (diff)
downloadmandoc-5bc970f9a1ac9d2e79813a5f47afc896c49d0653.tar.gz
mandoc-5bc970f9a1ac9d2e79813a5f47afc896c49d0653.tar.zst
mandoc-5bc970f9a1ac9d2e79813a5f47afc896c49d0653.zip
As a first step towards making roff_res() callable from mandoc_getarg(),
move the function mandoc_getarg() from mandoc.c to roff.c. It was misplaced in mandoc.c in the first place; that file is intended for utilities needed both by parsers and by formatters, while reading macro arguments in copy mode is purely a task of the roff(7) parser. Needed as a preliminary for an upcoming bugfix. No code change.
-rw-r--r--mandoc.c98
-rw-r--r--roff.c99
2 files changed, 99 insertions, 98 deletions
diff --git a/mandoc.c b/mandoc.c
index 02bcf954..d1e7356b 100644
--- a/mandoc.c
+++ b/mandoc.c
@@ -1,4 +1,4 @@
-/* $Id: mandoc.c,v 1.112 2018/12/16 00:17:02 schwarze Exp $ */
+/* $Id: mandoc.c,v 1.113 2018/12/18 22:00:02 schwarze Exp $ */
/*
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2011-2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
@@ -465,102 +465,6 @@ mandoc_escape(const char **end, const char **start, int *sz)
return gly;
}
-/*
- * Parse a quoted or unquoted roff-style request or macro argument.
- * Return a pointer to the parsed argument, which is either the original
- * pointer or advanced by one byte in case the argument is quoted.
- * NUL-terminate the argument in place.
- * Collapse pairs of quotes inside quoted arguments.
- * Advance the argument pointer to the next argument,
- * or to the NUL byte terminating the argument line.
- */
-char *
-mandoc_getarg(char **cpp, int ln, int *pos)
-{
- char *start, *cp;
- int quoted, pairs, white;
-
- /* Quoting can only start with a new word. */
- start = *cpp;
- quoted = 0;
- if ('"' == *start) {
- quoted = 1;
- start++;
- }
-
- pairs = 0;
- white = 0;
- for (cp = start; '\0' != *cp; cp++) {
-
- /*
- * Move the following text left
- * after quoted quotes and after "\\" and "\t".
- */
- if (pairs)
- cp[-pairs] = cp[0];
-
- if ('\\' == cp[0]) {
- /*
- * In copy mode, translate double to single
- * backslashes and backslash-t to literal tabs.
- */
- switch (cp[1]) {
- case 'a':
- case 't':
- cp[0] = '\t';
- /* FALLTHROUGH */
- case '\\':
- pairs++;
- cp++;
- break;
- case ' ':
- /* Skip escaped blanks. */
- if (0 == quoted)
- cp++;
- break;
- default:
- break;
- }
- } else if (0 == quoted) {
- if (' ' == cp[0]) {
- /* Unescaped blanks end unquoted args. */
- white = 1;
- break;
- }
- } else if ('"' == cp[0]) {
- if ('"' == cp[1]) {
- /* Quoted quotes collapse. */
- pairs++;
- cp++;
- } else {
- /* Unquoted quotes end quoted args. */
- quoted = 2;
- break;
- }
- }
- }
-
- /* Quoted argument without a closing quote. */
- if (1 == quoted)
- mandoc_msg(MANDOCERR_ARG_QUOTE, ln, *pos, NULL);
-
- /* NUL-terminate this argument and move to the next one. */
- if (pairs)
- cp[-pairs] = '\0';
- if ('\0' != *cp) {
- *cp++ = '\0';
- while (' ' == *cp)
- cp++;
- }
- *pos += (int)(cp - start) + (quoted ? 1 : 0);
- *cpp = cp;
-
- if ('\0' == *cp && (white || ' ' == cp[-1]))
- mandoc_msg(MANDOCERR_SPACE_EOL, ln, *pos, NULL);
-
- return start;
-}
-
static int
a2time(time_t *t, const char *fmt, const char *p)
{
diff --git a/roff.c b/roff.c
index 96a5b33d..e25a74ef 100644
--- a/roff.c
+++ b/roff.c
@@ -1,4 +1,4 @@
-/* $Id: roff.c,v 1.352 2018/12/15 19:30:26 schwarze Exp $ */
+/* $Id: roff.c,v 1.353 2018/12/18 22:00:02 schwarze Exp $ */
/*
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
@@ -1547,6 +1547,103 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos)
}
/*
+ * Parse a quoted or unquoted roff-style request or macro argument.
+ * Return a pointer to the parsed argument, which is either the original
+ * pointer or advanced by one byte in case the argument is quoted.
+ * NUL-terminate the argument in place.
+ * Collapse pairs of quotes inside quoted arguments.
+ * Advance the argument pointer to the next argument,
+ * or to the NUL byte terminating the argument line.
+ */
+char *
+mandoc_getarg(char **cpp, int ln, int *pos)
+{
+ char *start, *cp;
+ int quoted, pairs, white;
+
+ /* Quoting can only start with a new word. */
+ start = *cpp;
+ quoted = 0;
+ if ('"' == *start) {
+ quoted = 1;
+ start++;
+ }
+
+ pairs = 0;
+ white = 0;
+ for (cp = start; '\0' != *cp; cp++) {
+
+ /*
+ * Move the following text left
+ * after quoted quotes and after "\\" and "\t".
+ */
+ if (pairs)
+ cp[-pairs] = cp[0];
+
+ if ('\\' == cp[0]) {
+ /*
+ * In copy mode, translate double to single
+ * backslashes and backslash-t to literal tabs.
+ */
+ switch (cp[1]) {
+ case 'a':
+ case 't':
+ cp[0] = '\t';
+ /* FALLTHROUGH */
+ case '\\':
+ pairs++;
+ cp++;
+ break;
+ case ' ':
+ /* Skip escaped blanks. */
+ if (0 == quoted)
+ cp++;
+ break;
+ default:
+ break;
+ }
+ } else if (0 == quoted) {
+ if (' ' == cp[0]) {
+ /* Unescaped blanks end unquoted args. */
+ white = 1;
+ break;
+ }
+ } else if ('"' == cp[0]) {
+ if ('"' == cp[1]) {
+ /* Quoted quotes collapse. */
+ pairs++;
+ cp++;
+ } else {
+ /* Unquoted quotes end quoted args. */
+ quoted = 2;
+ break;
+ }
+ }
+ }
+
+ /* Quoted argument without a closing quote. */
+ if (1 == quoted)
+ mandoc_msg(MANDOCERR_ARG_QUOTE, ln, *pos, NULL);
+
+ /* NUL-terminate this argument and move to the next one. */
+ if (pairs)
+ cp[-pairs] = '\0';
+ if ('\0' != *cp) {
+ *cp++ = '\0';
+ while (' ' == *cp)
+ cp++;
+ }
+ *pos += (int)(cp - start) + (quoted ? 1 : 0);
+ *cpp = cp;
+
+ if ('\0' == *cp && (white || ' ' == cp[-1]))
+ mandoc_msg(MANDOCERR_SPACE_EOL, ln, *pos, NULL);
+
+ return start;
+}
+
+
+/*
* Process text streams.
*/
static int