slmisc.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. Copyright (C) 2004, 2005, 2006 John E. Davis
  3. This file is part of the S-Lang Library.
  4. Trimmed down for use in GNU Midnight Commander.
  5. The S-Lang Library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of the
  8. License, or (at your option) any later version.
  9. The S-Lang Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this library; if not, write to the Free Software
  15. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  16. USA.
  17. */
  18. #define _GNU_SOURCE
  19. #include "slinclud.h"
  20. #include <ctype.h>
  21. #include "slang.h"
  22. #include "_slang.h"
  23. char *SLmake_string(char *str)
  24. {
  25. return SLmake_nstring(str, strlen (str));
  26. }
  27. char *SLmake_nstring (char *str, unsigned int n)
  28. {
  29. char *ptr;
  30. if (NULL == (ptr = SLmalloc(n + 1)))
  31. {
  32. return NULL;
  33. }
  34. SLMEMCPY (ptr, str, n);
  35. ptr[n] = 0;
  36. return(ptr);
  37. }
  38. /*
  39. * This function assumes that the initial \ char has been removed.
  40. */
  41. char *_pSLexpand_escaped_char(char *p, SLwchar_Type *ch, int *isunicodep)
  42. {
  43. int i = 0;
  44. SLwchar_Type max = 0;
  45. SLwchar_Type num, base = 0;
  46. SLwchar_Type ch1;
  47. int isunicode;
  48. int needs_brace;
  49. ch1 = *p++;
  50. isunicode = 0;
  51. needs_brace = 0;
  52. switch (ch1)
  53. {
  54. default: num = ch1; break;
  55. case 'n': num = '\n'; break;
  56. case 't': num = '\t'; break;
  57. case 'v': num = '\v'; break;
  58. case 'b': num = '\b'; break;
  59. case 'r': num = '\r'; break;
  60. case 'f': num = '\f'; break;
  61. case 'E': case 'e': num = 27; break;
  62. case 'a': num = 7;
  63. break;
  64. /* octal */
  65. case '0': case '1': case '2': case '3':
  66. case '4': case '5': case '6': case '7':
  67. max = '7';
  68. base = 8; i = 2; num = ch1 - '0';
  69. break;
  70. case 'd': /* decimal -- S-Lang extension */
  71. base = 10;
  72. i = 3;
  73. max = '9';
  74. num = 0;
  75. break;
  76. case 'u':
  77. isunicode = 1;
  78. /* drop */
  79. case 'x': /* hex */
  80. base = 16;
  81. max = '9';
  82. i = 2;
  83. num = 0;
  84. if (*p == '{')
  85. {
  86. p++;
  87. i = 0;
  88. while (p[i] && (p[i] != '}'))
  89. i++;
  90. if (p[i] != '}')
  91. {
  92. SLang_verror (SL_SYNTAX_ERROR, "Escaped character missing closing }.");
  93. return NULL;
  94. }
  95. /* The meaning of \x{...} is mode dependent. If in UTF-8 mode, then
  96. * \x{...} always generates a unicode character. Otherwise, the
  97. * meaning of \x{...} depends upon the number of characters enclosed
  98. * by the brace. If there are less than 3, then assume no unicode.
  99. * If greater than or equal to 3, then assume unicode.
  100. */
  101. if (isunicode == 0) /* \x... */
  102. isunicode = _pSLinterp_UTF8_Mode || (i > 2);
  103. needs_brace = 1;
  104. }
  105. break;
  106. }
  107. while (i)
  108. {
  109. ch1 = *p;
  110. i--;
  111. if ((ch1 <= max) && (ch1 >= '0'))
  112. {
  113. num = base * num + (ch1 - '0');
  114. }
  115. else if (base == 16)
  116. {
  117. ch1 |= 0x20;
  118. if ((ch1 < 'a') || ((ch1 > 'f'))) break;
  119. num = base * num + 10 + (ch1 - 'a');
  120. }
  121. else break;
  122. p++;
  123. }
  124. if (needs_brace)
  125. {
  126. if (*p != '}')
  127. {
  128. SLang_verror (SL_SYNTAX_ERROR, "Malformed escaped character.");
  129. return NULL;
  130. }
  131. p++;
  132. }
  133. if (isunicodep != NULL)
  134. *isunicodep = isunicode;
  135. *ch = num;
  136. return p;
  137. }