process_escape_sequence.c 1.5 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 <stdio.h>
  11. #include <limits.h>
  12. #include <ctype.h>
  13. #include "libbb.h"
  14. #define WANT_HEX_ESCAPES 1
  15. /* Usual "this only works for ascii compatible encodings" disclaimer. */
  16. #undef _tolower
  17. #define _tolower(X) ((X)|((char) 0x20))
  18. char bb_process_escape_sequence(const char **ptr)
  19. {
  20. static const char charmap[] = {
  21. 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', 0,
  22. '\a', '\b', '\f', '\n', '\r', '\t', '\v', '\\', '\\' };
  23. const char *p;
  24. const char *q;
  25. unsigned int num_digits;
  26. unsigned int r;
  27. unsigned int n;
  28. unsigned int d;
  29. unsigned int 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 int)(*q - '0');
  42. #ifdef WANT_HEX_ESCAPES
  43. if (d >= 10) {
  44. d = ((unsigned int)(_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. }