version 1.78, 2018/12/14 06:33:03 |
version 1.79, 2018/12/15 19:30:19 |
|
|
sz = &local_sz; |
sz = &local_sz; |
|
|
/* |
/* |
|
* Treat "\E" just like "\"; |
|
* it only makes a difference in copy mode. |
|
*/ |
|
|
|
if (**end == 'E') |
|
++*end; |
|
|
|
/* |
* Beyond the backslash, at least one input character |
* Beyond the backslash, at least one input character |
* is part of the escape sequence. With one exception |
* is part of the escape sequence. With one exception |
* (see below), that character won't be returned. |
* (see below), that character won't be returned. |
|
|
*sz = 2; |
*sz = 2; |
break; |
break; |
case '[': |
case '[': |
|
if (**start == ' ') { |
|
++*end; |
|
return ESCAPE_ERROR; |
|
} |
gly = ESCAPE_SPECIAL; |
gly = ESCAPE_SPECIAL; |
term = ']'; |
term = ']'; |
break; |
break; |
|
|
/* |
/* |
* Escapes taking no arguments at all. |
* Escapes taking no arguments at all. |
*/ |
*/ |
case 'd': |
case '!': |
case 'u': |
case '?': |
|
return ESCAPE_UNSUPP; |
|
case '%': |
|
case '&': |
|
case ')': |
case ',': |
case ',': |
case '/': |
case '/': |
|
case '^': |
|
case 'a': |
|
case 'd': |
|
case 'r': |
|
case 't': |
|
case 'u': |
|
case '{': |
|
case '|': |
|
case '}': |
return ESCAPE_IGNORE; |
return ESCAPE_IGNORE; |
|
case 'c': |
|
return ESCAPE_NOSPACE; |
case 'p': |
case 'p': |
return ESCAPE_BREAK; |
return ESCAPE_BREAK; |
|
|
|
|
* 'X' is the trigger. These have opaque sub-strings. |
* 'X' is the trigger. These have opaque sub-strings. |
*/ |
*/ |
case 'F': |
case 'F': |
|
case 'f': |
case 'g': |
case 'g': |
case 'k': |
case 'k': |
case 'M': |
case 'M': |
case 'm': |
case 'm': |
case 'n': |
case 'n': |
|
case 'O': |
case 'V': |
case 'V': |
case 'Y': |
case 'Y': |
gly = ESCAPE_IGNORE; |
gly = (*start)[-1] == 'f' ? ESCAPE_FONT : ESCAPE_IGNORE; |
/* FALLTHROUGH */ |
|
case 'f': |
|
if (ESCAPE_ERROR == gly) |
|
gly = ESCAPE_FONT; |
|
switch (**start) { |
switch (**start) { |
case '(': |
case '(': |
|
if ((*start)[-1] == 'O') |
|
gly = ESCAPE_ERROR; |
*start = ++*end; |
*start = ++*end; |
*sz = 2; |
*sz = 2; |
break; |
break; |
case '[': |
case '[': |
|
if ((*start)[-1] == 'O') |
|
gly = (*start)[1] == '5' ? |
|
ESCAPE_UNSUPP : ESCAPE_ERROR; |
*start = ++*end; |
*start = ++*end; |
term = ']'; |
term = ']'; |
break; |
break; |
default: |
default: |
|
if ((*start)[-1] == 'O') { |
|
switch (**start) { |
|
case '0': |
|
gly = ESCAPE_UNSUPP; |
|
break; |
|
case '1': |
|
case '2': |
|
case '3': |
|
case '4': |
|
break; |
|
default: |
|
gly = ESCAPE_ERROR; |
|
break; |
|
} |
|
} |
*sz = 1; |
*sz = 1; |
break; |
break; |
} |
} |
|
|
break; |
break; |
|
|
/* |
/* |
* Anything else is assumed to be a glyph. |
* Several special characters can be encoded as |
* In this case, pass back the character after the backslash. |
* one-byte escape sequences without using \[]. |
*/ |
*/ |
default: |
case ' ': |
|
case '\'': |
|
case '-': |
|
case '.': |
|
case '0': |
|
case ':': |
|
case '_': |
|
case '`': |
|
case 'e': |
|
case '~': |
gly = ESCAPE_SPECIAL; |
gly = ESCAPE_SPECIAL; |
|
/* FALLTHROUGH */ |
|
default: |
|
if (gly == ESCAPE_ERROR) |
|
gly = ESCAPE_UNDEF; |
*start = --*end; |
*start = --*end; |
*sz = 1; |
*sz = 1; |
break; |
break; |
} |
} |
|
|
assert(ESCAPE_ERROR != gly); |
|
|
|
/* |
/* |
* Read up to the terminating character, |
* Read up to the terminating character, |
* paying attention to nested escapes. |
* paying attention to nested escapes. |
|
|
} |
} |
} |
} |
*sz = (*end)++ - *start; |
*sz = (*end)++ - *start; |
|
|
|
/* |
|
* The file chars.c only provides one common list |
|
* of character names, but \[-] == \- is the only |
|
* one of the characters with one-byte names that |
|
* allows enclosing the name in brackets. |
|
*/ |
|
if (gly == ESCAPE_SPECIAL && *sz == 1 && **start != '-') |
|
return ESCAPE_ERROR; |
} else { |
} else { |
assert(*sz > 0); |
assert(*sz > 0); |
if ((size_t)*sz > strlen(*start)) |
if ((size_t)*sz > strlen(*start)) |
|
|
break; |
break; |
case ESCAPE_SPECIAL: |
case ESCAPE_SPECIAL: |
if (**start == 'c') { |
if (**start == 'c') { |
if (*sz == 1) { |
|
gly = ESCAPE_NOSPACE; |
|
break; |
|
} |
|
if (*sz < 6 || *sz > 7 || |
if (*sz < 6 || *sz > 7 || |
strncmp(*start, "char", 4) != 0 || |
strncmp(*start, "char", 4) != 0 || |
(int)strspn(*start + 4, "0123456789") + 4 < *sz) |
(int)strspn(*start + 4, "0123456789") + 4 < *sz) |
|
|
* backslashes and backslash-t to literal tabs. |
* backslashes and backslash-t to literal tabs. |
*/ |
*/ |
switch (cp[1]) { |
switch (cp[1]) { |
|
case 'a': |
case 't': |
case 't': |
cp[0] = '\t'; |
cp[0] = '\t'; |
/* FALLTHROUGH */ |
/* FALLTHROUGH */ |