scan.c revision 117395
1/* Utility functions for scan-decls and fix-header programs. 2 Copyright (C) 1993, 1994, 1998, 2002 Free Software Foundation, Inc. 3 4This program is free software; you can redistribute it and/or modify it 5under the terms of the GNU General Public License as published by the 6Free Software Foundation; either version 2, or (at your option) any 7later version. 8 9This program is distributed in the hope that it will be useful, 10but WITHOUT ANY WARRANTY; without even the implied warranty of 11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12GNU General Public License for more details. 13 14You should have received a copy of the GNU General Public License 15along with this program; if not, write to the Free Software 16Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 17 18#include "hconfig.h" 19#include "system.h" 20#include "scan.h" 21 22int lineno = 1; 23int source_lineno = 1; 24sstring source_filename; 25 26void 27make_sstring_space (str, count) 28 sstring *str; 29 int count; 30{ 31 int cur_pos = str->ptr - str->base; 32 int cur_size = str->limit - str->base; 33 int new_size = cur_pos + count + 100; 34 35 if (new_size <= cur_size) 36 return; 37 38 str->base = xrealloc (str->base, new_size); 39 str->ptr = str->base + cur_size; 40 str->limit = str->base + new_size; 41} 42 43void 44sstring_append (dst, src) 45 sstring *dst; 46 sstring *src; 47{ 48 char *d, *s; 49 int count = SSTRING_LENGTH (src); 50 51 MAKE_SSTRING_SPACE (dst, count + 1); 52 d = dst->ptr; 53 s = src->base; 54 while (--count >= 0) *d++ = *s++; 55 dst->ptr = d; 56 *d = 0; 57} 58 59int 60scan_ident (fp, s, c) 61 FILE *fp; 62 sstring *s; 63 int c; 64{ 65 s->ptr = s->base; 66 if (ISIDST (c)) 67 { 68 for (;;) 69 { 70 SSTRING_PUT (s, c); 71 c = getc (fp); 72 if (c == EOF || ! ISIDNUM (c)) 73 break; 74 } 75 } 76 MAKE_SSTRING_SPACE (s, 1); 77 *s->ptr = 0; 78 return c; 79} 80 81int 82scan_string (fp, s, init) 83 FILE *fp; 84 sstring *s; 85 int init; 86{ 87 int c; 88 89 for (;;) 90 { 91 c = getc (fp); 92 if (c == EOF || c == '\n') 93 break; 94 if (c == init) 95 { 96 c = getc (fp); 97 break; 98 } 99 if (c == '\\') 100 { 101 c = getc (fp); 102 if (c == EOF) 103 break; 104 if (c == '\n') 105 continue; 106 } 107 SSTRING_PUT (s, c); 108 } 109 MAKE_SSTRING_SPACE (s, 1); 110 *s->ptr = 0; 111 return c; 112} 113 114/* Skip horizontal white spaces (spaces, tabs, and C-style comments). */ 115 116int 117skip_spaces (fp, c) 118 FILE *fp; 119 int c; 120{ 121 for (;;) 122 { 123 if (c == ' ' || c == '\t') 124 c = getc (fp); 125 else if (c == '/') 126 { 127 c = getc (fp); 128 if (c != '*') 129 { 130 ungetc (c, fp); 131 return '/'; 132 } 133 c = getc (fp); 134 for (;;) 135 { 136 if (c == EOF) 137 return EOF; 138 else if (c != '*') 139 { 140 if (c == '\n') 141 source_lineno++, lineno++; 142 c = getc (fp); 143 } 144 else if ((c = getc (fp)) == '/') 145 return getc (fp); 146 } 147 } 148 else 149 break; 150 } 151 return c; 152} 153 154int 155read_upto (fp, str, delim) 156 FILE *fp; 157 sstring *str; 158 int delim; 159{ 160 int ch; 161 162 for (;;) 163 { 164 ch = getc (fp); 165 if (ch == EOF || ch == delim) 166 break; 167 SSTRING_PUT (str, ch); 168 } 169 MAKE_SSTRING_SPACE (str, 1); 170 *str->ptr = 0; 171 return ch; 172} 173 174int 175get_token (fp, s) 176 FILE *fp; 177 sstring *s; 178{ 179 int c; 180 181 s->ptr = s->base; 182 retry: 183 c = ' '; 184 c = skip_spaces (fp, c); 185 if (c == '\n') 186 { 187 source_lineno++; 188 lineno++; 189 goto retry; 190 } 191 if (c == '#') 192 { 193 c = get_token (fp, s); 194 if (c == INT_TOKEN) 195 { 196 source_lineno = atoi (s->base) - 1; /* '\n' will add 1 */ 197 get_token (fp, &source_filename); 198 } 199 for (;;) 200 { 201 c = getc (fp); 202 if (c == EOF) 203 return EOF; 204 if (c == '\n') 205 { 206 source_lineno++; 207 lineno++; 208 goto retry; 209 } 210 } 211 } 212 if (c == EOF) 213 return EOF; 214 if (ISDIGIT (c)) 215 { 216 do 217 { 218 SSTRING_PUT (s, c); 219 c = getc (fp); 220 } while (c != EOF && ISDIGIT (c)); 221 ungetc (c, fp); 222 c = INT_TOKEN; 223 goto done; 224 } 225 if (ISIDST (c)) 226 { 227 c = scan_ident (fp, s, c); 228 ungetc (c, fp); 229 return IDENTIFIER_TOKEN; 230 } 231 if (c == '\'' || c == '"') 232 { 233 c = scan_string (fp, s, c); 234 ungetc (c, fp); 235 return c == '\'' ? CHAR_TOKEN : STRING_TOKEN; 236 } 237 SSTRING_PUT (s, c); 238 done: 239 MAKE_SSTRING_SPACE (s, 1); 240 *s->ptr = 0; 241 return c; 242} 243 244unsigned int 245hashstr (str, len) 246 const char *str; 247 unsigned int len; 248{ 249 unsigned int n = len; 250 unsigned int r = 0; 251 const unsigned char *s = (const unsigned char *) str; 252 253 do 254 r = r * 67 + (*s++ - 113); 255 while (--n); 256 return r + len; 257} 258