+/*
+ * Pre-filter each and every line for reserved words (one beginning with
+ * `\*', e.g., `\*(ab'). These must be handled before the actual line
+ * is processed.
+ */
+static int
+roff_res(struct roff *r, char **bufp, size_t *szp, int pos)
+{
+ const char *cp, *cpp, *st, *res;
+ int i, maxl;
+ size_t nsz;
+ char *n;
+
+ /* LINTED */
+ for (cp = &(*bufp)[pos]; (cpp = strstr(cp, "\\*")); cp++) {
+ cp = cpp + 2;
+ switch (*cp) {
+ case ('('):
+ cp++;
+ maxl = 2;
+ break;
+ case ('['):
+ cp++;
+ maxl = 0;
+ break;
+ default:
+ maxl = 1;
+ break;
+ }
+
+ st = cp;
+
+ for (i = 0; 0 == maxl || i < maxl; i++, cp++) {
+ if ('\0' == *cp)
+ return(1); /* Error. */
+ if (0 == maxl && ']' == *cp)
+ break;
+ }
+
+ res = roff_getstrn(r, st, (size_t)i);
+
+ if (NULL == res) {
+ cp -= maxl ? 1 : 0;
+ continue;
+ }
+
+ ROFF_DEBUG("roff: splicing reserved: [%.*s]\n", i, st);
+
+ nsz = *szp + strlen(res) + 1;
+ n = mandoc_malloc(nsz);
+
+ *n = '\0';
+
+ strlcat(n, *bufp, (size_t)(cpp - *bufp + 1));
+ strlcat(n, res, nsz);
+ strlcat(n, cp + (maxl ? 0 : 1), nsz);
+
+ free(*bufp);
+
+ *bufp = n;
+ *szp = nsz;
+ return(0);
+ }
+
+ return(1);
+}
+
+