118334Speter/* Utility functions for scan-decls and fix-header programs.
2132718Skan   Copyright (C) 1993, 1994, 1998, 2002, 2003 Free Software Foundation, Inc.
318334Speter
418334SpeterThis program is free software; you can redistribute it and/or modify it
518334Speterunder the terms of the GNU General Public License as published by the
618334SpeterFree Software Foundation; either version 2, or (at your option) any
718334Speterlater version.
818334Speter
918334SpeterThis program is distributed in the hope that it will be useful,
1018334Speterbut WITHOUT ANY WARRANTY; without even the implied warranty of
1118334SpeterMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1218334SpeterGNU General Public License for more details.
1318334Speter
1418334SpeterYou should have received a copy of the GNU General Public License
1518334Speteralong with this program; if not, write to the Free Software
16169689SkanFoundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
1718334Speter
18132718Skan#include "bconfig.h"
1950397Sobrien#include "system.h"
20132718Skan#include "coretypes.h"
21132718Skan#include "tm.h"
2218334Speter#include "scan.h"
2318334Speter
2418334Speterint lineno = 1;
2518334Speterint source_lineno = 1;
2618334Spetersstring source_filename;
2718334Speter
2818334Spetervoid
29132718Skanmake_sstring_space (sstring *str, int count)
3018334Speter{
3118334Speter  int cur_pos = str->ptr - str->base;
3218334Speter  int cur_size = str->limit - str->base;
3318334Speter  int new_size = cur_pos + count + 100;
3418334Speter
3518334Speter  if (new_size <= cur_size)
3618334Speter    return;
37117395Skan
3890075Sobrien  str->base = xrealloc (str->base, new_size);
3918334Speter  str->ptr = str->base + cur_size;
4018334Speter  str->limit = str->base + new_size;
4118334Speter}
4218334Speter
4318334Spetervoid
44132718Skansstring_append (sstring *dst, sstring *src)
4518334Speter{
4690075Sobrien  char *d, *s;
4790075Sobrien  int count = SSTRING_LENGTH (src);
4890075Sobrien
4990075Sobrien  MAKE_SSTRING_SPACE (dst, count + 1);
5018334Speter  d = dst->ptr;
5118334Speter  s = src->base;
5218334Speter  while (--count >= 0) *d++ = *s++;
5318334Speter  dst->ptr = d;
54117395Skan  *d = 0;
5518334Speter}
5618334Speter
5718334Speterint
58132718Skanscan_ident (FILE *fp, sstring *s, int c)
5918334Speter{
6018334Speter  s->ptr = s->base;
6190075Sobrien  if (ISIDST (c))
6218334Speter    {
6318334Speter      for (;;)
6418334Speter	{
6590075Sobrien	  SSTRING_PUT (s, c);
6618334Speter	  c = getc (fp);
6790075Sobrien	  if (c == EOF || ! ISIDNUM (c))
6818334Speter	    break;
6918334Speter	}
7018334Speter    }
7190075Sobrien  MAKE_SSTRING_SPACE (s, 1);
7218334Speter  *s->ptr = 0;
7318334Speter  return c;
7418334Speter}
7518334Speter
7618334Speterint
77132718Skanscan_string (FILE *fp, sstring *s, int init)
7818334Speter{
7918334Speter  int c;
8090075Sobrien
8118334Speter  for (;;)
8218334Speter    {
8318334Speter      c = getc (fp);
8418334Speter      if (c == EOF || c == '\n')
8518334Speter	break;
8618334Speter      if (c == init)
8718334Speter	{
8818334Speter	  c = getc (fp);
8918334Speter	  break;
9018334Speter	}
9118334Speter      if (c == '\\')
9218334Speter	{
9318334Speter	  c = getc (fp);
9418334Speter	  if (c == EOF)
9518334Speter	    break;
9618334Speter	  if (c == '\n')
9718334Speter	    continue;
9818334Speter	}
9990075Sobrien      SSTRING_PUT (s, c);
10018334Speter    }
10190075Sobrien  MAKE_SSTRING_SPACE (s, 1);
10218334Speter  *s->ptr = 0;
10318334Speter  return c;
10418334Speter}
10518334Speter
10650397Sobrien/* Skip horizontal white spaces (spaces, tabs, and C-style comments).  */
10718334Speter
10818334Speterint
109132718Skanskip_spaces (FILE *fp, int c)
11018334Speter{
11118334Speter  for (;;)
11218334Speter    {
11318334Speter      if (c == ' ' || c == '\t')
11418334Speter	c = getc (fp);
11518334Speter      else if (c == '/')
11618334Speter	{
11718334Speter	  c = getc (fp);
11818334Speter	  if (c != '*')
11918334Speter	    {
12018334Speter	      ungetc (c, fp);
12118334Speter	      return '/';
12218334Speter	    }
12318334Speter	  c = getc (fp);
12418334Speter	  for (;;)
12518334Speter	    {
12618334Speter	      if (c == EOF)
12718334Speter		return EOF;
12818334Speter	      else if (c != '*')
12918334Speter		{
13018334Speter		  if (c == '\n')
13118334Speter		    source_lineno++, lineno++;
13218334Speter		  c = getc (fp);
13318334Speter		}
13418334Speter	      else if ((c = getc (fp)) == '/')
13518334Speter		return getc (fp);
13618334Speter	    }
13718334Speter	}
13818334Speter      else
13918334Speter	break;
14018334Speter    }
14118334Speter  return c;
14218334Speter}
14318334Speter
14418334Speterint
145132718Skanread_upto (FILE *fp, sstring *str, int delim)
14618334Speter{
14718334Speter  int ch;
14890075Sobrien
14918334Speter  for (;;)
15018334Speter    {
15118334Speter      ch = getc (fp);
15218334Speter      if (ch == EOF || ch == delim)
15318334Speter	break;
15490075Sobrien      SSTRING_PUT (str, ch);
15518334Speter    }
15690075Sobrien  MAKE_SSTRING_SPACE (str, 1);
15718334Speter  *str->ptr = 0;
15818334Speter  return ch;
15918334Speter}
16018334Speter
16118334Speterint
162132718Skanget_token (FILE *fp, sstring *s)
16318334Speter{
16418334Speter  int c;
16590075Sobrien
16618334Speter  s->ptr = s->base;
16718334Speter retry:
16818334Speter  c = ' ';
16918334Speter  c = skip_spaces (fp, c);
17018334Speter  if (c == '\n')
17118334Speter    {
17218334Speter      source_lineno++;
17318334Speter      lineno++;
17418334Speter      goto retry;
17518334Speter    }
17618334Speter  if (c == '#')
17718334Speter    {
17818334Speter      c = get_token (fp, s);
17918334Speter      if (c == INT_TOKEN)
18018334Speter	{
18118334Speter	  source_lineno = atoi (s->base) - 1; /* '\n' will add 1 */
18218334Speter	  get_token (fp, &source_filename);
18318334Speter	}
18418334Speter      for (;;)
18518334Speter	{
18618334Speter	  c = getc (fp);
18718334Speter	  if (c == EOF)
18818334Speter	    return EOF;
18918334Speter	  if (c == '\n')
19018334Speter	    {
19118334Speter	    source_lineno++;
19218334Speter	    lineno++;
19318334Speter	    goto retry;
19418334Speter	    }
19518334Speter	}
19618334Speter    }
19718334Speter  if (c == EOF)
19818334Speter    return EOF;
19950397Sobrien  if (ISDIGIT (c))
20018334Speter    {
20118334Speter      do
20218334Speter	{
20390075Sobrien	  SSTRING_PUT (s, c);
20418334Speter	  c = getc (fp);
20590075Sobrien	} while (c != EOF && ISDIGIT (c));
20618334Speter      ungetc (c, fp);
20718334Speter      c = INT_TOKEN;
20818334Speter      goto done;
20918334Speter    }
21090075Sobrien  if (ISIDST (c))
21118334Speter    {
21218334Speter      c = scan_ident (fp, s, c);
21318334Speter      ungetc (c, fp);
21418334Speter      return IDENTIFIER_TOKEN;
21518334Speter    }
21618334Speter  if (c == '\'' || c == '"')
21718334Speter    {
21818334Speter      c = scan_string (fp, s, c);
21918334Speter      ungetc (c, fp);
22018334Speter      return c == '\'' ? CHAR_TOKEN : STRING_TOKEN;
22118334Speter    }
22290075Sobrien  SSTRING_PUT (s, c);
22318334Speter done:
22490075Sobrien  MAKE_SSTRING_SPACE (s, 1);
22518334Speter  *s->ptr = 0;
22618334Speter  return c;
22718334Speter}
22890075Sobrien
22990075Sobrienunsigned int
230132718Skanhashstr (const char *str, unsigned int len)
23190075Sobrien{
23290075Sobrien  unsigned int n = len;
23390075Sobrien  unsigned int r = 0;
23490075Sobrien  const unsigned char *s = (const unsigned char *) str;
23590075Sobrien
23690075Sobrien  do
23790075Sobrien    r = r * 67 + (*s++ - 113);
23890075Sobrien  while (--n);
23990075Sobrien  return r + len;
24090075Sobrien}
241