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