123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355 |
- /*--------------------------------*-C-*---------------------------------*
- * File: sltoken.c
- *
- * Descript: ---
- *
- * Requires: ---
- *
- * Public: SLexpand_escaped_char ();
- * SLexpand_escaped_string ();
- * SLang_extract_token ();
- * SLang_guess_type ();
- * SLatoi ();
- *
- * Private: ---
- *
- * Notes: ---
- *
- * Copyright (c) 1992, 1995 John E. Davis
- * All rights reserved.
- *
- * You may distribute under the terms of either the GNU General Public
- * License or the Perl Artistic License.
- \*----------------------------------------------------------------------*/
- #include "config.h"
- #include <stdio.h>
- #ifdef HAVE_STDLIB_H
- # include <stdlib.h>
- #endif
- #include <string.h>
- #include "slang.h"
- #include "_slang.h"
- /* There are non-zeros at positions "\t %()*,/:;[]{}" */
- static unsigned char special_chars[256] =
- {
- /* 0 */ 0,0,0,0,0,0,0,0, 0,'\t',0,0,0,0,0,0,
- /* 16 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- /* 32 */ ' ',0,0,0,0,'%',0,0, '(',')','*',0,',',0,0,'/',
- /* 48 */ 0,0,0,0,0,0,0,0, 0,0,':',';',0,0,0,0,
- /* 64 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- /* 80 */ 0,0,0,0,0,0,0,0, 0,0,0,'[',0,']',0,0,
- /* 96 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- /* 112 */ 0,0,0,0,0,0,0,0, 0,0,0,'{',0,'}',0,0,
- /* 8-bit characters */
- /* 128 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- /* 144 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- /* 160 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- /* 176 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- /* 192 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- /* 208 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- /* 224 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
- /* 240 */ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0
- };
- char *SLexpand_escaped_char(char *p, char *ch)
- {
- int i = 0;
- int max = 0, num, base = 0;
- char ch1;
-
- ch1 = *p++;
-
- switch (ch1)
- {
- default: num = ch1; break;
- case 'n': num = '\n'; break;
- case 't': num = '\t'; break;
- case 'v': num = '\v'; break;
- case 'b': num = '\b'; break;
- case 'r': num = '\r'; break;
- case 'f': num = '\f'; break;
- case 'E': case 'e': num = 27; break;
- case 'a': num = 7;
- break;
-
- /* octal */
- case '0': case '1': case '2': case '3':
- case '4': case '5': case '6': case '7':
- max = '7';
- base = 8; i = 2; num = ch1 - '0';
- break;
-
- case 'd': /* decimal -- S-Lang extension */
- base = 10;
- i = 3;
- max = '9';
- num = 0;
- break;
-
- case 'x': /* hex */
- base = 16;
- max = '9';
- i = 2;
- num = 0;
- break;
- }
-
- while (i--)
- {
- ch1 = *p;
-
- if ((ch1 <= max) && (ch1 >= '0'))
- {
- num = base * num + (ch1 - '0');
- }
- else if (base == 16)
- {
- ch1 |= 0x20;
- if ((ch1 < 'a') || ((ch1 > 'f'))) break;
- num = base * num + 10 + (ch1 - 'a');
- }
- else break;
- p++;
- }
-
- *ch = (char) num;
- return p;
- }
- void SLexpand_escaped_string (register char *s, register char *t,
- register char *tmax)
- {
- char ch;
-
- while (t < tmax)
- {
- ch = *t++;
- if (ch == '\\')
- {
- t = SLexpand_escaped_char (t, &ch);
- }
- *s++ = ch;
- }
- *s = 0;
- }
- int SLang_extract_token (char **linep, char *word_parm, int byte_comp)
- {
- register char ch, *line, *word = word_parm;
- int string;
- char ch1;
- char *word_max;
-
- word_max = word + 250;
-
- line = *linep;
- /* skip white space */
- while (((ch = *line) == ' ')
- || (ch == '\t')) line++;
- if ((!ch) || (ch == '\n'))
- {
- *linep = line;
- return(0);
- }
-
- *word++ = ch;
- line++;
-
- /* Look for -something and rule out --something and -= something */
- if ((ch == '-') &&
- (*line != '-') && (*line != '=') && ((*line > '9') || (*line < '0')))
- {
- *word = 0;
- *linep = line;
- return 1;
- }
-
-
- if (ch == '"') string = 1; else string = 0;
- if (ch == '\'')
- {
- if ((ch = *line++) != 0)
- {
- if (ch == '\\')
- {
- line = SLexpand_escaped_char(line, &ch1);
- ch = ch1;
- }
- if (*line++ == '\'')
- {
- --word;
- sprintf(word, "%d", (int) ((unsigned char) ch));
- word += strlen (word); ch = '\'';
- }
- else SLang_Error = SYNTAX_ERROR;
- }
- else SLang_Error = SYNTAX_ERROR;
- }
- else if (!special_chars[(unsigned char) ch])
- {
- while (ch = *line++,
- (ch > '"') ||
- ((ch != '\n') && (ch != 0) && (ch != '"')))
- {
- if (string)
- {
- if (ch == '\\')
- {
- ch = *line++;
- if ((ch == 0) || (ch == '\n')) break;
- if (byte_comp) *word++ = '\\';
- else
- {
- line = SLexpand_escaped_char(line - 1, &ch1);
- ch = ch1;
- }
- }
- }
- else if (special_chars[(unsigned char) ch])
- {
- line--;
- break;
- }
-
- *word++ = ch;
- if (word > word_max)
- {
- SLang_doerror ("Token to large.");
- break;
- }
- }
- }
-
- if ((!ch) || (ch == '\n')) line--;
- if ((ch == '"') && string) *word++ = '"'; else if (string) SLang_Error = SYNTAX_ERROR;
- *word = 0;
- *linep = line;
- /* massage variable-- and ++ into --variable, etc... */
- if (((int) (word - word_parm) > 2)
- && (ch = *(word - 1), (ch == '+') || (ch == '-'))
- && (ch == *(word - 2)))
- {
- word--;
- while (word >= word_parm + 2)
- {
- *word = *(word - 2);
- word--;
- }
- *word-- = ch;
- *word-- = ch;
- }
- return(1);
- }
- int SLang_guess_type (char *t)
- {
- char *p;
- register char ch;
- if (*t == '-') t++;
- p = t;
- #ifdef FLOAT_TYPE
- if (*p != '.')
- {
- #endif
- while ((*p >= '0') && (*p <= '9')) p++;
- if (t == p) return(STRING_TYPE);
- if ((*p == 'x') && (p == t + 1)) /* 0x?? */
- {
- p++;
- while (ch = *p,
- ((ch >= '0') && (ch <= '9'))
- || (((ch | 0x20) >= 'a') && ((ch | 0x20) <= 'f'))) p++;
- }
- if (*p == 0) return(INT_TYPE);
- #ifndef FLOAT_TYPE
- return(STRING_TYPE);
- #else
- }
-
- /* now down to float case */
- if (*p == '.')
- {
- p++;
- while ((*p >= '0') && (*p <= '9')) p++;
- }
- if (*p == 0) return(FLOAT_TYPE);
- if ((*p != 'e') && (*p != 'E')) return(STRING_TYPE);
- p++;
- if ((*p == '-') || (*p == '+')) p++;
- while ((*p >= '0') && (*p <= '9')) p++;
- if (*p != 0) return(STRING_TYPE); else return(FLOAT_TYPE);
- #endif
- }
- int SLatoi (unsigned char *s)
- {
- register unsigned char ch;
- register unsigned int value;
- register int base;
-
- if (*s != '0') return atoi((char *) s);
- /* look for 'x' which indicates hex */
- s++;
- if ((*s | 0x20) == 'x')
- {
- base = 16;
- s++;
- if (*s == 0)
- {
- SLang_Error = SYNTAX_ERROR;
- return -1;
- }
- }
- else base = 8;
-
-
- value = 0;
- while ((ch = *s++) != 0)
- {
- char ch1 = ch | 0x20;
- switch (ch1)
- {
- default:
- SLang_Error = SYNTAX_ERROR;
- break;
- case '8':
- case '9':
- if (base != 16) SLang_Error = SYNTAX_ERROR;
- /* drop */
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- ch1 -= '0';
- break;
-
- case 'a':
- case 'b':
- case 'c':
- case 'd':
- case 'e':
- case 'f':
- if (base != 16) SLang_Error = SYNTAX_ERROR;
- ch1 = (ch1 - 'a') + 10;
- break;
- }
- value = value * base + ch1;
- }
- return (int) value;
- }
|