done till colors ...
[midnight-commander.git] / slang / sltoken.c
blob7b3368a3fa7c00c2053a3ff293de9772669abeb1
1 /*--------------------------------*-C-*---------------------------------*
2 * File: sltoken.c
4 * Descript: ---
6 * Requires: ---
8 * Public: SLexpand_escaped_char ();
9 * SLexpand_escaped_string ();
10 * SLang_extract_token ();
11 * SLang_guess_type ();
12 * SLatoi ();
14 * Private: ---
16 * Notes: ---
18 * Copyright (c) 1992, 1995 John E. Davis
19 * All rights reserved.
21 * You may distribute under the terms of either the GNU General Public
22 * License or the Perl Artistic License.
23 \*----------------------------------------------------------------------*/
25 #include "config.h"
27 #include <stdio.h>
30 #ifdef HAVE_STDLIB_H
31 # include <stdlib.h>
32 #endif
33 #include <string.h>
34 #include "_slang.h"
36 /* There are non-zeros at positions "\t %()*,/:;[]{}" */
38 static const unsigned char special_chars[256] =
40 /* 0 */ 0,0,0,0,0,0,0,0, 0,'\t',0,0,0,0,0,0,
41 /* 16 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
42 /* 32 */ ' ',0,0,0,0,'%',0,0, '(',')','*',0,',',0,0,'/',
43 /* 48 */ 0,0,0,0,0,0,0,0, 0,0,':',';',0,0,0,0,
44 /* 64 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
45 /* 80 */ 0,0,0,0,0,0,0,0, 0,0,0,'[',0,']',0,0,
46 /* 96 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
47 /* 112 */ 0,0,0,0,0,0,0,0, 0,0,0,'{',0,'}',0,0,
48 /* 8-bit characters */
49 /* 128 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
50 /* 144 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
51 /* 160 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
52 /* 176 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
53 /* 192 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
54 /* 208 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
55 /* 224 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
56 /* 240 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0
59 char *SLexpand_escaped_char(char *p, char *ch)
61 int i = 0;
62 int max = 0, num, base = 0;
63 char ch1;
65 ch1 = *p++;
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 'x': /* hex */
95 base = 16;
96 max = '9';
97 i = 2;
98 num = 0;
99 break;
102 while (i--)
104 ch1 = *p;
106 if ((ch1 <= max) && (ch1 >= '0'))
108 num = base * num + (ch1 - '0');
110 else if (base == 16)
112 ch1 |= 0x20;
113 if ((ch1 < 'a') || ((ch1 > 'f'))) break;
114 num = base * num + 10 + (ch1 - 'a');
116 else break;
117 p++;
120 *ch = (char) num;
121 return p;
124 void SLexpand_escaped_string (register char *s, register char *t,
125 register char *tmax)
127 char ch;
129 while (t < tmax)
131 ch = *t++;
132 if (ch == '\\')
134 t = SLexpand_escaped_char (t, &ch);
136 *s++ = ch;
138 *s = 0;
142 int SLang_extract_token (char **linep, char *word_parm, int byte_comp)
144 register char ch, *line, *word = word_parm;
145 int string;
146 char ch1;
147 char *word_max;
149 word_max = word + 250;
151 line = *linep;
153 /* skip white space */
154 while (((ch = *line) == ' ')
155 || (ch == '\t')) line++;
157 if ((!ch) || (ch == '\n'))
159 *linep = line;
160 return(0);
163 *word++ = ch;
164 line++;
166 /* Look for -something and rule out --something and -= something */
167 if ((ch == '-') &&
168 (*line != '-') && (*line != '=') && ((*line > '9') || (*line < '0')))
170 *word = 0;
171 *linep = line;
172 return 1;
176 if (ch == '"') string = 1; else string = 0;
177 if (ch == '\'')
179 if ((ch = *line++) != 0)
181 if (ch == '\\')
183 line = SLexpand_escaped_char(line, &ch1);
184 ch = ch1;
186 if (*line++ == '\'')
188 --word;
189 sprintf(word, "%d", (int) ((unsigned char) ch));
190 word += strlen (word); ch = '\'';
192 else SLang_Error = SYNTAX_ERROR;
194 else SLang_Error = SYNTAX_ERROR;
196 else if (!special_chars[(unsigned char) ch])
198 while (ch = *line++,
199 (ch > '"') ||
200 ((ch != '\n') && (ch != 0) && (ch != '"')))
202 if (string)
204 if (ch == '\\')
206 ch = *line++;
207 if ((ch == 0) || (ch == '\n')) break;
208 if (byte_comp) *word++ = '\\';
209 else
211 line = SLexpand_escaped_char(line - 1, &ch1);
212 ch = ch1;
216 else if (special_chars[(unsigned char) ch])
218 line--;
219 break;
222 *word++ = ch;
223 if (word > word_max)
225 SLang_doerror ("Token to large.");
226 break;
231 if ((!ch) || (ch == '\n')) line--;
232 if ((ch == '"') && string) *word++ = '"'; else if (string) SLang_Error = SYNTAX_ERROR;
233 *word = 0;
234 *linep = line;
235 /* massage variable-- and ++ into --variable, etc... */
236 if (((int) (word - word_parm) > 2)
237 && (ch = *(word - 1), (ch == '+') || (ch == '-'))
238 && (ch == *(word - 2)))
240 word--;
241 while (word >= word_parm + 2)
243 *word = *(word - 2);
244 word--;
246 *word-- = ch;
247 *word-- = ch;
249 return(1);
253 int SLang_guess_type (char *t)
255 char *p;
256 register char ch;
258 if (*t == '-') t++;
259 p = t;
260 #ifdef FLOAT_TYPE
261 if (*p != '.')
263 #endif
264 while ((*p >= '0') && (*p <= '9')) p++;
265 if (t == p) return(STRING_TYPE);
266 if ((*p == 'x') && (p == t + 1)) /* 0x?? */
268 p++;
269 while (ch = *p,
270 ((ch >= '0') && (ch <= '9'))
271 || (((ch | 0x20) >= 'a') && ((ch | 0x20) <= 'f'))) p++;
273 if (*p == 0) return(INT_TYPE);
274 #ifndef FLOAT_TYPE
275 return(STRING_TYPE);
276 #else
279 /* now down to float case */
280 if (*p == '.')
282 p++;
283 while ((*p >= '0') && (*p <= '9')) p++;
285 if (*p == 0) return(FLOAT_TYPE);
286 if ((*p != 'e') && (*p != 'E')) return(STRING_TYPE);
287 p++;
288 if ((*p == '-') || (*p == '+')) p++;
289 while ((*p >= '0') && (*p <= '9')) p++;
290 if (*p != 0) return(STRING_TYPE); else return(FLOAT_TYPE);
291 #endif
294 int SLatoi (unsigned char *s)
296 register unsigned char ch;
297 register unsigned int value;
298 register int base;
300 if (*s != '0') return atoi((char *) s);
302 /* look for 'x' which indicates hex */
303 s++;
304 if ((*s | 0x20) == 'x')
306 base = 16;
307 s++;
308 if (*s == 0)
310 SLang_Error = SYNTAX_ERROR;
311 return -1;
314 else base = 8;
317 value = 0;
318 while ((ch = *s++) != 0)
320 char ch1 = ch | 0x20;
321 switch (ch1)
323 default:
324 SLang_Error = SYNTAX_ERROR;
325 break;
326 case '8':
327 case '9':
328 if (base != 16) SLang_Error = SYNTAX_ERROR;
329 /* drop */
330 case '0':
331 case '1':
332 case '2':
333 case '3':
334 case '4':
335 case '5':
336 case '6':
337 case '7':
338 ch1 -= '0';
339 break;
341 case 'a':
342 case 'b':
343 case 'c':
344 case 'd':
345 case 'e':
346 case 'f':
347 if (base != 16) SLang_Error = SYNTAX_ERROR;
348 ch1 = (ch1 - 'a') + 10;
349 break;
351 value = value * base + ch1;
353 return (int) value;