scan.c 4.27 KB
Newer Older
1
/* Utility functions for scan-decls and fix-header programs.
2
   Copyright (C) 1993, 1994, 1998, 2002, 2003, 2007 Free Software Foundation, Inc.
Per Bothner committed
3

4 5 6 7
   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 3, or (at your option) any
   later version.
Per Bothner committed
8

9 10 11 12
   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.
Per Bothner committed
13

14 15 16
   You should have received a copy of the GNU General Public License
   along with this program; see the file COPYING3.  If not see
   <http://www.gnu.org/licenses/>.  */
Per Bothner committed
17

18
#include "bconfig.h"
19
#include "system.h"
20 21
#include "coretypes.h"
#include "tm.h"
22
#include "scan.h"
Per Bothner committed
23 24 25 26 27 28

int lineno = 1;
int source_lineno = 1;
sstring source_filename;

void
29
make_sstring_space (sstring *str, int count)
Per Bothner committed
30 31 32 33 34 35 36
{
  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;
Kazu Hirata committed
37

38
  str->base = xrealloc (str->base, new_size);
Per Bothner committed
39 40 41 42 43
  str->ptr = str->base + cur_size;
  str->limit = str->base + new_size;
}

void
44
sstring_append (sstring *dst, sstring *src)
Per Bothner committed
45
{
46
  char *d, *s;
Kazu Hirata committed
47
  int count = SSTRING_LENGTH (src);
48

Kazu Hirata committed
49
  MAKE_SSTRING_SPACE (dst, count + 1);
Per Bothner committed
50 51 52 53
  d = dst->ptr;
  s = src->base;
  while (--count >= 0) *d++ = *s++;
  dst->ptr = d;
Kazu Hirata committed
54
  *d = 0;
Per Bothner committed
55 56 57
}

int
58
scan_ident (FILE *fp, sstring *s, int c)
Per Bothner committed
59 60
{
  s->ptr = s->base;
Kazu Hirata committed
61
  if (ISIDST (c))
Per Bothner committed
62 63 64
    {
      for (;;)
	{
Kazu Hirata committed
65
	  SSTRING_PUT (s, c);
Per Bothner committed
66
	  c = getc (fp);
Kazu Hirata committed
67
	  if (c == EOF || ! ISIDNUM (c))
Per Bothner committed
68 69 70
	    break;
	}
    }
Kazu Hirata committed
71
  MAKE_SSTRING_SPACE (s, 1);
Per Bothner committed
72 73 74 75
  *s->ptr = 0;
  return c;
}

76
int
77
scan_string (FILE *fp, sstring *s, int init)
Per Bothner committed
78 79
{
  int c;
80

Per Bothner committed
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
  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;
	}
Kazu Hirata committed
99
      SSTRING_PUT (s, c);
Per Bothner committed
100
    }
Kazu Hirata committed
101
  MAKE_SSTRING_SPACE (s, 1);
Per Bothner committed
102 103 104 105
  *s->ptr = 0;
  return c;
}

Mike Stump committed
106
/* Skip horizontal white spaces (spaces, tabs, and C-style comments).  */
Per Bothner committed
107

108
int
109
skip_spaces (FILE *fp, int c)
Per Bothner committed
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
{
  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
145
read_upto (FILE *fp, sstring *str, int delim)
Per Bothner committed
146 147
{
  int ch;
148

Per Bothner committed
149 150 151 152 153
  for (;;)
    {
      ch = getc (fp);
      if (ch == EOF || ch == delim)
	break;
Kazu Hirata committed
154
      SSTRING_PUT (str, ch);
Per Bothner committed
155
    }
Kazu Hirata committed
156
  MAKE_SSTRING_SPACE (str, 1);
Per Bothner committed
157 158 159 160 161
  *str->ptr = 0;
  return ch;
}

int
162
get_token (FILE *fp, sstring *s)
Per Bothner committed
163 164
{
  int c;
165

Per Bothner committed
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
  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)
	{
Per Bothner committed
181
	  source_lineno = atoi (s->base) - 1; /* '\n' will add 1 */
Per Bothner committed
182 183 184 185 186 187 188 189
	  get_token (fp, &source_filename);
	}
      for (;;)
	{
	  c = getc (fp);
	  if (c == EOF)
	    return EOF;
	  if (c == '\n')
Per Bothner committed
190 191 192
	    {
	    source_lineno++;
	    lineno++;
Per Bothner committed
193
	    goto retry;
Per Bothner committed
194
	    }
Per Bothner committed
195 196 197 198
	}
    }
  if (c == EOF)
    return EOF;
199
  if (ISDIGIT (c))
Per Bothner committed
200 201 202
    {
      do
	{
Kazu Hirata committed
203
	  SSTRING_PUT (s, c);
Per Bothner committed
204
	  c = getc (fp);
Kazu Hirata committed
205
	} while (c != EOF && ISDIGIT (c));
Per Bothner committed
206 207 208 209
      ungetc (c, fp);
      c = INT_TOKEN;
      goto done;
    }
210
  if (ISIDST (c))
Per Bothner committed
211 212 213 214 215 216 217 218 219 220 221
    {
      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;
    }
Kazu Hirata committed
222
  SSTRING_PUT (s, c);
Per Bothner committed
223
 done:
Kazu Hirata committed
224
  MAKE_SSTRING_SPACE (s, 1);
Per Bothner committed
225 226 227
  *s->ptr = 0;
  return c;
}
228 229

unsigned int
230
hashstr (const char *str, unsigned int len)
231 232 233
{
  unsigned int n = len;
  unsigned int r = 0;
Kazu Hirata committed
234
  const unsigned char *s = (const unsigned char *) str;
235 236 237 238 239 240

  do
    r = r * 67 + (*s++ - 113);
  while (--n);
  return r + len;
}