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