/* Utility functions for scan-decls and fix-header programs. Copyright (C) 1993, 1994, 1998 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "hconfig.h" #include "system.h" #include "scan.h" int lineno = 1; int source_lineno = 1; sstring source_filename; void make_sstring_space (str, count) sstring *str; int count; { int cur_pos = str->ptr - str->base; int cur_size = str->limit - str->base; int new_size = cur_pos + count + 100; if (new_size <= cur_size) return; if (str->base == NULL) str->base = xmalloc (new_size); else str->base = xrealloc (str->base, new_size); str->ptr = str->base + cur_size; str->limit = str->base + new_size; } void sstring_append (dst, src) sstring *dst; sstring *src; { register char *d, *s; register int count = SSTRING_LENGTH(src); MAKE_SSTRING_SPACE(dst, count + 1); d = dst->ptr; s = src->base; while (--count >= 0) *d++ = *s++; dst->ptr = d; *d = 0; } int scan_ident (fp, s, c) register FILE *fp; register sstring *s; int c; { s->ptr = s->base; if (ISALPHA(c) || c == '_') { for (;;) { SSTRING_PUT(s, c); c = getc (fp); if (c == EOF || !(ISALNUM(c) || c == '_')) break; } } MAKE_SSTRING_SPACE(s, 1); *s->ptr = 0; return c; } int scan_string (fp, s, init) register FILE *fp; register sstring *s; int init; { int c; for (;;) { c = getc (fp); if (c == EOF || c == '\n') break; if (c == init) { c = getc (fp); break; } if (c == '\\') { c = getc (fp); if (c == EOF) break; if (c == '\n') continue; } SSTRING_PUT(s, c); } MAKE_SSTRING_SPACE(s, 1); *s->ptr = 0; return c; } /* Skip horizontal white spaces (spaces, tabs, and C-style comments). */ int skip_spaces (fp, c) register FILE *fp; int c; { for (;;) { if (c == ' ' || c == '\t') c = getc (fp); else if (c == '/') { c = getc (fp); if (c != '*') { ungetc (c, fp); return '/'; } c = getc (fp); for (;;) { if (c == EOF) return EOF; else if (c != '*') { if (c == '\n') source_lineno++, lineno++; c = getc (fp); } else if ((c = getc (fp)) == '/') return getc (fp); } } else break; } return c; } int read_upto (fp, str, delim) FILE *fp; sstring *str; int delim; { int ch; for (;;) { ch = getc (fp); if (ch == EOF || ch == delim) break; SSTRING_PUT(str, ch); } MAKE_SSTRING_SPACE(str, 1); *str->ptr = 0; return ch; } int get_token (fp, s) register FILE *fp; register sstring *s; { int c; s->ptr = s->base; retry: c = ' '; c = skip_spaces (fp, c); if (c == '\n') { source_lineno++; lineno++; goto retry; } if (c == '#') { c = get_token (fp, s); if (c == INT_TOKEN) { source_lineno = atoi (s->base) - 1; /* '\n' will add 1 */ get_token (fp, &source_filename); } for (;;) { c = getc (fp); if (c == EOF) return EOF; if (c == '\n') { source_lineno++; lineno++; goto retry; } } } if (c == EOF) return EOF; if (ISDIGIT (c)) { do { SSTRING_PUT(s, c); c = getc (fp); } while (c != EOF && ISDIGIT(c)); ungetc (c, fp); c = INT_TOKEN; goto done; } if (ISALPHA (c) || c == '_') { c = scan_ident (fp, s, c); ungetc (c, fp); return IDENTIFIER_TOKEN; } if (c == '\'' || c == '"') { c = scan_string (fp, s, c); ungetc (c, fp); return c == '\'' ? CHAR_TOKEN : STRING_TOKEN; } SSTRING_PUT(s, c); done: MAKE_SSTRING_SPACE(s, 1); *s->ptr = 0; return c; }