+ const char *local_start;
+ int local_sz;
+ char term;
+ enum mandoc_esc gly;
+
+ /*
+ * When the caller doesn't provide return storage,
+ * use local storage.
+ */
+
+ if (NULL == start)
+ start = &local_start;
+ if (NULL == sz)
+ sz = &local_sz;
+
+ /*
+ * Beyond the backslash, at least one input character
+ * is part of the escape sequence. With one exception
+ * (see below), that character won't be returned.
+ */
+
+ gly = ESCAPE_ERROR;
+ *start = ++*end;
+ *sz = 0;
+ term = '\0';
+
+ switch ((*start)[-1]) {
+ /*
+ * First the glyphs. There are several different forms of
+ * these, but each eventually returns a substring of the glyph
+ * name.
+ */
+ case '(':
+ gly = ESCAPE_SPECIAL;
+ *sz = 2;
+ break;
+ case '[':
+ gly = ESCAPE_SPECIAL;
+ /*
+ * Unicode escapes are defined in groff as \[uXXXX] to
+ * \[u10FFFF], where the contained value must be a valid
+ * Unicode codepoint. Here, however, only check whether
+ * it's not a zero-width escape.
+ */
+ if ('u' == (*start)[0] && ']' != (*start)[1])
+ gly = ESCAPE_UNICODE;
+ term = ']';
+ break;
+ case 'C':
+ if ('\'' != **start)
+ return(ESCAPE_ERROR);
+ *start = ++*end;
+ if ('u' == (*start)[0] && '\'' != (*start)[1])
+ gly = ESCAPE_UNICODE;
+ else
+ gly = ESCAPE_SPECIAL;
+ term = '\'';
+ break;