process_escape_sequence.c 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * Utility routines.
  4. *
  5. * Copyright (C) Manuel Novoa III <mjn3@codepoet.org>
  6. * and Vladimir Oleynik <dzo@simtreas.ru>
  7. *
  8. * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
  9. */
  10. #include "libbb.h"
  11. #define WANT_HEX_ESCAPES 1
  12. /* Usual "this only works for ascii compatible encodings" disclaimer. */
  13. #undef _tolower
  14. #define _tolower(X) ((X)|((char) 0x20))
  15. char FAST_FUNC bb_process_escape_sequence(const char **ptr)
  16. {
  17. /* bash builtin "echo -e '\ec'" interprets \e as ESC,
  18. * but coreutils "/bin/echo -e '\ec'" does not.
  19. * manpages tend to support coreutils way. */
  20. static const char charmap[] ALIGN1 = {
  21. 'a', 'b', /*'e',*/ 'f', 'n', 'r', 't', 'v', '\\', 0,
  22. '\a', '\b', /*27,*/ '\f', '\n', '\r', '\t', '\v', '\\', '\\' };
  23. const char *p;
  24. const char *q;
  25. unsigned num_digits;
  26. unsigned r;
  27. unsigned n;
  28. unsigned d;
  29. unsigned base;
  30. num_digits = n = 0;
  31. base = 8;
  32. q = *ptr;
  33. #ifdef WANT_HEX_ESCAPES
  34. if (*q == 'x') {
  35. ++q;
  36. base = 16;
  37. ++num_digits;
  38. }
  39. #endif
  40. do {
  41. d = (unsigned char)(*q) - '0';
  42. #ifdef WANT_HEX_ESCAPES
  43. if (d >= 10) {
  44. d = (unsigned char)(_tolower(*q)) - 'a' + 10;
  45. }
  46. #endif
  47. if (d >= base) {
  48. #ifdef WANT_HEX_ESCAPES
  49. if ((base == 16) && (!--num_digits)) {
  50. /* return '\\'; */
  51. --q;
  52. }
  53. #endif
  54. break;
  55. }
  56. r = n * base + d;
  57. if (r > UCHAR_MAX) {
  58. break;
  59. }
  60. n = r;
  61. ++q;
  62. } while (++num_digits < 3);
  63. if (num_digits == 0) { /* mnemonic escape sequence? */
  64. p = charmap;
  65. do {
  66. if (*p == *q) {
  67. q++;
  68. break;
  69. }
  70. } while (*++p);
  71. n = *(p + (sizeof(charmap)/2));
  72. }
  73. *ptr = q;
  74. return (char) n;
  75. }