scan.c revision 132718
1/* Utility functions for scan-decls and fix-header programs. 2 Copyright (C) 1993, 1994, 1998, 2002, 2003 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 "bconfig.h" 19#include "system.h" 20#include "coretypes.h" 21#include "tm.h" 22#include "scan.h" 23 24int lineno = 1; 25int source_lineno = 1; 26sstring source_filename; 27 28void 29make_sstring_space (sstring *str, 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 (sstring *dst, sstring *src) 45{ 46 char *d, *s; 47 int count = SSTRING_LENGTH (src); 48 49 MAKE_SSTRING_SPACE (dst, count + 1); 50 d = dst->ptr; 51 s = src->base; 52 while (--count >= 0) *d++ = *s++; 53 dst->ptr = d; 54 *d = 0; 55} 56 57int 58scan_ident (FILE *fp, sstring *s, int c) 59{ 60 s->ptr = s->base; 61 if (ISIDST (c)) 62 { 63 for (;;) 64 { 65 SSTRING_PUT (s, c); 66 c = getc (fp); 67 if (c == EOF || ! ISIDNUM (c)) 68 break; 69 } 70 } 71 MAKE_SSTRING_SPACE (s, 1); 72 *s->ptr = 0; 73 return c; 74} 75 76int 77scan_string (FILE *fp, sstring *s, int init) 78{ 79 int c; 80 81 for (;;) 82 { 83 c = getc (fp); 84 if (c == EOF || c == '\n') 85 break; 86 if (c == init) 87 { 88 c = getc (fp); 89 break; 90 } 91 if (c == '\\') 92 { 93 c = getc (fp); 94 if (c == EOF) 95 break; 96 if (c == '\n') 97 continue; 98 } 99 SSTRING_PUT (s, c); 100 } 101 MAKE_SSTRING_SPACE (s, 1); 102 *s->ptr = 0; 103 return c; 104} 105 106/* Skip horizontal white spaces (spaces, tabs, and C-style comments). */ 107 108int 109skip_spaces (FILE *fp, int c) 110{ 111 for (;;) 112 { 113 if (c == ' ' || c == '\t') 114 c = getc (fp); 115 else if (c == '/') 116 { 117 c = getc (fp); 118 if (c != '*') 119 { 120 ungetc (c, fp); 121 return '/'; 122 } 123 c = getc (fp); 124 for (;;) 125 { 126 if (c == EOF) 127 return EOF; 128 else if (c != '*') 129 { 130 if (c == '\n') 131 source_lineno++, lineno++; 132 c = getc (fp); 133 } 134 else if ((c = getc (fp)) == '/') 135 return getc (fp); 136 } 137 } 138 else 139 break; 140 } 141 return c; 142} 143 144int 145read_upto (FILE *fp, sstring *str, int delim) 146{ 147 int ch; 148 149 for (;;) 150 { 151 ch = getc (fp); 152 if (ch == EOF || ch == delim) 153 break; 154 SSTRING_PUT (str, ch); 155 } 156 MAKE_SSTRING_SPACE (str, 1); 157 *str->ptr = 0; 158 return ch; 159} 160 161int 162get_token (FILE *fp, sstring *s) 163{ 164 int c; 165 166 s->ptr = s->base; 167 retry: 168 c = ' '; 169 c = skip_spaces (fp, c); 170 if (c == '\n') 171 { 172 source_lineno++; 173 lineno++; 174 goto retry; 175 } 176 if (c == '#') 177 { 178 c = get_token (fp, s); 179 if (c == INT_TOKEN) 180 { 181 source_lineno = atoi (s->base) - 1; /* '\n' will add 1 */ 182 get_token (fp, &source_filename); 183 } 184 for (;;) 185 { 186 c = getc (fp); 187 if (c == EOF) 188 return EOF; 189 if (c == '\n') 190 { 191 source_lineno++; 192 lineno++; 193 goto retry; 194 } 195 } 196 } 197 if (c == EOF) 198 return EOF; 199 if (ISDIGIT (c)) 200 { 201 do 202 { 203 SSTRING_PUT (s, c); 204 c = getc (fp); 205 } while (c != EOF && ISDIGIT (c)); 206 ungetc (c, fp); 207 c = INT_TOKEN; 208 goto done; 209 } 210 if (ISIDST (c)) 211 { 212 c = scan_ident (fp, s, c); 213 ungetc (c, fp); 214 return IDENTIFIER_TOKEN; 215 } 216 if (c == '\'' || c == '"') 217 { 218 c = scan_string (fp, s, c); 219 ungetc (c, fp); 220 return c == '\'' ? CHAR_TOKEN : STRING_TOKEN; 221 } 222 SSTRING_PUT (s, c); 223 done: 224 MAKE_SSTRING_SPACE (s, 1); 225 *s->ptr = 0; 226 return c; 227} 228 229unsigned int 230hashstr (const char *str, unsigned int len) 231{ 232 unsigned int n = len; 233 unsigned int r = 0; 234 const unsigned char *s = (const unsigned char *) str; 235 236 do 237 r = r * 67 + (*s++ - 113); 238 while (--n); 239 return r + len; 240} 241