Merge 15268:15329 from trunk
[reactos.git] / rosapps / mc / slang / sltoken.c
1 /*--------------------------------*-C-*---------------------------------*
2 * File: sltoken.c
3 *
4 * Descript: ---
5 *
6 * Requires: ---
7 *
8 * Public: SLexpand_escaped_char ();
9 * SLexpand_escaped_string ();
10 * SLang_extract_token ();
11 * SLang_guess_type ();
12 * SLatoi ();
13 *
14 * Private: ---
15 *
16 * Notes: ---
17 *
18 * Copyright (c) 1992, 1995 John E. Davis
19 * All rights reserved.
20 *
21 * You may distribute under the terms of either the GNU General Public
22 * License or the Perl Artistic License.
23 \*----------------------------------------------------------------------*/
24
25 #include "config.h"
26
27 #include <stdio.h>
28
29
30 #ifdef HAVE_STDLIB_H
31 # include <stdlib.h>
32 #endif
33 #include <string.h>
34 #include "slang.h"
35 #include "_slang.h"
36
37 /* There are non-zeros at positions "\t %()*,/:;[]{}" */
38
39 static unsigned char special_chars[256] =
40 {
41 /* 0 */ 0,0,0,0,0,0,0,0, 0,'\t',0,0,0,0,0,0,
42 /* 16 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
43 /* 32 */ ' ',0,0,0,0,'%',0,0, '(',')','*',0,',',0,0,'/',
44 /* 48 */ 0,0,0,0,0,0,0,0, 0,0,':',';',0,0,0,0,
45 /* 64 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
46 /* 80 */ 0,0,0,0,0,0,0,0, 0,0,0,'[',0,']',0,0,
47 /* 96 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
48 /* 112 */ 0,0,0,0,0,0,0,0, 0,0,0,'{',0,'}',0,0,
49 /* 8-bit characters */
50 /* 128 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
51 /* 144 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
52 /* 160 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
53 /* 176 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
54 /* 192 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
55 /* 208 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
56 /* 224 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
57 /* 240 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0
58 };
59
60 char *SLexpand_escaped_char(char *p, char *ch)
61 {
62 int i = 0;
63 int max = 0, num, base = 0;
64 char ch1;
65
66 ch1 = *p++;
67
68 switch (ch1)
69 {
70 default: num = ch1; break;
71 case 'n': num = '\n'; break;
72 case 't': num = '\t'; break;
73 case 'v': num = '\v'; break;
74 case 'b': num = '\b'; break;
75 case 'r': num = '\r'; break;
76 case 'f': num = '\f'; break;
77 case 'E': case 'e': num = 27; break;
78 case 'a': num = 7;
79 break;
80
81 /* octal */
82 case '0': case '1': case '2': case '3':
83 case '4': case '5': case '6': case '7':
84 max = '7';
85 base = 8; i = 2; num = ch1 - '0';
86 break;
87
88 case 'd': /* decimal -- S-Lang extension */
89 base = 10;
90 i = 3;
91 max = '9';
92 num = 0;
93 break;
94
95 case 'x': /* hex */
96 base = 16;
97 max = '9';
98 i = 2;
99 num = 0;
100 break;
101 }
102
103 while (i--)
104 {
105 ch1 = *p;
106
107 if ((ch1 <= max) && (ch1 >= '0'))
108 {
109 num = base * num + (ch1 - '0');
110 }
111 else if (base == 16)
112 {
113 ch1 |= 0x20;
114 if ((ch1 < 'a') || ((ch1 > 'f'))) break;
115 num = base * num + 10 + (ch1 - 'a');
116 }
117 else break;
118 p++;
119 }
120
121 *ch = (char) num;
122 return p;
123 }
124
125 void SLexpand_escaped_string (register char *s, register char *t,
126 register char *tmax)
127 {
128 char ch;
129
130 while (t < tmax)
131 {
132 ch = *t++;
133 if (ch == '\\')
134 {
135 t = SLexpand_escaped_char (t, &ch);
136 }
137 *s++ = ch;
138 }
139 *s = 0;
140 }
141
142
143 int SLang_extract_token (char **linep, char *word_parm, int byte_comp)
144 {
145 register char ch, *line, *word = word_parm;
146 int string;
147 char ch1;
148 char *word_max;
149
150 word_max = word + 250;
151
152 line = *linep;
153
154 /* skip white space */
155 while (((ch = *line) == ' ')
156 || (ch == '\t')) line++;
157
158 if ((!ch) || (ch == '\n'))
159 {
160 *linep = line;
161 return(0);
162 }
163
164 *word++ = ch;
165 line++;
166
167 /* Look for -something and rule out --something and -= something */
168 if ((ch == '-') &&
169 (*line != '-') && (*line != '=') && ((*line > '9') || (*line < '0')))
170 {
171 *word = 0;
172 *linep = line;
173 return 1;
174 }
175
176
177 if (ch == '"') string = 1; else string = 0;
178 if (ch == '\'')
179 {
180 if ((ch = *line++) != 0)
181 {
182 if (ch == '\\')
183 {
184 line = SLexpand_escaped_char(line, &ch1);
185 ch = ch1;
186 }
187 if (*line++ == '\'')
188 {
189 --word;
190 sprintf(word, "%d", (int) ((unsigned char) ch));
191 word += strlen (word); ch = '\'';
192 }
193 else SLang_Error = SYNTAX_ERROR;
194 }
195 else SLang_Error = SYNTAX_ERROR;
196 }
197 else if (!special_chars[(unsigned char) ch])
198 {
199 while (ch = *line++,
200 (ch > '"') ||
201 ((ch != '\n') && (ch != 0) && (ch != '"')))
202 {
203 if (string)
204 {
205 if (ch == '\\')
206 {
207 ch = *line++;
208 if ((ch == 0) || (ch == '\n')) break;
209 if (byte_comp) *word++ = '\\';
210 else
211 {
212 line = SLexpand_escaped_char(line - 1, &ch1);
213 ch = ch1;
214 }
215 }
216 }
217 else if (special_chars[(unsigned char) ch])
218 {
219 line--;
220 break;
221 }
222
223 *word++ = ch;
224 if (word > word_max)
225 {
226 SLang_doerror ("Token to large.");
227 break;
228 }
229 }
230 }
231
232 if ((!ch) || (ch == '\n')) line--;
233 if ((ch == '"') && string) *word++ = '"'; else if (string) SLang_Error = SYNTAX_ERROR;
234 *word = 0;
235 *linep = line;
236 /* massage variable-- and ++ into --variable, etc... */
237 if (((int) (word - word_parm) > 2)
238 && (ch = *(word - 1), (ch == '+') || (ch == '-'))
239 && (ch == *(word - 2)))
240 {
241 word--;
242 while (word >= word_parm + 2)
243 {
244 *word = *(word - 2);
245 word--;
246 }
247 *word-- = ch;
248 *word-- = ch;
249 }
250 return(1);
251 }
252
253
254 int SLang_guess_type (char *t)
255 {
256 char *p;
257 register char ch;
258
259 if (*t == '-') t++;
260 p = t;
261 #ifdef FLOAT_TYPE
262 if (*p != '.')
263 {
264 #endif
265 while ((*p >= '0') && (*p <= '9')) p++;
266 if (t == p) return(STRING_TYPE);
267 if ((*p == 'x') && (p == t + 1)) /* 0x?? */
268 {
269 p++;
270 while (ch = *p,
271 ((ch >= '0') && (ch <= '9'))
272 || (((ch | 0x20) >= 'a') && ((ch | 0x20) <= 'f'))) p++;
273 }
274 if (*p == 0) return(INT_TYPE);
275 #ifndef FLOAT_TYPE
276 return(STRING_TYPE);
277 #else
278 }
279
280 /* now down to float case */
281 if (*p == '.')
282 {
283 p++;
284 while ((*p >= '0') && (*p <= '9')) p++;
285 }
286 if (*p == 0) return(FLOAT_TYPE);
287 if ((*p != 'e') && (*p != 'E')) return(STRING_TYPE);
288 p++;
289 if ((*p == '-') || (*p == '+')) p++;
290 while ((*p >= '0') && (*p <= '9')) p++;
291 if (*p != 0) return(STRING_TYPE); else return(FLOAT_TYPE);
292 #endif
293 }
294
295 int SLatoi (unsigned char *s)
296 {
297 register unsigned char ch;
298 register unsigned int value;
299 register int base;
300
301 if (*s != '0') return atoi((char *) s);
302
303 /* look for 'x' which indicates hex */
304 s++;
305 if ((*s | 0x20) == 'x')
306 {
307 base = 16;
308 s++;
309 if (*s == 0)
310 {
311 SLang_Error = SYNTAX_ERROR;
312 return -1;
313 }
314 }
315 else base = 8;
316
317
318 value = 0;
319 while ((ch = *s++) != 0)
320 {
321 char ch1 = ch | 0x20;
322 switch (ch1)
323 {
324 default:
325 SLang_Error = SYNTAX_ERROR;
326 break;
327 case '8':
328 case '9':
329 if (base != 16) SLang_Error = SYNTAX_ERROR;
330 /* drop */
331 case '0':
332 case '1':
333 case '2':
334 case '3':
335 case '4':
336 case '5':
337 case '6':
338 case '7':
339 ch1 -= '0';
340 break;
341
342 case 'a':
343 case 'b':
344 case 'c':
345 case 'd':
346 case 'e':
347 case 'f':
348 if (base != 16) SLang_Error = SYNTAX_ERROR;
349 ch1 = (ch1 - 'a') + 10;
350 break;
351 }
352 value = value * base + ch1;
353 }
354 return (int) value;
355 }