OSDN Git Service

gcc/
[pf3gnuchains/gcc-fork.git] / gcc / scan.c
1 /* Utility functions for scan-decls and fix-header programs.
2    Copyright (C) 1993, 1994, 1998, 2002, 2003, 2007, 2008
3    Free Software Foundation, Inc.
4
5    This program is free software; you can redistribute it and/or modify it
6    under the terms of the GNU General Public License as published by the
7    Free Software Foundation; either version 3, or (at your option) any
8    later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; see the file COPYING3.  If not see
17    <http://www.gnu.org/licenses/>.  */
18
19 #include "bconfig.h"
20 #include "system.h"
21 #include "coretypes.h"
22 #include "tm.h"
23 #include "scan.h"
24
25 int lineno = 1;
26 int source_lineno = 1;
27 sstring source_filename;
28
29 void
30 make_sstring_space (sstring *str, int count)
31 {
32   int cur_pos = str->ptr - str->base;
33   int cur_size = str->limit - str->base;
34   int new_size = cur_pos + count + 100;
35
36   if (new_size <= cur_size)
37     return;
38
39   str->base = (char *) xrealloc (str->base, new_size);
40   str->ptr = str->base + cur_size;
41   str->limit = str->base + new_size;
42 }
43
44 void
45 sstring_append (sstring *dst, sstring *src)
46 {
47   char *d, *s;
48   int count = SSTRING_LENGTH (src);
49
50   MAKE_SSTRING_SPACE (dst, count + 1);
51   d = dst->ptr;
52   s = src->base;
53   while (--count >= 0) *d++ = *s++;
54   dst->ptr = d;
55   *d = 0;
56 }
57
58 int
59 scan_ident (FILE *fp, sstring *s, int c)
60 {
61   s->ptr = s->base;
62   if (ISIDST (c))
63     {
64       for (;;)
65         {
66           SSTRING_PUT (s, c);
67           c = getc (fp);
68           if (c == EOF || ! ISIDNUM (c))
69             break;
70         }
71     }
72   MAKE_SSTRING_SPACE (s, 1);
73   *s->ptr = 0;
74   return c;
75 }
76
77 int
78 scan_string (FILE *fp, sstring *s, int init)
79 {
80   int c;
81
82   for (;;)
83     {
84       c = getc (fp);
85       if (c == EOF || c == '\n')
86         break;
87       if (c == init)
88         {
89           c = getc (fp);
90           break;
91         }
92       if (c == '\\')
93         {
94           c = getc (fp);
95           if (c == EOF)
96             break;
97           if (c == '\n')
98             continue;
99         }
100       SSTRING_PUT (s, c);
101     }
102   MAKE_SSTRING_SPACE (s, 1);
103   *s->ptr = 0;
104   return c;
105 }
106
107 /* Skip horizontal white spaces (spaces, tabs, and C-style comments).  */
108
109 int
110 skip_spaces (FILE *fp, int c)
111 {
112   for (;;)
113     {
114       if (c == ' ' || c == '\t')
115         c = getc (fp);
116       else if (c == '/')
117         {
118           c = getc (fp);
119           if (c != '*')
120             {
121               ungetc (c, fp);
122               return '/';
123             }
124           c = getc (fp);
125           for (;;)
126             {
127               if (c == EOF)
128                 return EOF;
129               else if (c != '*')
130                 {
131                   if (c == '\n')
132                     source_lineno++, lineno++;
133                   c = getc (fp);
134                 }
135               else if ((c = getc (fp)) == '/')
136                 return getc (fp);
137             }
138         }
139       else
140         break;
141     }
142   return c;
143 }
144
145 int
146 read_upto (FILE *fp, sstring *str, int delim)
147 {
148   int ch;
149
150   for (;;)
151     {
152       ch = getc (fp);
153       if (ch == EOF || ch == delim)
154         break;
155       SSTRING_PUT (str, ch);
156     }
157   MAKE_SSTRING_SPACE (str, 1);
158   *str->ptr = 0;
159   return ch;
160 }
161
162 int
163 get_token (FILE *fp, sstring *s)
164 {
165   int c;
166
167   s->ptr = s->base;
168  retry:
169   c = ' ';
170   c = skip_spaces (fp, c);
171   if (c == '\n')
172     {
173       source_lineno++;
174       lineno++;
175       goto retry;
176     }
177   if (c == '#')
178     {
179       c = get_token (fp, s);
180       if (c == INT_TOKEN)
181         {
182           source_lineno = atoi (s->base) - 1; /* '\n' will add 1 */
183           get_token (fp, &source_filename);
184         }
185       for (;;)
186         {
187           c = getc (fp);
188           if (c == EOF)
189             return EOF;
190           if (c == '\n')
191             {
192             source_lineno++;
193             lineno++;
194             goto retry;
195             }
196         }
197     }
198   if (c == EOF)
199     return EOF;
200   if (ISDIGIT (c))
201     {
202       do
203         {
204           SSTRING_PUT (s, c);
205           c = getc (fp);
206         } while (c != EOF && ISDIGIT (c));
207       ungetc (c, fp);
208       c = INT_TOKEN;
209       goto done;
210     }
211   if (ISIDST (c))
212     {
213       c = scan_ident (fp, s, c);
214       ungetc (c, fp);
215       return IDENTIFIER_TOKEN;
216     }
217   if (c == '\'' || c == '"')
218     {
219       c = scan_string (fp, s, c);
220       ungetc (c, fp);
221       return c == '\'' ? CHAR_TOKEN : STRING_TOKEN;
222     }
223   SSTRING_PUT (s, c);
224  done:
225   MAKE_SSTRING_SPACE (s, 1);
226   *s->ptr = 0;
227   return c;
228 }
229
230 unsigned int
231 hashstr (const char *str, unsigned int len)
232 {
233   unsigned int n = len;
234   unsigned int r = 0;
235   const unsigned char *s = (const unsigned char *) str;
236
237   do
238     r = r * 67 + (*s++ - 113);
239   while (--n);
240   return r + len;
241 }