00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "hconfig.h"
00019 #include "system.h"
00020 #include "scan.h"
00021
00022 int lineno = 1;
00023 int source_lineno = 1;
00024 sstring source_filename;
00025
00026 void
00027 make_sstring_space (str, count)
00028 sstring *str;
00029 int count;
00030 {
00031 int cur_pos = str->ptr - str->base;
00032 int cur_size = str->limit - str->base;
00033 int new_size = cur_pos + count + 100;
00034
00035 if (new_size <= cur_size)
00036 return;
00037
00038 str->base = xrealloc (str->base, new_size);
00039 str->ptr = str->base + cur_size;
00040 str->limit = str->base + new_size;
00041 }
00042
00043 void
00044 sstring_append (dst, src)
00045 sstring *dst;
00046 sstring *src;
00047 {
00048 char *d, *s;
00049 int count = SSTRING_LENGTH (src);
00050
00051 MAKE_SSTRING_SPACE (dst, count + 1);
00052 d = dst->ptr;
00053 s = src->base;
00054 while (--count >= 0) *d++ = *s++;
00055 dst->ptr = d;
00056 *d = 0;
00057 }
00058
00059 int
00060 scan_ident (fp, s, c)
00061 FILE *fp;
00062 sstring *s;
00063 int c;
00064 {
00065 s->ptr = s->base;
00066 if (ISIDST (c))
00067 {
00068 for (;;)
00069 {
00070 SSTRING_PUT (s, c);
00071 c = getc (fp);
00072 if (c == EOF || ! ISIDNUM (c))
00073 break;
00074 }
00075 }
00076 MAKE_SSTRING_SPACE (s, 1);
00077 *s->ptr = 0;
00078 return c;
00079 }
00080
00081 int
00082 scan_string (fp, s, init)
00083 FILE *fp;
00084 sstring *s;
00085 int init;
00086 {
00087 int c;
00088
00089 for (;;)
00090 {
00091 c = getc (fp);
00092 if (c == EOF || c == '\n')
00093 break;
00094 if (c == init)
00095 {
00096 c = getc (fp);
00097 break;
00098 }
00099 if (c == '\\')
00100 {
00101 c = getc (fp);
00102 if (c == EOF)
00103 break;
00104 if (c == '\n')
00105 continue;
00106 }
00107 SSTRING_PUT (s, c);
00108 }
00109 MAKE_SSTRING_SPACE (s, 1);
00110 *s->ptr = 0;
00111 return c;
00112 }
00113
00114
00115
00116 int
00117 skip_spaces (fp, c)
00118 FILE *fp;
00119 int c;
00120 {
00121 for (;;)
00122 {
00123 if (c == ' ' || c == '\t')
00124 c = getc (fp);
00125 else if (c == '/')
00126 {
00127 c = getc (fp);
00128 if (c != '*')
00129 {
00130 ungetc (c, fp);
00131 return '/';
00132 }
00133 c = getc (fp);
00134 for (;;)
00135 {
00136 if (c == EOF)
00137 return EOF;
00138 else if (c != '*')
00139 {
00140 if (c == '\n')
00141 source_lineno++, lineno++;
00142 c = getc (fp);
00143 }
00144 else if ((c = getc (fp)) == '/')
00145 return getc (fp);
00146 }
00147 }
00148 else
00149 break;
00150 }
00151 return c;
00152 }
00153
00154 int
00155 read_upto (fp, str, delim)
00156 FILE *fp;
00157 sstring *str;
00158 int delim;
00159 {
00160 int ch;
00161
00162 for (;;)
00163 {
00164 ch = getc (fp);
00165 if (ch == EOF || ch == delim)
00166 break;
00167 SSTRING_PUT (str, ch);
00168 }
00169 MAKE_SSTRING_SPACE (str, 1);
00170 *str->ptr = 0;
00171 return ch;
00172 }
00173
00174 int
00175 get_token (fp, s)
00176 FILE *fp;
00177 sstring *s;
00178 {
00179 int c;
00180
00181 s->ptr = s->base;
00182 retry:
00183 c = ' ';
00184 c = skip_spaces (fp, c);
00185 if (c == '\n')
00186 {
00187 source_lineno++;
00188 lineno++;
00189 goto retry;
00190 }
00191 if (c == '#')
00192 {
00193 c = get_token (fp, s);
00194 if (c == INT_TOKEN)
00195 {
00196 source_lineno = atoi (s->base) - 1;
00197 get_token (fp, &source_filename);
00198 }
00199 for (;;)
00200 {
00201 c = getc (fp);
00202 if (c == EOF)
00203 return EOF;
00204 if (c == '\n')
00205 {
00206 source_lineno++;
00207 lineno++;
00208 goto retry;
00209 }
00210 }
00211 }
00212 if (c == EOF)
00213 return EOF;
00214 if (ISDIGIT (c))
00215 {
00216 do
00217 {
00218 SSTRING_PUT (s, c);
00219 c = getc (fp);
00220 } while (c != EOF && ISDIGIT (c));
00221 ungetc (c, fp);
00222 c = INT_TOKEN;
00223 goto done;
00224 }
00225 if (ISIDST (c))
00226 {
00227 c = scan_ident (fp, s, c);
00228 ungetc (c, fp);
00229 return IDENTIFIER_TOKEN;
00230 }
00231 if (c == '\'' || c == '"')
00232 {
00233 c = scan_string (fp, s, c);
00234 ungetc (c, fp);
00235 return c == '\'' ? CHAR_TOKEN : STRING_TOKEN;
00236 }
00237 SSTRING_PUT (s, c);
00238 done:
00239 MAKE_SSTRING_SPACE (s, 1);
00240 *s->ptr = 0;
00241 return c;
00242 }
00243
00244 unsigned int
00245 hashstr (str, len)
00246 const char *str;
00247 unsigned int len;
00248 {
00249 unsigned int n = len;
00250 unsigned int r = 0;
00251 const unsigned char *s = (const unsigned char *) str;
00252
00253 do
00254 r = r * 67 + (*s++ - 113);
00255 while (--n);
00256 return r + len;
00257 }