/*--------------------------------*-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 #ifdef HAVE_STDLIB_H # include #endif #include #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; }