| 1334 | // and returns the rune. |
| 1335 | // Pre: t at '\\'. Post: after escape. |
| 1336 | @SuppressWarnings("fallthrough") // disables *all* fallthru checking. Lame. |
| 1337 | private static int parseEscape(StringIterator t) throws PatternSyntaxException { |
| 1338 | int startPos = t.pos(); |
| 1339 | t.skip(1); // '\\' |
| 1340 | if (!t.more()) { |
| 1341 | throw new PatternSyntaxException(ERR_TRAILING_BACKSLASH); |
| 1342 | } |
| 1343 | int c = t.pop(); |
| 1344 | bigswitch: |
| 1345 | switch (c) { |
| 1346 | default: |
| 1347 | if (!Utils.isalnum(c)) { |
| 1348 | // Escaped non-word characters are always themselves. |
| 1349 | // PCRE is not quite so rigorous: it accepts things like |
| 1350 | // \q, but we don't. We once rejected \_, but too many |
| 1351 | // programs and people insist on using it, so allow \_. |
| 1352 | return c; |
| 1353 | } |
| 1354 | break; |
| 1355 | |
| 1356 | // Octal escapes. |
| 1357 | case '1': |
| 1358 | case '2': |
| 1359 | case '3': |
| 1360 | case '4': |
| 1361 | case '5': |
| 1362 | case '6': |
| 1363 | case '7': |
| 1364 | // Single non-zero digit is a backreference; not supported |
| 1365 | if (!t.more() || t.peek() < '0' || t.peek() > '7') { |
| 1366 | break; |
| 1367 | } |
| 1368 | /* fallthrough */ |
| 1369 | case '0': |
| 1370 | // Consume up to three octal digits; already have one. |
| 1371 | int r = c - '0'; |
| 1372 | for (int i = 1; i < 3; i++) { |
| 1373 | if (!t.more() || t.peek() < '0' || t.peek() > '7') { |
| 1374 | break; |
| 1375 | } |
| 1376 | r = r * 8 + t.peek() - '0'; |
| 1377 | t.skip(1); // digit |
| 1378 | } |
| 1379 | return r; |
| 1380 | |
| 1381 | // Hexadecimal escapes. |
| 1382 | case 'x': |
| 1383 | if (!t.more()) { |
| 1384 | break; |
| 1385 | } |
| 1386 | c = t.pop(); |
| 1387 | if (c == '{') { |
| 1388 | // Any number of digits in braces. |
| 1389 | // Perl accepts any text at all; it ignores all text |
| 1390 | // after the first non-hex digit. We require only hex digits, |
| 1391 | // and at least one. |
| 1392 | int nhex = 0; |
| 1393 | r = 0; |