diff options
author | David Walter Seikel | 2012-01-04 18:41:13 +1000 |
---|---|---|
committer | David Walter Seikel | 2012-01-04 18:41:13 +1000 |
commit | dd7595a3475407a7fa96a97393bae8c5220e8762 (patch) | |
tree | e341e911d7eb911a51684a7412ef7f7c7605d28e /libraries/edje/src/bin/epp | |
parent | Add the skeleton. (diff) | |
download | SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.zip SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.gz SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.bz2 SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.xz |
Add the base Enlightenment Foundation Libraries - eina, eet, evas, ecore, embryo, and edje.
Note that embryo wont be used, but I'm not sure yet if you can build edje without it.
Diffstat (limited to 'libraries/edje/src/bin/epp')
-rw-r--r-- | libraries/edje/src/bin/epp/Makefile.am | 59 | ||||
-rw-r--r-- | libraries/edje/src/bin/epp/Makefile.in | 756 | ||||
-rw-r--r-- | libraries/edje/src/bin/epp/cppalloc.c | 70 | ||||
-rw-r--r-- | libraries/edje/src/bin/epp/cpperror.c | 147 | ||||
-rw-r--r-- | libraries/edje/src/bin/epp/cppexp.c | 1090 | ||||
-rw-r--r-- | libraries/edje/src/bin/epp/cpphash.c | 198 | ||||
-rw-r--r-- | libraries/edje/src/bin/epp/cpphash.h | 41 | ||||
-rw-r--r-- | libraries/edje/src/bin/epp/cpplib.c | 7427 | ||||
-rw-r--r-- | libraries/edje/src/bin/epp/cpplib.h | 641 | ||||
-rw-r--r-- | libraries/edje/src/bin/epp/cppmain.c | 142 |
10 files changed, 10571 insertions, 0 deletions
diff --git a/libraries/edje/src/bin/epp/Makefile.am b/libraries/edje/src/bin/epp/Makefile.am new file mode 100644 index 0000000..6db5016 --- /dev/null +++ b/libraries/edje/src/bin/epp/Makefile.am | |||
@@ -0,0 +1,59 @@ | |||
1 | # Makefile for GNU C compiler. | ||
2 | # Copyright (C) 1987, 88, 90-94, 1995 Free Software Foundation, Inc. | ||
3 | |||
4 | #This file is part of GNU CC. | ||
5 | |||
6 | #GNU CC is free software; you can redistribute it and/or modify | ||
7 | #it under the terms of the GNU General Public License as published by | ||
8 | #the Free Software Foundation; either version 2, or (at your option) | ||
9 | #any later version. | ||
10 | |||
11 | #GNU CC is distributed in the hope that it will be useful, | ||
12 | #but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | #GNU General Public License for more details. | ||
15 | |||
16 | #You should have received a copy of the GNU General Public License | ||
17 | #along with GNU CC; see the file COPYING. If not, write to | ||
18 | #the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | |||
20 | MAINTAINERCLEANFILES = Makefile.in | ||
21 | |||
22 | eppdir = @libdir@/@PACKAGE@/utils | ||
23 | |||
24 | epp_PROGRAMS = epp | ||
25 | |||
26 | epp_SOURCES = \ | ||
27 | cpplib.h \ | ||
28 | cpphash.h \ | ||
29 | cppalloc.c \ | ||
30 | cpperror.c \ | ||
31 | cppexp.c \ | ||
32 | cpphash.c \ | ||
33 | cpplib.c \ | ||
34 | cppmain.c | ||
35 | |||
36 | epp_CPPFLAGS = \ | ||
37 | -I$(top_builddir) \ | ||
38 | $(CWARNFLAGS) | ||
39 | |||
40 | DEFS= \ | ||
41 | -DHAVE_CONFIG_H \ | ||
42 | -DHAVE_STRERROR \ | ||
43 | -DFATAL_EXIT_CODE=1 \ | ||
44 | -DSUCCESS_EXIT_CODE=0 \ | ||
45 | -DGCC_INCLUDE_DIR=\"/usr/include\" \ | ||
46 | -DGPLUSPLUS_INCLUDE_DIR=\"/usr/include\" \ | ||
47 | -DTOOL_INCLUDE_DIR=\"/usr/bin\" \ | ||
48 | -DHOST_BITS_PER_LONG=32 \ | ||
49 | -DBITS_PER_UNIT=8 \ | ||
50 | -DHOST_BITS_PER_INT=32 \ | ||
51 | -DBITS_PER_WORD=16 \ | ||
52 | -DTARGET_BELL=7 \ | ||
53 | -DTARGET_BS=8 \ | ||
54 | -DTARGET_FF=12 \ | ||
55 | -DTARGET_NEWLINE=10 \ | ||
56 | -DTARGET_CR=13 \ | ||
57 | -DTARGET_TAB=9 \ | ||
58 | -DTARGET_VT=11 | ||
59 | |||
diff --git a/libraries/edje/src/bin/epp/Makefile.in b/libraries/edje/src/bin/epp/Makefile.in new file mode 100644 index 0000000..2ef2e56 --- /dev/null +++ b/libraries/edje/src/bin/epp/Makefile.in | |||
@@ -0,0 +1,756 @@ | |||
1 | # Makefile.in generated by automake 1.11.1 from Makefile.am. | ||
2 | # @configure_input@ | ||
3 | |||
4 | # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, | ||
5 | # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, | ||
6 | # Inc. | ||
7 | # This Makefile.in is free software; the Free Software Foundation | ||
8 | # gives unlimited permission to copy and/or distribute it, | ||
9 | # with or without modifications, as long as this notice is preserved. | ||
10 | |||
11 | # This program is distributed in the hope that it will be useful, | ||
12 | # but WITHOUT ANY WARRANTY, to the extent permitted by law; without | ||
13 | # even the implied warranty of MERCHANTABILITY or FITNESS FOR A | ||
14 | # PARTICULAR PURPOSE. | ||
15 | |||
16 | @SET_MAKE@ | ||
17 | |||
18 | # Makefile for GNU C compiler. | ||
19 | # Copyright (C) 1987, 88, 90-94, 1995 Free Software Foundation, Inc. | ||
20 | |||
21 | #This file is part of GNU CC. | ||
22 | |||
23 | #GNU CC is free software; you can redistribute it and/or modify | ||
24 | #it under the terms of the GNU General Public License as published by | ||
25 | #the Free Software Foundation; either version 2, or (at your option) | ||
26 | #any later version. | ||
27 | |||
28 | #GNU CC is distributed in the hope that it will be useful, | ||
29 | #but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
30 | #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
31 | #GNU General Public License for more details. | ||
32 | |||
33 | #You should have received a copy of the GNU General Public License | ||
34 | #along with GNU CC; see the file COPYING. If not, write to | ||
35 | #the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
36 | |||
37 | VPATH = @srcdir@ | ||
38 | pkgdatadir = $(datadir)/@PACKAGE@ | ||
39 | pkgincludedir = $(includedir)/@PACKAGE@ | ||
40 | pkglibdir = $(libdir)/@PACKAGE@ | ||
41 | pkglibexecdir = $(libexecdir)/@PACKAGE@ | ||
42 | am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd | ||
43 | install_sh_DATA = $(install_sh) -c -m 644 | ||
44 | install_sh_PROGRAM = $(install_sh) -c | ||
45 | install_sh_SCRIPT = $(install_sh) -c | ||
46 | INSTALL_HEADER = $(INSTALL_DATA) | ||
47 | transform = $(program_transform_name) | ||
48 | NORMAL_INSTALL = : | ||
49 | PRE_INSTALL = : | ||
50 | POST_INSTALL = : | ||
51 | NORMAL_UNINSTALL = : | ||
52 | PRE_UNINSTALL = : | ||
53 | POST_UNINSTALL = : | ||
54 | build_triplet = @build@ | ||
55 | host_triplet = @host@ | ||
56 | epp_PROGRAMS = epp$(EXEEXT) | ||
57 | subdir = src/bin/epp | ||
58 | DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in | ||
59 | ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 | ||
60 | am__aclocal_m4_deps = $(top_srcdir)/m4/ac_attribute.m4 \ | ||
61 | $(top_srcdir)/m4/efl_binary.m4 \ | ||
62 | $(top_srcdir)/m4/efl_coverage.m4 \ | ||
63 | $(top_srcdir)/m4/efl_doxygen.m4 \ | ||
64 | $(top_srcdir)/m4/efl_path_max.m4 $(top_srcdir)/m4/efl_tests.m4 \ | ||
65 | $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ | ||
66 | $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ | ||
67 | $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac | ||
68 | am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ | ||
69 | $(ACLOCAL_M4) | ||
70 | mkinstalldirs = $(install_sh) -d | ||
71 | CONFIG_HEADER = $(top_builddir)/config.h | ||
72 | CONFIG_CLEAN_FILES = | ||
73 | CONFIG_CLEAN_VPATH_FILES = | ||
74 | am__installdirs = "$(DESTDIR)$(eppdir)" | ||
75 | PROGRAMS = $(epp_PROGRAMS) | ||
76 | am_epp_OBJECTS = epp-cppalloc.$(OBJEXT) epp-cpperror.$(OBJEXT) \ | ||
77 | epp-cppexp.$(OBJEXT) epp-cpphash.$(OBJEXT) \ | ||
78 | epp-cpplib.$(OBJEXT) epp-cppmain.$(OBJEXT) | ||
79 | epp_OBJECTS = $(am_epp_OBJECTS) | ||
80 | epp_LDADD = $(LDADD) | ||
81 | AM_V_lt = $(am__v_lt_$(V)) | ||
82 | am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) | ||
83 | am__v_lt_0 = --silent | ||
84 | DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) | ||
85 | depcomp = $(SHELL) $(top_srcdir)/depcomp | ||
86 | am__depfiles_maybe = depfiles | ||
87 | am__mv = mv -f | ||
88 | COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ | ||
89 | $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) | ||
90 | LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ | ||
91 | $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ | ||
92 | $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ | ||
93 | $(AM_CFLAGS) $(CFLAGS) | ||
94 | AM_V_CC = $(am__v_CC_$(V)) | ||
95 | am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) | ||
96 | am__v_CC_0 = @echo " CC " $@; | ||
97 | AM_V_at = $(am__v_at_$(V)) | ||
98 | am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) | ||
99 | am__v_at_0 = @ | ||
100 | CCLD = $(CC) | ||
101 | LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ | ||
102 | $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ | ||
103 | $(AM_LDFLAGS) $(LDFLAGS) -o $@ | ||
104 | AM_V_CCLD = $(am__v_CCLD_$(V)) | ||
105 | am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) | ||
106 | am__v_CCLD_0 = @echo " CCLD " $@; | ||
107 | AM_V_GEN = $(am__v_GEN_$(V)) | ||
108 | am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) | ||
109 | am__v_GEN_0 = @echo " GEN " $@; | ||
110 | SOURCES = $(epp_SOURCES) | ||
111 | DIST_SOURCES = $(epp_SOURCES) | ||
112 | ETAGS = etags | ||
113 | CTAGS = ctags | ||
114 | DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) | ||
115 | ACLOCAL = @ACLOCAL@ | ||
116 | ALLOCA = @ALLOCA@ | ||
117 | ALSA_CFLAGS = @ALSA_CFLAGS@ | ||
118 | ALSA_LIBS = @ALSA_LIBS@ | ||
119 | AMTAR = @AMTAR@ | ||
120 | AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ | ||
121 | AR = @AR@ | ||
122 | AS = @AS@ | ||
123 | AUTOCONF = @AUTOCONF@ | ||
124 | AUTOHEADER = @AUTOHEADER@ | ||
125 | AUTOMAKE = @AUTOMAKE@ | ||
126 | AWK = @AWK@ | ||
127 | CC = @CC@ | ||
128 | CCDEPMODE = @CCDEPMODE@ | ||
129 | CFLAGS = @CFLAGS@ | ||
130 | CHECK_CFLAGS = @CHECK_CFLAGS@ | ||
131 | CHECK_LIBS = @CHECK_LIBS@ | ||
132 | CPP = @CPP@ | ||
133 | CPPFLAGS = @CPPFLAGS@ | ||
134 | CYGPATH_W = @CYGPATH_W@ | ||
135 | DEFS = \ | ||
136 | -DHAVE_CONFIG_H \ | ||
137 | -DHAVE_STRERROR \ | ||
138 | -DFATAL_EXIT_CODE=1 \ | ||
139 | -DSUCCESS_EXIT_CODE=0 \ | ||
140 | -DGCC_INCLUDE_DIR=\"/usr/include\" \ | ||
141 | -DGPLUSPLUS_INCLUDE_DIR=\"/usr/include\" \ | ||
142 | -DTOOL_INCLUDE_DIR=\"/usr/bin\" \ | ||
143 | -DHOST_BITS_PER_LONG=32 \ | ||
144 | -DBITS_PER_UNIT=8 \ | ||
145 | -DHOST_BITS_PER_INT=32 \ | ||
146 | -DBITS_PER_WORD=16 \ | ||
147 | -DTARGET_BELL=7 \ | ||
148 | -DTARGET_BS=8 \ | ||
149 | -DTARGET_FF=12 \ | ||
150 | -DTARGET_NEWLINE=10 \ | ||
151 | -DTARGET_CR=13 \ | ||
152 | -DTARGET_TAB=9 \ | ||
153 | -DTARGET_VT=11 | ||
154 | |||
155 | DEPDIR = @DEPDIR@ | ||
156 | DLLTOOL = @DLLTOOL@ | ||
157 | DSYMUTIL = @DSYMUTIL@ | ||
158 | DUMPBIN = @DUMPBIN@ | ||
159 | ECHO_C = @ECHO_C@ | ||
160 | ECHO_N = @ECHO_N@ | ||
161 | ECHO_T = @ECHO_T@ | ||
162 | ECORE_IMF_CFLAGS = @ECORE_IMF_CFLAGS@ | ||
163 | ECORE_IMF_LIBS = @ECORE_IMF_LIBS@ | ||
164 | EDJE_CC_CFLAGS = @EDJE_CC_CFLAGS@ | ||
165 | EDJE_CC_LIBS = @EDJE_CC_LIBS@ | ||
166 | EDJE_CC_PRG = @EDJE_CC_PRG@ | ||
167 | EDJE_CFLAGS = @EDJE_CFLAGS@ | ||
168 | EDJE_DECC_CFLAGS = @EDJE_DECC_CFLAGS@ | ||
169 | EDJE_DECC_LIBS = @EDJE_DECC_LIBS@ | ||
170 | EDJE_DECC_PRG = @EDJE_DECC_PRG@ | ||
171 | EDJE_EXTERNAL_INSPECTOR_CFLAGS = @EDJE_EXTERNAL_INSPECTOR_CFLAGS@ | ||
172 | EDJE_EXTERNAL_INSPECTOR_LIBS = @EDJE_EXTERNAL_INSPECTOR_LIBS@ | ||
173 | EDJE_EXTERNAL_INSPECTOR_PRG = @EDJE_EXTERNAL_INSPECTOR_PRG@ | ||
174 | EDJE_INSPECTOR_CFLAGS = @EDJE_INSPECTOR_CFLAGS@ | ||
175 | EDJE_INSPECTOR_LIBS = @EDJE_INSPECTOR_LIBS@ | ||
176 | EDJE_INSPECTOR_PRG = @EDJE_INSPECTOR_PRG@ | ||
177 | EDJE_LIBS = @EDJE_LIBS@ | ||
178 | EDJE_PLAYER_CFLAGS = @EDJE_PLAYER_CFLAGS@ | ||
179 | EDJE_PLAYER_LIBS = @EDJE_PLAYER_LIBS@ | ||
180 | EDJE_PLAYER_PRG = @EDJE_PLAYER_PRG@ | ||
181 | EDJE_RECC_PRG = @EDJE_RECC_PRG@ | ||
182 | EFL_COVERAGE_CFLAGS = @EFL_COVERAGE_CFLAGS@ | ||
183 | EFL_COVERAGE_LIBS = @EFL_COVERAGE_LIBS@ | ||
184 | EFL_EDJE_BUILD = @EFL_EDJE_BUILD@ | ||
185 | EGREP = @EGREP@ | ||
186 | EVIL_CFLAGS = @EVIL_CFLAGS@ | ||
187 | EVIL_LIBS = @EVIL_LIBS@ | ||
188 | EXEEXT = @EXEEXT@ | ||
189 | FGREP = @FGREP@ | ||
190 | FLAC_CFLAGS = @FLAC_CFLAGS@ | ||
191 | FLAC_LIBS = @FLAC_LIBS@ | ||
192 | GREP = @GREP@ | ||
193 | INSTALL = @INSTALL@ | ||
194 | INSTALL_DATA = @INSTALL_DATA@ | ||
195 | INSTALL_PROGRAM = @INSTALL_PROGRAM@ | ||
196 | INSTALL_SCRIPT = @INSTALL_SCRIPT@ | ||
197 | INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ | ||
198 | LD = @LD@ | ||
199 | LDFLAGS = @LDFLAGS@ | ||
200 | LIBOBJS = @LIBOBJS@ | ||
201 | LIBS = @LIBS@ | ||
202 | LIBTOOL = @LIBTOOL@ | ||
203 | LIPO = @LIPO@ | ||
204 | LN_S = @LN_S@ | ||
205 | LTLIBOBJS = @LTLIBOBJS@ | ||
206 | LUA_CFLAGS = @LUA_CFLAGS@ | ||
207 | LUA_LIBS = @LUA_LIBS@ | ||
208 | MAKEINFO = @MAKEINFO@ | ||
209 | MINIMAL_CFLAGS = @MINIMAL_CFLAGS@ | ||
210 | MINIMAL_LIBS = @MINIMAL_LIBS@ | ||
211 | MKDIR_P = @MKDIR_P@ | ||
212 | MODULE_ARCH = @MODULE_ARCH@ | ||
213 | NM = @NM@ | ||
214 | NMEDIT = @NMEDIT@ | ||
215 | OBJDUMP = @OBJDUMP@ | ||
216 | OBJEXT = @OBJEXT@ | ||
217 | OTOOL = @OTOOL@ | ||
218 | OTOOL64 = @OTOOL64@ | ||
219 | PACKAGE = @PACKAGE@ | ||
220 | PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ | ||
221 | PACKAGE_NAME = @PACKAGE_NAME@ | ||
222 | PACKAGE_STRING = @PACKAGE_STRING@ | ||
223 | PACKAGE_TARNAME = @PACKAGE_TARNAME@ | ||
224 | PACKAGE_URL = @PACKAGE_URL@ | ||
225 | PACKAGE_VERSION = @PACKAGE_VERSION@ | ||
226 | PATH_SEPARATOR = @PATH_SEPARATOR@ | ||
227 | PKG_CONFIG = @PKG_CONFIG@ | ||
228 | PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ | ||
229 | PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ | ||
230 | PYTHON = @PYTHON@ | ||
231 | PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ | ||
232 | PYTHON_PLATFORM = @PYTHON_PLATFORM@ | ||
233 | PYTHON_PREFIX = @PYTHON_PREFIX@ | ||
234 | PYTHON_VERSION = @PYTHON_VERSION@ | ||
235 | RANLIB = @RANLIB@ | ||
236 | REMIX_CFLAGS = @REMIX_CFLAGS@ | ||
237 | REMIX_LIBS = @REMIX_LIBS@ | ||
238 | REMIX_PLUGIN_DIR = @REMIX_PLUGIN_DIR@ | ||
239 | SED = @SED@ | ||
240 | SET_MAKE = @SET_MAKE@ | ||
241 | SHELL = @SHELL@ | ||
242 | SNDFILE_CFLAGS = @SNDFILE_CFLAGS@ | ||
243 | SNDFILE_LIBS = @SNDFILE_LIBS@ | ||
244 | STRIP = @STRIP@ | ||
245 | VERSION = @VERSION@ | ||
246 | VMAJ = @VMAJ@ | ||
247 | VORBISENC_CFLAGS = @VORBISENC_CFLAGS@ | ||
248 | VORBISENC_LIBS = @VORBISENC_LIBS@ | ||
249 | abs_builddir = @abs_builddir@ | ||
250 | abs_srcdir = @abs_srcdir@ | ||
251 | abs_top_builddir = @abs_top_builddir@ | ||
252 | abs_top_srcdir = @abs_top_srcdir@ | ||
253 | ac_ct_CC = @ac_ct_CC@ | ||
254 | ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ | ||
255 | am__include = @am__include@ | ||
256 | am__leading_dot = @am__leading_dot@ | ||
257 | am__quote = @am__quote@ | ||
258 | am__tar = @am__tar@ | ||
259 | am__untar = @am__untar@ | ||
260 | bindir = @bindir@ | ||
261 | build = @build@ | ||
262 | build_alias = @build_alias@ | ||
263 | build_cpu = @build_cpu@ | ||
264 | build_os = @build_os@ | ||
265 | build_vendor = @build_vendor@ | ||
266 | builddir = @builddir@ | ||
267 | datadir = @datadir@ | ||
268 | datarootdir = @datarootdir@ | ||
269 | docdir = @docdir@ | ||
270 | dvidir = @dvidir@ | ||
271 | edje_cc = @edje_cc@ | ||
272 | efl_doxygen = @efl_doxygen@ | ||
273 | efl_have_doxygen = @efl_have_doxygen@ | ||
274 | exec_prefix = @exec_prefix@ | ||
275 | have_lcov = @have_lcov@ | ||
276 | host = @host@ | ||
277 | host_alias = @host_alias@ | ||
278 | host_cpu = @host_cpu@ | ||
279 | host_os = @host_os@ | ||
280 | host_vendor = @host_vendor@ | ||
281 | htmldir = @htmldir@ | ||
282 | includedir = @includedir@ | ||
283 | infodir = @infodir@ | ||
284 | install_sh = @install_sh@ | ||
285 | libdir = @libdir@ | ||
286 | libexecdir = @libexecdir@ | ||
287 | localedir = @localedir@ | ||
288 | localstatedir = @localstatedir@ | ||
289 | lt_ECHO = @lt_ECHO@ | ||
290 | lt_enable_auto_import = @lt_enable_auto_import@ | ||
291 | lua_libs = @lua_libs@ | ||
292 | mandir = @mandir@ | ||
293 | mkdir_p = @mkdir_p@ | ||
294 | oldincludedir = @oldincludedir@ | ||
295 | pdfdir = @pdfdir@ | ||
296 | pkgconfig_requires_private = @pkgconfig_requires_private@ | ||
297 | pkgpyexecdir = @pkgpyexecdir@ | ||
298 | pkgpythondir = @pkgpythondir@ | ||
299 | prefix = @prefix@ | ||
300 | program_transform_name = @program_transform_name@ | ||
301 | psdir = @psdir@ | ||
302 | pyexecdir = @pyexecdir@ | ||
303 | pythondir = @pythondir@ | ||
304 | release_info = @release_info@ | ||
305 | requirement_edje = @requirement_edje@ | ||
306 | sbindir = @sbindir@ | ||
307 | sharedstatedir = @sharedstatedir@ | ||
308 | srcdir = @srcdir@ | ||
309 | sysconfdir = @sysconfdir@ | ||
310 | target_alias = @target_alias@ | ||
311 | top_build_prefix = @top_build_prefix@ | ||
312 | top_builddir = @top_builddir@ | ||
313 | top_srcdir = @top_srcdir@ | ||
314 | version_info = @version_info@ | ||
315 | vimdir = @vimdir@ | ||
316 | MAINTAINERCLEANFILES = Makefile.in | ||
317 | eppdir = @libdir@/@PACKAGE@/utils | ||
318 | epp_SOURCES = \ | ||
319 | cpplib.h \ | ||
320 | cpphash.h \ | ||
321 | cppalloc.c \ | ||
322 | cpperror.c \ | ||
323 | cppexp.c \ | ||
324 | cpphash.c \ | ||
325 | cpplib.c \ | ||
326 | cppmain.c | ||
327 | |||
328 | epp_CPPFLAGS = \ | ||
329 | -I$(top_builddir) \ | ||
330 | $(CWARNFLAGS) | ||
331 | |||
332 | all: all-am | ||
333 | |||
334 | .SUFFIXES: | ||
335 | .SUFFIXES: .c .lo .o .obj | ||
336 | $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) | ||
337 | @for dep in $?; do \ | ||
338 | case '$(am__configure_deps)' in \ | ||
339 | *$$dep*) \ | ||
340 | ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ | ||
341 | && { if test -f $@; then exit 0; else break; fi; }; \ | ||
342 | exit 1;; \ | ||
343 | esac; \ | ||
344 | done; \ | ||
345 | echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/bin/epp/Makefile'; \ | ||
346 | $(am__cd) $(top_srcdir) && \ | ||
347 | $(AUTOMAKE) --gnu src/bin/epp/Makefile | ||
348 | .PRECIOUS: Makefile | ||
349 | Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status | ||
350 | @case '$?' in \ | ||
351 | *config.status*) \ | ||
352 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ | ||
353 | *) \ | ||
354 | echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ | ||
355 | cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ | ||
356 | esac; | ||
357 | |||
358 | $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) | ||
359 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh | ||
360 | |||
361 | $(top_srcdir)/configure: $(am__configure_deps) | ||
362 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh | ||
363 | $(ACLOCAL_M4): $(am__aclocal_m4_deps) | ||
364 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh | ||
365 | $(am__aclocal_m4_deps): | ||
366 | install-eppPROGRAMS: $(epp_PROGRAMS) | ||
367 | @$(NORMAL_INSTALL) | ||
368 | test -z "$(eppdir)" || $(MKDIR_P) "$(DESTDIR)$(eppdir)" | ||
369 | @list='$(epp_PROGRAMS)'; test -n "$(eppdir)" || list=; \ | ||
370 | for p in $$list; do echo "$$p $$p"; done | \ | ||
371 | sed 's/$(EXEEXT)$$//' | \ | ||
372 | while read p p1; do if test -f $$p || test -f $$p1; \ | ||
373 | then echo "$$p"; echo "$$p"; else :; fi; \ | ||
374 | done | \ | ||
375 | sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ | ||
376 | -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ | ||
377 | sed 'N;N;N;s,\n, ,g' | \ | ||
378 | $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ | ||
379 | { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ | ||
380 | if ($$2 == $$4) files[d] = files[d] " " $$1; \ | ||
381 | else { print "f", $$3 "/" $$4, $$1; } } \ | ||
382 | END { for (d in files) print "f", d, files[d] }' | \ | ||
383 | while read type dir files; do \ | ||
384 | if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ | ||
385 | test -z "$$files" || { \ | ||
386 | echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(eppdir)$$dir'"; \ | ||
387 | $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(eppdir)$$dir" || exit $$?; \ | ||
388 | } \ | ||
389 | ; done | ||
390 | |||
391 | uninstall-eppPROGRAMS: | ||
392 | @$(NORMAL_UNINSTALL) | ||
393 | @list='$(epp_PROGRAMS)'; test -n "$(eppdir)" || list=; \ | ||
394 | files=`for p in $$list; do echo "$$p"; done | \ | ||
395 | sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ | ||
396 | -e 's/$$/$(EXEEXT)/' `; \ | ||
397 | test -n "$$list" || exit 0; \ | ||
398 | echo " ( cd '$(DESTDIR)$(eppdir)' && rm -f" $$files ")"; \ | ||
399 | cd "$(DESTDIR)$(eppdir)" && rm -f $$files | ||
400 | |||
401 | clean-eppPROGRAMS: | ||
402 | @list='$(epp_PROGRAMS)'; test -n "$$list" || exit 0; \ | ||
403 | echo " rm -f" $$list; \ | ||
404 | rm -f $$list || exit $$?; \ | ||
405 | test -n "$(EXEEXT)" || exit 0; \ | ||
406 | list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ | ||
407 | echo " rm -f" $$list; \ | ||
408 | rm -f $$list | ||
409 | epp$(EXEEXT): $(epp_OBJECTS) $(epp_DEPENDENCIES) | ||
410 | @rm -f epp$(EXEEXT) | ||
411 | $(AM_V_CCLD)$(LINK) $(epp_OBJECTS) $(epp_LDADD) $(LIBS) | ||
412 | |||
413 | mostlyclean-compile: | ||
414 | -rm -f *.$(OBJEXT) | ||
415 | |||
416 | distclean-compile: | ||
417 | -rm -f *.tab.c | ||
418 | |||
419 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epp-cppalloc.Po@am__quote@ | ||
420 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epp-cpperror.Po@am__quote@ | ||
421 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epp-cppexp.Po@am__quote@ | ||
422 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epp-cpphash.Po@am__quote@ | ||
423 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epp-cpplib.Po@am__quote@ | ||
424 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epp-cppmain.Po@am__quote@ | ||
425 | |||
426 | .c.o: | ||
427 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< | ||
428 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po | ||
429 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
430 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ | ||
431 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
432 | @am__fastdepCC_FALSE@ $(COMPILE) -c $< | ||
433 | |||
434 | .c.obj: | ||
435 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` | ||
436 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po | ||
437 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
438 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ | ||
439 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
440 | @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` | ||
441 | |||
442 | .c.lo: | ||
443 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< | ||
444 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo | ||
445 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
446 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ | ||
447 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
448 | @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< | ||
449 | |||
450 | epp-cppalloc.o: cppalloc.c | ||
451 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(epp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT epp-cppalloc.o -MD -MP -MF $(DEPDIR)/epp-cppalloc.Tpo -c -o epp-cppalloc.o `test -f 'cppalloc.c' || echo '$(srcdir)/'`cppalloc.c | ||
452 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/epp-cppalloc.Tpo $(DEPDIR)/epp-cppalloc.Po | ||
453 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
454 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cppalloc.c' object='epp-cppalloc.o' libtool=no @AMDEPBACKSLASH@ | ||
455 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
456 | @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(epp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o epp-cppalloc.o `test -f 'cppalloc.c' || echo '$(srcdir)/'`cppalloc.c | ||
457 | |||
458 | epp-cppalloc.obj: cppalloc.c | ||
459 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(epp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT epp-cppalloc.obj -MD -MP -MF $(DEPDIR)/epp-cppalloc.Tpo -c -o epp-cppalloc.obj `if test -f 'cppalloc.c'; then $(CYGPATH_W) 'cppalloc.c'; else $(CYGPATH_W) '$(srcdir)/cppalloc.c'; fi` | ||
460 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/epp-cppalloc.Tpo $(DEPDIR)/epp-cppalloc.Po | ||
461 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
462 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cppalloc.c' object='epp-cppalloc.obj' libtool=no @AMDEPBACKSLASH@ | ||
463 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
464 | @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(epp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o epp-cppalloc.obj `if test -f 'cppalloc.c'; then $(CYGPATH_W) 'cppalloc.c'; else $(CYGPATH_W) '$(srcdir)/cppalloc.c'; fi` | ||
465 | |||
466 | epp-cpperror.o: cpperror.c | ||
467 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(epp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT epp-cpperror.o -MD -MP -MF $(DEPDIR)/epp-cpperror.Tpo -c -o epp-cpperror.o `test -f 'cpperror.c' || echo '$(srcdir)/'`cpperror.c | ||
468 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/epp-cpperror.Tpo $(DEPDIR)/epp-cpperror.Po | ||
469 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
470 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cpperror.c' object='epp-cpperror.o' libtool=no @AMDEPBACKSLASH@ | ||
471 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
472 | @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(epp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o epp-cpperror.o `test -f 'cpperror.c' || echo '$(srcdir)/'`cpperror.c | ||
473 | |||
474 | epp-cpperror.obj: cpperror.c | ||
475 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(epp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT epp-cpperror.obj -MD -MP -MF $(DEPDIR)/epp-cpperror.Tpo -c -o epp-cpperror.obj `if test -f 'cpperror.c'; then $(CYGPATH_W) 'cpperror.c'; else $(CYGPATH_W) '$(srcdir)/cpperror.c'; fi` | ||
476 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/epp-cpperror.Tpo $(DEPDIR)/epp-cpperror.Po | ||
477 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
478 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cpperror.c' object='epp-cpperror.obj' libtool=no @AMDEPBACKSLASH@ | ||
479 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
480 | @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(epp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o epp-cpperror.obj `if test -f 'cpperror.c'; then $(CYGPATH_W) 'cpperror.c'; else $(CYGPATH_W) '$(srcdir)/cpperror.c'; fi` | ||
481 | |||
482 | epp-cppexp.o: cppexp.c | ||
483 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(epp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT epp-cppexp.o -MD -MP -MF $(DEPDIR)/epp-cppexp.Tpo -c -o epp-cppexp.o `test -f 'cppexp.c' || echo '$(srcdir)/'`cppexp.c | ||
484 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/epp-cppexp.Tpo $(DEPDIR)/epp-cppexp.Po | ||
485 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
486 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cppexp.c' object='epp-cppexp.o' libtool=no @AMDEPBACKSLASH@ | ||
487 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
488 | @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(epp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o epp-cppexp.o `test -f 'cppexp.c' || echo '$(srcdir)/'`cppexp.c | ||
489 | |||
490 | epp-cppexp.obj: cppexp.c | ||
491 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(epp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT epp-cppexp.obj -MD -MP -MF $(DEPDIR)/epp-cppexp.Tpo -c -o epp-cppexp.obj `if test -f 'cppexp.c'; then $(CYGPATH_W) 'cppexp.c'; else $(CYGPATH_W) '$(srcdir)/cppexp.c'; fi` | ||
492 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/epp-cppexp.Tpo $(DEPDIR)/epp-cppexp.Po | ||
493 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
494 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cppexp.c' object='epp-cppexp.obj' libtool=no @AMDEPBACKSLASH@ | ||
495 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
496 | @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(epp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o epp-cppexp.obj `if test -f 'cppexp.c'; then $(CYGPATH_W) 'cppexp.c'; else $(CYGPATH_W) '$(srcdir)/cppexp.c'; fi` | ||
497 | |||
498 | epp-cpphash.o: cpphash.c | ||
499 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(epp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT epp-cpphash.o -MD -MP -MF $(DEPDIR)/epp-cpphash.Tpo -c -o epp-cpphash.o `test -f 'cpphash.c' || echo '$(srcdir)/'`cpphash.c | ||
500 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/epp-cpphash.Tpo $(DEPDIR)/epp-cpphash.Po | ||
501 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
502 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cpphash.c' object='epp-cpphash.o' libtool=no @AMDEPBACKSLASH@ | ||
503 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
504 | @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(epp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o epp-cpphash.o `test -f 'cpphash.c' || echo '$(srcdir)/'`cpphash.c | ||
505 | |||
506 | epp-cpphash.obj: cpphash.c | ||
507 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(epp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT epp-cpphash.obj -MD -MP -MF $(DEPDIR)/epp-cpphash.Tpo -c -o epp-cpphash.obj `if test -f 'cpphash.c'; then $(CYGPATH_W) 'cpphash.c'; else $(CYGPATH_W) '$(srcdir)/cpphash.c'; fi` | ||
508 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/epp-cpphash.Tpo $(DEPDIR)/epp-cpphash.Po | ||
509 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
510 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cpphash.c' object='epp-cpphash.obj' libtool=no @AMDEPBACKSLASH@ | ||
511 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
512 | @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(epp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o epp-cpphash.obj `if test -f 'cpphash.c'; then $(CYGPATH_W) 'cpphash.c'; else $(CYGPATH_W) '$(srcdir)/cpphash.c'; fi` | ||
513 | |||
514 | epp-cpplib.o: cpplib.c | ||
515 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(epp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT epp-cpplib.o -MD -MP -MF $(DEPDIR)/epp-cpplib.Tpo -c -o epp-cpplib.o `test -f 'cpplib.c' || echo '$(srcdir)/'`cpplib.c | ||
516 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/epp-cpplib.Tpo $(DEPDIR)/epp-cpplib.Po | ||
517 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
518 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cpplib.c' object='epp-cpplib.o' libtool=no @AMDEPBACKSLASH@ | ||
519 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
520 | @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(epp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o epp-cpplib.o `test -f 'cpplib.c' || echo '$(srcdir)/'`cpplib.c | ||
521 | |||
522 | epp-cpplib.obj: cpplib.c | ||
523 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(epp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT epp-cpplib.obj -MD -MP -MF $(DEPDIR)/epp-cpplib.Tpo -c -o epp-cpplib.obj `if test -f 'cpplib.c'; then $(CYGPATH_W) 'cpplib.c'; else $(CYGPATH_W) '$(srcdir)/cpplib.c'; fi` | ||
524 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/epp-cpplib.Tpo $(DEPDIR)/epp-cpplib.Po | ||
525 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
526 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cpplib.c' object='epp-cpplib.obj' libtool=no @AMDEPBACKSLASH@ | ||
527 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
528 | @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(epp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o epp-cpplib.obj `if test -f 'cpplib.c'; then $(CYGPATH_W) 'cpplib.c'; else $(CYGPATH_W) '$(srcdir)/cpplib.c'; fi` | ||
529 | |||
530 | epp-cppmain.o: cppmain.c | ||
531 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(epp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT epp-cppmain.o -MD -MP -MF $(DEPDIR)/epp-cppmain.Tpo -c -o epp-cppmain.o `test -f 'cppmain.c' || echo '$(srcdir)/'`cppmain.c | ||
532 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/epp-cppmain.Tpo $(DEPDIR)/epp-cppmain.Po | ||
533 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
534 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cppmain.c' object='epp-cppmain.o' libtool=no @AMDEPBACKSLASH@ | ||
535 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
536 | @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(epp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o epp-cppmain.o `test -f 'cppmain.c' || echo '$(srcdir)/'`cppmain.c | ||
537 | |||
538 | epp-cppmain.obj: cppmain.c | ||
539 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(epp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT epp-cppmain.obj -MD -MP -MF $(DEPDIR)/epp-cppmain.Tpo -c -o epp-cppmain.obj `if test -f 'cppmain.c'; then $(CYGPATH_W) 'cppmain.c'; else $(CYGPATH_W) '$(srcdir)/cppmain.c'; fi` | ||
540 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/epp-cppmain.Tpo $(DEPDIR)/epp-cppmain.Po | ||
541 | @am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ | ||
542 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cppmain.c' object='epp-cppmain.obj' libtool=no @AMDEPBACKSLASH@ | ||
543 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ | ||
544 | @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(epp_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o epp-cppmain.obj `if test -f 'cppmain.c'; then $(CYGPATH_W) 'cppmain.c'; else $(CYGPATH_W) '$(srcdir)/cppmain.c'; fi` | ||
545 | |||
546 | mostlyclean-libtool: | ||
547 | -rm -f *.lo | ||
548 | |||
549 | clean-libtool: | ||
550 | -rm -rf .libs _libs | ||
551 | |||
552 | ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) | ||
553 | list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ | ||
554 | unique=`for i in $$list; do \ | ||
555 | if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ | ||
556 | done | \ | ||
557 | $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ | ||
558 | END { if (nonempty) { for (i in files) print i; }; }'`; \ | ||
559 | mkid -fID $$unique | ||
560 | tags: TAGS | ||
561 | |||
562 | TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ | ||
563 | $(TAGS_FILES) $(LISP) | ||
564 | set x; \ | ||
565 | here=`pwd`; \ | ||
566 | list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ | ||
567 | unique=`for i in $$list; do \ | ||
568 | if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ | ||
569 | done | \ | ||
570 | $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ | ||
571 | END { if (nonempty) { for (i in files) print i; }; }'`; \ | ||
572 | shift; \ | ||
573 | if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ | ||
574 | test -n "$$unique" || unique=$$empty_fix; \ | ||
575 | if test $$# -gt 0; then \ | ||
576 | $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ | ||
577 | "$$@" $$unique; \ | ||
578 | else \ | ||
579 | $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ | ||
580 | $$unique; \ | ||
581 | fi; \ | ||
582 | fi | ||
583 | ctags: CTAGS | ||
584 | CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ | ||
585 | $(TAGS_FILES) $(LISP) | ||
586 | list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ | ||
587 | unique=`for i in $$list; do \ | ||
588 | if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ | ||
589 | done | \ | ||
590 | $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ | ||
591 | END { if (nonempty) { for (i in files) print i; }; }'`; \ | ||
592 | test -z "$(CTAGS_ARGS)$$unique" \ | ||
593 | || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ | ||
594 | $$unique | ||
595 | |||
596 | GTAGS: | ||
597 | here=`$(am__cd) $(top_builddir) && pwd` \ | ||
598 | && $(am__cd) $(top_srcdir) \ | ||
599 | && gtags -i $(GTAGS_ARGS) "$$here" | ||
600 | |||
601 | distclean-tags: | ||
602 | -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags | ||
603 | |||
604 | distdir: $(DISTFILES) | ||
605 | @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ | ||
606 | topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ | ||
607 | list='$(DISTFILES)'; \ | ||
608 | dist_files=`for file in $$list; do echo $$file; done | \ | ||
609 | sed -e "s|^$$srcdirstrip/||;t" \ | ||
610 | -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ | ||
611 | case $$dist_files in \ | ||
612 | */*) $(MKDIR_P) `echo "$$dist_files" | \ | ||
613 | sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ | ||
614 | sort -u` ;; \ | ||
615 | esac; \ | ||
616 | for file in $$dist_files; do \ | ||
617 | if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ | ||
618 | if test -d $$d/$$file; then \ | ||
619 | dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ | ||
620 | if test -d "$(distdir)/$$file"; then \ | ||
621 | find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ | ||
622 | fi; \ | ||
623 | if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ | ||
624 | cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ | ||
625 | find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ | ||
626 | fi; \ | ||
627 | cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ | ||
628 | else \ | ||
629 | test -f "$(distdir)/$$file" \ | ||
630 | || cp -p $$d/$$file "$(distdir)/$$file" \ | ||
631 | || exit 1; \ | ||
632 | fi; \ | ||
633 | done | ||
634 | check-am: all-am | ||
635 | check: check-am | ||
636 | all-am: Makefile $(PROGRAMS) | ||
637 | installdirs: | ||
638 | for dir in "$(DESTDIR)$(eppdir)"; do \ | ||
639 | test -z "$$dir" || $(MKDIR_P) "$$dir"; \ | ||
640 | done | ||
641 | install: install-am | ||
642 | install-exec: install-exec-am | ||
643 | install-data: install-data-am | ||
644 | uninstall: uninstall-am | ||
645 | |||
646 | install-am: all-am | ||
647 | @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am | ||
648 | |||
649 | installcheck: installcheck-am | ||
650 | install-strip: | ||
651 | $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ | ||
652 | install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ | ||
653 | `test -z '$(STRIP)' || \ | ||
654 | echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install | ||
655 | mostlyclean-generic: | ||
656 | |||
657 | clean-generic: | ||
658 | |||
659 | distclean-generic: | ||
660 | -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) | ||
661 | -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) | ||
662 | |||
663 | maintainer-clean-generic: | ||
664 | @echo "This command is intended for maintainers to use" | ||
665 | @echo "it deletes files that may require special tools to rebuild." | ||
666 | -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) | ||
667 | clean: clean-am | ||
668 | |||
669 | clean-am: clean-eppPROGRAMS clean-generic clean-libtool mostlyclean-am | ||
670 | |||
671 | distclean: distclean-am | ||
672 | -rm -rf ./$(DEPDIR) | ||
673 | -rm -f Makefile | ||
674 | distclean-am: clean-am distclean-compile distclean-generic \ | ||
675 | distclean-tags | ||
676 | |||
677 | dvi: dvi-am | ||
678 | |||
679 | dvi-am: | ||
680 | |||
681 | html: html-am | ||
682 | |||
683 | html-am: | ||
684 | |||
685 | info: info-am | ||
686 | |||
687 | info-am: | ||
688 | |||
689 | install-data-am: install-eppPROGRAMS | ||
690 | |||
691 | install-dvi: install-dvi-am | ||
692 | |||
693 | install-dvi-am: | ||
694 | |||
695 | install-exec-am: | ||
696 | |||
697 | install-html: install-html-am | ||
698 | |||
699 | install-html-am: | ||
700 | |||
701 | install-info: install-info-am | ||
702 | |||
703 | install-info-am: | ||
704 | |||
705 | install-man: | ||
706 | |||
707 | install-pdf: install-pdf-am | ||
708 | |||
709 | install-pdf-am: | ||
710 | |||
711 | install-ps: install-ps-am | ||
712 | |||
713 | install-ps-am: | ||
714 | |||
715 | installcheck-am: | ||
716 | |||
717 | maintainer-clean: maintainer-clean-am | ||
718 | -rm -rf ./$(DEPDIR) | ||
719 | -rm -f Makefile | ||
720 | maintainer-clean-am: distclean-am maintainer-clean-generic | ||
721 | |||
722 | mostlyclean: mostlyclean-am | ||
723 | |||
724 | mostlyclean-am: mostlyclean-compile mostlyclean-generic \ | ||
725 | mostlyclean-libtool | ||
726 | |||
727 | pdf: pdf-am | ||
728 | |||
729 | pdf-am: | ||
730 | |||
731 | ps: ps-am | ||
732 | |||
733 | ps-am: | ||
734 | |||
735 | uninstall-am: uninstall-eppPROGRAMS | ||
736 | |||
737 | .MAKE: install-am install-strip | ||
738 | |||
739 | .PHONY: CTAGS GTAGS all all-am check check-am clean clean-eppPROGRAMS \ | ||
740 | clean-generic clean-libtool ctags distclean distclean-compile \ | ||
741 | distclean-generic distclean-libtool distclean-tags distdir dvi \ | ||
742 | dvi-am html html-am info info-am install install-am \ | ||
743 | install-data install-data-am install-dvi install-dvi-am \ | ||
744 | install-eppPROGRAMS install-exec install-exec-am install-html \ | ||
745 | install-html-am install-info install-info-am install-man \ | ||
746 | install-pdf install-pdf-am install-ps install-ps-am \ | ||
747 | install-strip installcheck installcheck-am installdirs \ | ||
748 | maintainer-clean maintainer-clean-generic mostlyclean \ | ||
749 | mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ | ||
750 | pdf pdf-am ps ps-am tags uninstall uninstall-am \ | ||
751 | uninstall-eppPROGRAMS | ||
752 | |||
753 | |||
754 | # Tell versions [3.59,3.63) of GNU make to not export all variables. | ||
755 | # Otherwise a system limit (for SysV at least) may be exceeded. | ||
756 | .NOEXPORT: | ||
diff --git a/libraries/edje/src/bin/epp/cppalloc.c b/libraries/edje/src/bin/epp/cppalloc.c new file mode 100644 index 0000000..4ce0dd0 --- /dev/null +++ b/libraries/edje/src/bin/epp/cppalloc.c | |||
@@ -0,0 +1,70 @@ | |||
1 | /* Part of CPP library. (memory allocation - xmalloc etc) | ||
2 | * Copyright (C) 1986, 87, 89, 92, 93, 94, 1995 Free Software Foundation, Inc. | ||
3 | * Written by Per Bothner, 1994. | ||
4 | * Based on CCCP program by by Paul Rubin, June 1986 | ||
5 | * Adapted to ANSI C, Richard Stallman, Jan 1987 | ||
6 | * Copyright (C) 2003-2011 Kim Woelders | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2, or (at your option) any | ||
11 | * later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | * | ||
22 | * In other words, you are welcome to use, share and improve this program. | ||
23 | * You are forbidden to forbid anyone else to use, share and improve | ||
24 | * what you give them. Help stamp out software-hoarding! */ | ||
25 | |||
26 | #ifdef HAVE_CONFIG_H | ||
27 | # include <config.h> | ||
28 | #endif | ||
29 | |||
30 | #include <stdlib.h> | ||
31 | |||
32 | #include "cpplib.h" | ||
33 | |||
34 | static void | ||
35 | memory_full(void) | ||
36 | { | ||
37 | cpp_fatal("Memory exhausted."); | ||
38 | } | ||
39 | |||
40 | void * | ||
41 | xmalloc(unsigned size) | ||
42 | { | ||
43 | char *ptr = (char *)malloc(size); | ||
44 | |||
45 | if (ptr) | ||
46 | return (ptr); | ||
47 | memory_full(); | ||
48 | /*NOTREACHED */ | ||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | void * | ||
53 | xrealloc(void *old, unsigned size) | ||
54 | { | ||
55 | char *ptr = (char *)realloc(old, size); | ||
56 | |||
57 | if (!ptr) | ||
58 | memory_full(); | ||
59 | return ptr; | ||
60 | } | ||
61 | |||
62 | void * | ||
63 | xcalloc(unsigned number, unsigned size) | ||
64 | { | ||
65 | char *ptr = (char *)calloc(number, size); | ||
66 | |||
67 | if (!ptr) | ||
68 | memory_full(); | ||
69 | return ptr; | ||
70 | } | ||
diff --git a/libraries/edje/src/bin/epp/cpperror.c b/libraries/edje/src/bin/epp/cpperror.c new file mode 100644 index 0000000..f4cd5eb --- /dev/null +++ b/libraries/edje/src/bin/epp/cpperror.c | |||
@@ -0,0 +1,147 @@ | |||
1 | /* Default error handlers for CPP Library. | ||
2 | * Copyright (C) 1986, 87, 89, 92, 93, 94, 1995 Free Software Foundation, Inc. | ||
3 | * Written by Per Bothner, 1994. | ||
4 | * Based on CCCP program by by Paul Rubin, June 1986 | ||
5 | * Adapted to ANSI C, Richard Stallman, Jan 1987 | ||
6 | * Copyright (C) 2003-2011 Kim Woelders | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2, or (at your option) any | ||
11 | * later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | * | ||
22 | * In other words, you are welcome to use, share and improve this program. | ||
23 | * You are forbidden to forbid anyone else to use, share and improve | ||
24 | * what you give them. Help stamp out software-hoarding! */ | ||
25 | |||
26 | #ifdef HAVE_CONFIG_H | ||
27 | # include <config.h> | ||
28 | #endif | ||
29 | |||
30 | #include <stdio.h> | ||
31 | #include <stdlib.h> | ||
32 | |||
33 | #include "cpplib.h" | ||
34 | |||
35 | /* Print the file names and line numbers of the #include | ||
36 | * commands which led to the current file. */ | ||
37 | |||
38 | void | ||
39 | cpp_print_containing_files(cpp_reader * pfile) | ||
40 | { | ||
41 | cpp_buffer *ip; | ||
42 | int first = 1; | ||
43 | |||
44 | /* If stack of files hasn't changed since we last printed | ||
45 | * this info, don't repeat it. */ | ||
46 | if (pfile->input_stack_listing_current) | ||
47 | return; | ||
48 | |||
49 | ip = cpp_file_buffer(pfile); | ||
50 | |||
51 | /* Give up if we don't find a source file. */ | ||
52 | if (!ip) | ||
53 | return; | ||
54 | |||
55 | /* Find the other, outer source files. */ | ||
56 | while ((ip = CPP_PREV_BUFFER(ip)), ip != CPP_NULL_BUFFER(pfile)) | ||
57 | { | ||
58 | long line, col; | ||
59 | |||
60 | cpp_buf_line_and_col(ip, &line, &col); | ||
61 | if (ip->fname) | ||
62 | { | ||
63 | if (first) | ||
64 | { | ||
65 | first = 0; | ||
66 | fprintf(stderr, "In file included"); | ||
67 | } | ||
68 | else | ||
69 | fprintf(stderr, ",\n "); | ||
70 | } | ||
71 | } | ||
72 | if (!first) | ||
73 | fprintf(stderr, ":\n"); | ||
74 | |||
75 | /* Record we have printed the status as of this time. */ | ||
76 | pfile->input_stack_listing_current = 1; | ||
77 | } | ||
78 | |||
79 | void | ||
80 | cpp_file_line_for_message(cpp_reader * pfile __UNUSED__, const char *filename, | ||
81 | int line, int column) | ||
82 | { | ||
83 | if (column > 0) | ||
84 | { | ||
85 | fprintf(stderr, "%s:%d:%d: ", filename, line, column); | ||
86 | } | ||
87 | else | ||
88 | { | ||
89 | fprintf(stderr, "%s:%d: ", filename, line); | ||
90 | } | ||
91 | } | ||
92 | |||
93 | /* IS_ERROR is 1 for error, 0 for warning */ | ||
94 | void | ||
95 | cpp_message_v(cpp_reader * pfile, int is_error, const char *msg, va_list args) | ||
96 | { | ||
97 | if (is_error) | ||
98 | pfile->errors++; | ||
99 | else | ||
100 | fprintf(stderr, "warning: "); | ||
101 | vfprintf(stderr, msg, args); | ||
102 | fprintf(stderr, "\n"); | ||
103 | } | ||
104 | |||
105 | void | ||
106 | cpp_message(cpp_reader * pfile, int is_error, const char *msg, ...) | ||
107 | { | ||
108 | va_list args; | ||
109 | |||
110 | va_start(args, msg); | ||
111 | |||
112 | cpp_message_v(pfile, is_error, msg, args); | ||
113 | |||
114 | va_end(args); | ||
115 | } | ||
116 | |||
117 | static void | ||
118 | cpp_fatal_v(const char *msg, va_list args) | ||
119 | { | ||
120 | fprintf(stderr, "%s: ", progname); | ||
121 | vfprintf(stderr, msg, args); | ||
122 | fprintf(stderr, "\n"); | ||
123 | exit(FATAL_EXIT_CODE); | ||
124 | } | ||
125 | |||
126 | void | ||
127 | cpp_fatal(const char *msg, ...) | ||
128 | { | ||
129 | va_list args; | ||
130 | |||
131 | va_start(args, msg); | ||
132 | |||
133 | cpp_fatal_v(msg, args); | ||
134 | |||
135 | va_end(args); | ||
136 | } | ||
137 | |||
138 | void | ||
139 | cpp_pfatal_with_name(cpp_reader * pfile, const char *name) | ||
140 | { | ||
141 | cpp_perror_with_name(pfile, name); | ||
142 | #ifdef VMS | ||
143 | exit(vaxc$errno); | ||
144 | #else | ||
145 | exit(FATAL_EXIT_CODE); | ||
146 | #endif | ||
147 | } | ||
diff --git a/libraries/edje/src/bin/epp/cppexp.c b/libraries/edje/src/bin/epp/cppexp.c new file mode 100644 index 0000000..5fcb33f --- /dev/null +++ b/libraries/edje/src/bin/epp/cppexp.c | |||
@@ -0,0 +1,1090 @@ | |||
1 | /* Parse C expressions for CCCP. | ||
2 | * Copyright (C) 1987, 1992, 1994, 1995 Free Software Foundation. | ||
3 | * Copyright (C) 2003-2011 Kim Woelders | ||
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 2, 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; if not, write to the Free Software | ||
17 | * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | * | ||
19 | * In other words, you are welcome to use, share and improve this program. | ||
20 | * You are forbidden to forbid anyone else to use, share and improve | ||
21 | * what you give them. Help stamp out software-hoarding! | ||
22 | * | ||
23 | * Written by Per Bothner 1994. */ | ||
24 | |||
25 | /* Parse a C expression from text in a string */ | ||
26 | |||
27 | #ifdef HAVE_CONFIG_H | ||
28 | # include <config.h> | ||
29 | #endif | ||
30 | |||
31 | #ifdef __EMX__ | ||
32 | # include <strings.h> | ||
33 | #endif | ||
34 | |||
35 | #ifdef MULTIBYTE_CHARS | ||
36 | # include <locale.h> | ||
37 | #endif | ||
38 | |||
39 | #include <stdlib.h> | ||
40 | #include <stdio.h> | ||
41 | #include <string.h> | ||
42 | |||
43 | #include "cpplib.h" | ||
44 | #include "cpphash.h" | ||
45 | |||
46 | /* This is used for communicating lists of keywords with cccp.c. */ | ||
47 | struct arglist { | ||
48 | struct arglist *next; | ||
49 | unsigned char *name; | ||
50 | int length; | ||
51 | int argno; | ||
52 | }; | ||
53 | |||
54 | /* Define a generic NULL if one hasn't already been defined. */ | ||
55 | |||
56 | #ifndef NULL | ||
57 | #define NULL 0 | ||
58 | #endif | ||
59 | |||
60 | #ifndef GENERIC_PTR | ||
61 | #if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) | ||
62 | #define GENERIC_PTR void * | ||
63 | #else | ||
64 | #define GENERIC_PTR char * | ||
65 | #endif | ||
66 | #endif | ||
67 | |||
68 | #ifndef NULL_PTR | ||
69 | #define NULL_PTR ((GENERIC_PTR)0) | ||
70 | #endif | ||
71 | |||
72 | #ifndef CHAR_TYPE_SIZE | ||
73 | #define CHAR_TYPE_SIZE BITS_PER_UNIT | ||
74 | #endif | ||
75 | |||
76 | #ifndef INT_TYPE_SIZE | ||
77 | #define INT_TYPE_SIZE BITS_PER_WORD | ||
78 | #endif | ||
79 | |||
80 | #ifndef LONG_TYPE_SIZE | ||
81 | #define LONG_TYPE_SIZE BITS_PER_WORD | ||
82 | #endif | ||
83 | |||
84 | #ifndef WCHAR_TYPE_SIZE | ||
85 | #define WCHAR_TYPE_SIZE INT_TYPE_SIZE | ||
86 | #endif | ||
87 | |||
88 | #ifndef MAX_CHAR_TYPE_SIZE | ||
89 | #define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE | ||
90 | #endif | ||
91 | |||
92 | #ifndef MAX_INT_TYPE_SIZE | ||
93 | #define MAX_INT_TYPE_SIZE INT_TYPE_SIZE | ||
94 | #endif | ||
95 | |||
96 | #ifndef MAX_LONG_TYPE_SIZE | ||
97 | #define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE | ||
98 | #endif | ||
99 | |||
100 | #ifndef MAX_WCHAR_TYPE_SIZE | ||
101 | #define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE | ||
102 | #endif | ||
103 | |||
104 | /* Yield nonzero if adding two numbers with A's and B's signs can yield a | ||
105 | * number with SUM's sign, where A, B, and SUM are all C integers. */ | ||
106 | #define possible_sum_sign(a, b, sum) ((((a) ^ (b)) | ~ ((a) ^ (sum))) < 0) | ||
107 | |||
108 | #define ERROR 299 | ||
109 | #define OROR 300 | ||
110 | #define ANDAND 301 | ||
111 | #define EQUAL 302 | ||
112 | #define NOTEQUAL 303 | ||
113 | #define LEQ 304 | ||
114 | #define GEQ 305 | ||
115 | #define LSH 306 | ||
116 | #define RSH 307 | ||
117 | #define NAME 308 | ||
118 | #define INT 309 | ||
119 | #define CHAR 310 | ||
120 | |||
121 | #define LEFT_OPERAND_REQUIRED 1 | ||
122 | #define RIGHT_OPERAND_REQUIRED 2 | ||
123 | #define HAVE_VALUE 4 | ||
124 | /* SKIP_OPERAND is set for '&&' '||' '?' and ':' when the | ||
125 | * following operand should be short-circuited instead of evaluated. */ | ||
126 | #define SKIP_OPERAND 8 | ||
127 | /*#define UNSIGNEDP 16 */ | ||
128 | |||
129 | struct operation { | ||
130 | short op; | ||
131 | char rprio; /* Priority of op (relative to it right operand). */ | ||
132 | char flags; | ||
133 | char unsignedp; /* true if value should be treated as unsigned */ | ||
134 | HOST_WIDE_INT value; /* The value logically "right" of op. */ | ||
135 | }; | ||
136 | |||
137 | /* Take care of parsing a number (anything that starts with a digit). | ||
138 | * LEN is the number of characters in it. */ | ||
139 | |||
140 | /* maybe needs to actually deal with floating point numbers */ | ||
141 | |||
142 | static void | ||
143 | parse_number(struct operation *op, cpp_reader * pfile, const char *start, | ||
144 | int olen) | ||
145 | { | ||
146 | const char *p = start; | ||
147 | int c; | ||
148 | unsigned long n = 0, nd, ULONG_MAX_over_base; | ||
149 | int base = 10; | ||
150 | int len = olen; | ||
151 | int overflow = 0; | ||
152 | int digit, largest_digit = 0; | ||
153 | int spec_long = 0; | ||
154 | |||
155 | op->unsignedp = 0; | ||
156 | |||
157 | for (c = 0; c < len; c++) | ||
158 | if (p[c] == '.') | ||
159 | { | ||
160 | /* It's a float since it contains a point. */ | ||
161 | cpp_error(pfile, | ||
162 | "floating point numbers not allowed in #if expressions"); | ||
163 | op->op = ERROR; | ||
164 | return; | ||
165 | } | ||
166 | if (len >= 3 && (!strncmp(p, "0x", 2) || !strncmp(p, "0X", 2))) | ||
167 | { | ||
168 | p += 2; | ||
169 | base = 16; | ||
170 | len -= 2; | ||
171 | } | ||
172 | else if (*p == '0') | ||
173 | base = 8; | ||
174 | |||
175 | /* Some buggy compilers (e.g. MPW C) seem to need both casts. */ | ||
176 | ULONG_MAX_over_base = ((unsigned long)-1) / ((unsigned long)base); | ||
177 | |||
178 | for (; len > 0; len--) | ||
179 | { | ||
180 | c = *p++; | ||
181 | |||
182 | if (c >= '0' && c <= '9') | ||
183 | digit = c - '0'; | ||
184 | else if (base == 16 && c >= 'a' && c <= 'f') | ||
185 | digit = c - 'a' + 10; | ||
186 | else if (base == 16 && c >= 'A' && c <= 'F') | ||
187 | digit = c - 'A' + 10; | ||
188 | else | ||
189 | { | ||
190 | /* `l' means long, and `u' means unsigned. */ | ||
191 | while (1) | ||
192 | { | ||
193 | if (c == 'l' || c == 'L') | ||
194 | { | ||
195 | if (spec_long) | ||
196 | cpp_error(pfile, "two `l's in integer constant"); | ||
197 | spec_long = 1; | ||
198 | } | ||
199 | else if (c == 'u' || c == 'U') | ||
200 | { | ||
201 | if (op->unsignedp) | ||
202 | cpp_error(pfile, "two `u's in integer constant"); | ||
203 | op->unsignedp = 1; | ||
204 | } | ||
205 | else | ||
206 | break; | ||
207 | |||
208 | if (--len == 0) | ||
209 | break; | ||
210 | c = *p++; | ||
211 | } | ||
212 | /* Don't look for any more digits after the suffixes. */ | ||
213 | break; | ||
214 | } | ||
215 | if (largest_digit < digit) | ||
216 | largest_digit = digit; | ||
217 | nd = n * base + digit; | ||
218 | overflow |= (ULONG_MAX_over_base < n) | (nd < n); | ||
219 | n = nd; | ||
220 | } | ||
221 | |||
222 | if (len != 0) | ||
223 | { | ||
224 | cpp_error(pfile, "Invalid number in #if expression"); | ||
225 | op->op = ERROR; | ||
226 | return; | ||
227 | } | ||
228 | if (base <= largest_digit) | ||
229 | cpp_warning(pfile, "integer constant contains digits beyond the radix"); | ||
230 | |||
231 | if (overflow) | ||
232 | cpp_warning(pfile, "integer constant out of range"); | ||
233 | |||
234 | /* If too big to be signed, consider it unsigned. */ | ||
235 | if ((long)n < 0 && !op->unsignedp) | ||
236 | { | ||
237 | if (base == 10) | ||
238 | cpp_warning(pfile, | ||
239 | "integer constant is so large that it is unsigned"); | ||
240 | op->unsignedp = 1; | ||
241 | } | ||
242 | op->value = n; | ||
243 | op->op = INT; | ||
244 | } | ||
245 | |||
246 | struct token { | ||
247 | const char *oper; | ||
248 | int token; | ||
249 | }; | ||
250 | |||
251 | static struct token tokentab2[] = { | ||
252 | {"&&", ANDAND}, | ||
253 | {"||", OROR}, | ||
254 | {"<<", LSH}, | ||
255 | {">>", RSH}, | ||
256 | {"==", EQUAL}, | ||
257 | {"!=", NOTEQUAL}, | ||
258 | {"<=", LEQ}, | ||
259 | {">=", GEQ}, | ||
260 | {"++", ERROR}, | ||
261 | {"--", ERROR}, | ||
262 | {NULL, ERROR} | ||
263 | }; | ||
264 | |||
265 | /* Read one token. */ | ||
266 | |||
267 | static void | ||
268 | cpp_lex(struct operation *op, cpp_reader * pfile) | ||
269 | { | ||
270 | int c; | ||
271 | struct token *toktab; | ||
272 | enum cpp_token token; | ||
273 | unsigned char *tok_start, *tok_end; | ||
274 | int old_written; | ||
275 | |||
276 | op->value = 0; | ||
277 | op->unsignedp = 0; | ||
278 | |||
279 | retry: | ||
280 | |||
281 | old_written = CPP_WRITTEN(pfile); | ||
282 | cpp_skip_hspace(pfile); | ||
283 | c = CPP_BUF_PEEK(CPP_BUFFER(pfile)); | ||
284 | if (c == '#') | ||
285 | { | ||
286 | parse_number(op, pfile, cpp_read_check_assertion(pfile) ? "1" : "0", 1); | ||
287 | return; | ||
288 | } | ||
289 | |||
290 | if (c == '\n') | ||
291 | { | ||
292 | op->op = 0; | ||
293 | return; | ||
294 | } | ||
295 | token = cpp_get_token(pfile); | ||
296 | tok_start = pfile->token_buffer + old_written; | ||
297 | tok_end = CPP_PWRITTEN(pfile); | ||
298 | pfile->limit = tok_start; | ||
299 | switch (token) | ||
300 | { | ||
301 | case CPP_EOF: /* Should not happen ... */ | ||
302 | op->op = 0; | ||
303 | break; | ||
304 | |||
305 | case CPP_VSPACE: | ||
306 | case CPP_POP: | ||
307 | if (CPP_BUFFER(pfile)->fname) | ||
308 | { | ||
309 | op->op = 0; | ||
310 | break; | ||
311 | } | ||
312 | goto retry; | ||
313 | |||
314 | case CPP_HSPACE: | ||
315 | case CPP_COMMENT: | ||
316 | goto retry; | ||
317 | |||
318 | case CPP_NUMBER: | ||
319 | parse_number(op, pfile, (char *)tok_start, tok_end - tok_start); | ||
320 | break; | ||
321 | |||
322 | case CPP_STRING: | ||
323 | cpp_error(pfile, "string constants not allowed in #if expressions"); | ||
324 | op->op = ERROR; | ||
325 | break; | ||
326 | |||
327 | case CPP_CHAR: | ||
328 | /* This code for reading a character constant | ||
329 | * handles multicharacter constants and wide characters. | ||
330 | * It is mostly copied from c-lex.c. */ | ||
331 | { | ||
332 | int result = 0; | ||
333 | int num_chars = 0; | ||
334 | unsigned width = MAX_CHAR_TYPE_SIZE; | ||
335 | int wide_flag = 0; | ||
336 | int max_chars; | ||
337 | char *ptr = (char *)tok_start; | ||
338 | |||
339 | #ifdef MULTIBYTE_CHARS | ||
340 | char token_buffer[MAX_LONG_TYPE_SIZE / | ||
341 | MAX_CHAR_TYPE_SIZE + MB_CUR_MAX]; | ||
342 | #endif | ||
343 | |||
344 | if (*ptr == 'L') | ||
345 | { | ||
346 | ptr++; | ||
347 | wide_flag = 1; | ||
348 | width = MAX_WCHAR_TYPE_SIZE; | ||
349 | #ifdef MULTIBYTE_CHARS | ||
350 | max_chars = MB_CUR_MAX; | ||
351 | #else | ||
352 | max_chars = 1; | ||
353 | #endif | ||
354 | } | ||
355 | else | ||
356 | max_chars = MAX_LONG_TYPE_SIZE / width; | ||
357 | |||
358 | while (1) | ||
359 | { | ||
360 | if (ptr >= (char *)CPP_PWRITTEN(pfile) || (c = *ptr++) == '\'') | ||
361 | break; | ||
362 | |||
363 | if (c == '\\') | ||
364 | { | ||
365 | c = cpp_parse_escape(pfile, &ptr); | ||
366 | if (width < HOST_BITS_PER_INT | ||
367 | && (unsigned)c >= (unsigned)(1 << width)) | ||
368 | cpp_pedwarn(pfile, | ||
369 | "escape sequence out of range for character"); | ||
370 | } | ||
371 | num_chars++; | ||
372 | |||
373 | /* Merge character into result; ignore excess chars. */ | ||
374 | if (num_chars < max_chars + 1) | ||
375 | { | ||
376 | if (width < HOST_BITS_PER_INT) | ||
377 | result = (result << width) | (c & ((1 << width) - 1)); | ||
378 | else | ||
379 | result = c; | ||
380 | #ifdef MULTIBYTE_CHARS | ||
381 | token_buffer[num_chars - 1] = c; | ||
382 | #endif | ||
383 | } | ||
384 | } | ||
385 | |||
386 | #ifdef MULTIBYTE_CHARS | ||
387 | token_buffer[num_chars] = 0; | ||
388 | #endif | ||
389 | |||
390 | if (c != '\'') | ||
391 | cpp_error(pfile, "malformatted character constant"); | ||
392 | else if (num_chars == 0) | ||
393 | cpp_error(pfile, "empty character constant"); | ||
394 | else if (num_chars > max_chars) | ||
395 | { | ||
396 | num_chars = max_chars; | ||
397 | cpp_error(pfile, "character constant too long"); | ||
398 | } | ||
399 | else if (num_chars != 1 && !CPP_TRADITIONAL(pfile)) | ||
400 | cpp_warning(pfile, "multi-character character constant"); | ||
401 | |||
402 | /* If char type is signed, sign-extend the constant. */ | ||
403 | if (!wide_flag) | ||
404 | { | ||
405 | int num_bits = num_chars * width; | ||
406 | |||
407 | if (cpp_lookup("__CHAR_UNSIGNED__", | ||
408 | sizeof("__CHAR_UNSIGNED__") - 1, -1) | ||
409 | || ((result >> (num_bits - 1)) & 1) == 0) | ||
410 | op->value = | ||
411 | result & ((unsigned long)~0 >> | ||
412 | (HOST_BITS_PER_LONG - num_bits)); | ||
413 | else | ||
414 | op->value = | ||
415 | result | ~((unsigned long)~0 >> | ||
416 | (HOST_BITS_PER_LONG - num_bits)); | ||
417 | } | ||
418 | else | ||
419 | { | ||
420 | #ifdef MULTIBYTE_CHARS | ||
421 | /* Set the initial shift state and convert the next sequence. */ | ||
422 | result = 0; | ||
423 | /* In all locales L'\0' is zero and mbtowc will return zero, | ||
424 | * so don't use it. */ | ||
425 | if (num_chars > 1 | ||
426 | || (num_chars == 1 && token_buffer[0] != '\0')) | ||
427 | { | ||
428 | wchar_t wc; | ||
429 | |||
430 | (void)mbtowc(NULL_PTR, NULL_PTR, 0); | ||
431 | if (mbtowc(&wc, token_buffer, num_chars) == num_chars) | ||
432 | result = wc; | ||
433 | else | ||
434 | cpp_warning(pfile, | ||
435 | "Ignoring invalid multibyte character"); | ||
436 | } | ||
437 | #endif | ||
438 | op->value = result; | ||
439 | } | ||
440 | } | ||
441 | |||
442 | /* This is always a signed type. */ | ||
443 | op->unsignedp = 0; | ||
444 | op->op = CHAR; | ||
445 | break; | ||
446 | |||
447 | case CPP_NAME: | ||
448 | parse_number(op, pfile, "0", 0); | ||
449 | break; | ||
450 | |||
451 | case CPP_OTHER: | ||
452 | /* See if it is a special token of length 2. */ | ||
453 | if (tok_start + 2 == tok_end) | ||
454 | { | ||
455 | for (toktab = tokentab2; toktab->oper; toktab++) | ||
456 | if (tok_start[0] == toktab->oper[0] | ||
457 | && tok_start[1] == toktab->oper[1]) | ||
458 | break; | ||
459 | if (toktab->token == ERROR) | ||
460 | { | ||
461 | char *buf = (char *)malloc(40); | ||
462 | |||
463 | memset(buf, 0, 40); | ||
464 | |||
465 | sprintf(buf, "`%s' not allowed in operand of `#if'", | ||
466 | tok_start); | ||
467 | cpp_error(pfile, buf); | ||
468 | free(buf); | ||
469 | } | ||
470 | op->op = toktab->token; | ||
471 | break; | ||
472 | } | ||
473 | /* fall through */ | ||
474 | default: | ||
475 | op->op = *tok_start; | ||
476 | break; | ||
477 | } | ||
478 | } | ||
479 | |||
480 | /* Parse a C escape sequence. STRING_PTR points to a variable | ||
481 | * containing a pointer to the string to parse. That pointer | ||
482 | * is updated past the characters we use. The value of the | ||
483 | * escape sequence is returned. | ||
484 | * | ||
485 | * A negative value means the sequence \ newline was seen, | ||
486 | * which is supposed to be equivalent to nothing at all. | ||
487 | * | ||
488 | * If \ is followed by a null character, we return a negative | ||
489 | * value and leave the string pointer pointing at the null character. | ||
490 | * | ||
491 | * If \ is followed by 000, we return 0 and leave the string pointer | ||
492 | * after the zeros. A value of 0 does not mean end of string. */ | ||
493 | |||
494 | int | ||
495 | cpp_parse_escape(cpp_reader * pfile, char **string_ptr) | ||
496 | { | ||
497 | int c = *(*string_ptr)++; | ||
498 | |||
499 | switch (c) | ||
500 | { | ||
501 | case 'a': | ||
502 | return TARGET_BELL; | ||
503 | case 'b': | ||
504 | return TARGET_BS; | ||
505 | case 'e': | ||
506 | case 'E': | ||
507 | if (CPP_PEDANTIC(pfile)) | ||
508 | cpp_pedwarn(pfile, "non-ANSI-standard escape sequence, `\\%c'", c); | ||
509 | return 033; | ||
510 | case 'f': | ||
511 | return TARGET_FF; | ||
512 | case 'n': | ||
513 | return TARGET_NEWLINE; | ||
514 | case 'r': | ||
515 | return TARGET_CR; | ||
516 | case 't': | ||
517 | return TARGET_TAB; | ||
518 | case 'v': | ||
519 | return TARGET_VT; | ||
520 | case '\n': | ||
521 | return -2; | ||
522 | case 0: | ||
523 | (*string_ptr)--; | ||
524 | return 0; | ||
525 | |||
526 | case '0': | ||
527 | case '1': | ||
528 | case '2': | ||
529 | case '3': | ||
530 | case '4': | ||
531 | case '5': | ||
532 | case '6': | ||
533 | case '7': | ||
534 | { | ||
535 | int i = c - '0'; | ||
536 | int count = 0; | ||
537 | |||
538 | while (++count < 3) | ||
539 | { | ||
540 | c = *(*string_ptr)++; | ||
541 | if (c >= '0' && c <= '7') | ||
542 | i = (i << 3) + c - '0'; | ||
543 | else | ||
544 | { | ||
545 | (*string_ptr)--; | ||
546 | break; | ||
547 | } | ||
548 | } | ||
549 | if ((i & ~((1 << MAX_CHAR_TYPE_SIZE) - 1)) != 0) | ||
550 | { | ||
551 | i &= (1 << MAX_CHAR_TYPE_SIZE) - 1; | ||
552 | cpp_warning(pfile, | ||
553 | "octal character constant does not fit in a byte"); | ||
554 | } | ||
555 | return i; | ||
556 | } | ||
557 | case 'x': | ||
558 | { | ||
559 | unsigned i = 0, overflow = 0, digits_found = 0, digit; | ||
560 | |||
561 | for (;;) | ||
562 | { | ||
563 | c = *(*string_ptr)++; | ||
564 | if (c >= '0' && c <= '9') | ||
565 | digit = c - '0'; | ||
566 | else if (c >= 'a' && c <= 'f') | ||
567 | digit = c - 'a' + 10; | ||
568 | else if (c >= 'A' && c <= 'F') | ||
569 | digit = c - 'A' + 10; | ||
570 | else | ||
571 | { | ||
572 | (*string_ptr)--; | ||
573 | break; | ||
574 | } | ||
575 | overflow |= i ^ (i << 4 >> 4); | ||
576 | i = (i << 4) + digit; | ||
577 | digits_found = 1; | ||
578 | } | ||
579 | if (!digits_found) | ||
580 | cpp_error(pfile, "\\x used with no following hex digits"); | ||
581 | if (overflow | (i & ~((1 << BITS_PER_UNIT) - 1))) | ||
582 | { | ||
583 | i &= (1 << BITS_PER_UNIT) - 1; | ||
584 | cpp_warning(pfile, | ||
585 | "hex character constant does not fit in a byte"); | ||
586 | } | ||
587 | return i; | ||
588 | } | ||
589 | default: | ||
590 | return c; | ||
591 | } | ||
592 | } | ||
593 | |||
594 | static void | ||
595 | integer_overflow(cpp_reader * pfile) | ||
596 | { | ||
597 | if (CPP_PEDANTIC(pfile)) | ||
598 | cpp_pedwarn(pfile, "integer overflow in preprocessor expression"); | ||
599 | } | ||
600 | |||
601 | static long | ||
602 | left_shift(cpp_reader * pfile, long a, int unsignedp, unsigned long b) | ||
603 | { | ||
604 | if (b >= HOST_BITS_PER_LONG) | ||
605 | { | ||
606 | if (!unsignedp && a != 0) | ||
607 | integer_overflow(pfile); | ||
608 | return 0; | ||
609 | } | ||
610 | else if (unsignedp) | ||
611 | return (unsigned long)a << b; | ||
612 | else | ||
613 | { | ||
614 | long l = a << b; | ||
615 | |||
616 | if (l >> b != a) | ||
617 | integer_overflow(pfile); | ||
618 | return l; | ||
619 | } | ||
620 | } | ||
621 | |||
622 | static long | ||
623 | right_shift(cpp_reader * pfile __UNUSED__, long a, int unsignedp, | ||
624 | unsigned long b) | ||
625 | { | ||
626 | if (b >= HOST_BITS_PER_LONG) | ||
627 | { | ||
628 | return unsignedp ? 0 : a >> (HOST_BITS_PER_LONG - 1); | ||
629 | } | ||
630 | else if (unsignedp) | ||
631 | { | ||
632 | return (unsigned long)a >> b; | ||
633 | } | ||
634 | else | ||
635 | { | ||
636 | return a >> b; | ||
637 | } | ||
638 | } | ||
639 | |||
640 | /* These priorities are all even, so we can handle associatively. */ | ||
641 | #define PAREN_INNER_PRIO 0 | ||
642 | #define COMMA_PRIO 4 | ||
643 | #define COND_PRIO (COMMA_PRIO+2) | ||
644 | #define OROR_PRIO (COND_PRIO+2) | ||
645 | #define ANDAND_PRIO (OROR_PRIO+2) | ||
646 | #define OR_PRIO (ANDAND_PRIO+2) | ||
647 | #define XOR_PRIO (OR_PRIO+2) | ||
648 | #define AND_PRIO (XOR_PRIO+2) | ||
649 | #define EQUAL_PRIO (AND_PRIO+2) | ||
650 | #define LESS_PRIO (EQUAL_PRIO+2) | ||
651 | #define SHIFT_PRIO (LESS_PRIO+2) | ||
652 | #define PLUS_PRIO (SHIFT_PRIO+2) | ||
653 | #define MUL_PRIO (PLUS_PRIO+2) | ||
654 | #define UNARY_PRIO (MUL_PRIO+2) | ||
655 | #define PAREN_OUTER_PRIO (UNARY_PRIO+2) | ||
656 | |||
657 | #define COMPARE(OP) \ | ||
658 | top->unsignedp = 0;\ | ||
659 | top->value = (unsigned1 || unsigned2) ? (unsigned long) v1 OP (unsigned long) v2 : (v1 OP v2) | ||
660 | |||
661 | /* Parse and evaluate a C expression, reading from PFILE. | ||
662 | * Returns the value of the expression. */ | ||
663 | |||
664 | HOST_WIDE_INT | ||
665 | cpp_parse_expr(cpp_reader * pfile) | ||
666 | { | ||
667 | /* The implementation is an operator precedence parser, | ||
668 | * i.e. a bottom-up parser, using a stack for not-yet-reduced tokens. | ||
669 | * | ||
670 | * The stack base is 'stack', and the current stack pointer is 'top'. | ||
671 | * There is a stack element for each operator (only), | ||
672 | * and the most recently pushed operator is 'top->op'. | ||
673 | * An operand (value) is stored in the 'value' field of the stack | ||
674 | * element of the operator that precedes it. | ||
675 | * In that case the 'flags' field has the HAVE_VALUE flag set. */ | ||
676 | |||
677 | #define INIT_STACK_SIZE 20 | ||
678 | struct operation init_stack[INIT_STACK_SIZE]; | ||
679 | struct operation *stack = init_stack; | ||
680 | struct operation *limit = stack + INIT_STACK_SIZE; | ||
681 | struct operation *top = stack; | ||
682 | int lprio = 0, rprio = 0; | ||
683 | int skip_evaluation = 0; | ||
684 | |||
685 | top->rprio = 0; | ||
686 | top->flags = 0; | ||
687 | for (;;) | ||
688 | { | ||
689 | struct operation op; | ||
690 | char flags = 0; | ||
691 | |||
692 | /* Read a token */ | ||
693 | cpp_lex(&op, pfile); | ||
694 | |||
695 | /* See if the token is an operand, in which case go to set_value. | ||
696 | * If the token is an operator, figure out its left and right | ||
697 | * priorities, and then goto maybe_reduce. */ | ||
698 | |||
699 | switch (op.op) | ||
700 | { | ||
701 | case NAME: | ||
702 | top->value = 0, top->unsignedp = 0; | ||
703 | goto set_value; | ||
704 | case INT: | ||
705 | case CHAR: | ||
706 | top->value = op.value; | ||
707 | top->unsignedp = op.unsignedp; | ||
708 | goto set_value; | ||
709 | case 0: | ||
710 | lprio = 0; | ||
711 | goto maybe_reduce; | ||
712 | case '+': | ||
713 | case '-': | ||
714 | /* Is this correct if unary ? FIXME */ | ||
715 | flags = RIGHT_OPERAND_REQUIRED; | ||
716 | lprio = PLUS_PRIO; | ||
717 | rprio = lprio + 1; | ||
718 | goto maybe_reduce; | ||
719 | case '!': | ||
720 | case '~': | ||
721 | flags = RIGHT_OPERAND_REQUIRED; | ||
722 | rprio = UNARY_PRIO; | ||
723 | lprio = rprio + 1; | ||
724 | goto maybe_reduce; | ||
725 | case '*': | ||
726 | case '/': | ||
727 | case '%': | ||
728 | lprio = MUL_PRIO; | ||
729 | goto binop; | ||
730 | case '<': | ||
731 | case '>': | ||
732 | case LEQ: | ||
733 | case GEQ: | ||
734 | lprio = LESS_PRIO; | ||
735 | goto binop; | ||
736 | case EQUAL: | ||
737 | case NOTEQUAL: | ||
738 | lprio = EQUAL_PRIO; | ||
739 | goto binop; | ||
740 | case LSH: | ||
741 | case RSH: | ||
742 | lprio = SHIFT_PRIO; | ||
743 | goto binop; | ||
744 | case '&': | ||
745 | lprio = AND_PRIO; | ||
746 | goto binop; | ||
747 | case '^': | ||
748 | lprio = XOR_PRIO; | ||
749 | goto binop; | ||
750 | case '|': | ||
751 | lprio = OR_PRIO; | ||
752 | goto binop; | ||
753 | case ANDAND: | ||
754 | lprio = ANDAND_PRIO; | ||
755 | goto binop; | ||
756 | case OROR: | ||
757 | lprio = OROR_PRIO; | ||
758 | goto binop; | ||
759 | case ',': | ||
760 | lprio = COMMA_PRIO; | ||
761 | goto binop; | ||
762 | case '(': | ||
763 | lprio = PAREN_OUTER_PRIO; | ||
764 | rprio = PAREN_INNER_PRIO; | ||
765 | goto maybe_reduce; | ||
766 | case ')': | ||
767 | lprio = PAREN_INNER_PRIO; | ||
768 | rprio = PAREN_OUTER_PRIO; | ||
769 | goto maybe_reduce; | ||
770 | case ':': | ||
771 | lprio = COND_PRIO; | ||
772 | rprio = COND_PRIO; | ||
773 | goto maybe_reduce; | ||
774 | case '?': | ||
775 | lprio = COND_PRIO + 1; | ||
776 | rprio = COND_PRIO; | ||
777 | goto maybe_reduce; | ||
778 | binop: | ||
779 | flags = LEFT_OPERAND_REQUIRED | RIGHT_OPERAND_REQUIRED; | ||
780 | rprio = lprio + 1; | ||
781 | goto maybe_reduce; | ||
782 | default: | ||
783 | cpp_error(pfile, "invalid character in #if"); | ||
784 | goto syntax_error; | ||
785 | } | ||
786 | |||
787 | set_value: | ||
788 | /* Push a value onto the stack. */ | ||
789 | if (top->flags & HAVE_VALUE) | ||
790 | { | ||
791 | cpp_error(pfile, "syntax error in #if"); | ||
792 | goto syntax_error; | ||
793 | } | ||
794 | top->flags |= HAVE_VALUE; | ||
795 | continue; | ||
796 | |||
797 | maybe_reduce: | ||
798 | /* Push an operator, and check if we can reduce now. */ | ||
799 | while (top->rprio > lprio) | ||
800 | { | ||
801 | long v1 = top[-1].value, v2 = top[0].value; | ||
802 | int unsigned1 = top[-1].unsignedp, unsigned2 = | ||
803 | top[0].unsignedp; | ||
804 | |||
805 | top--; | ||
806 | if ((top[1].flags & LEFT_OPERAND_REQUIRED) | ||
807 | && !(top[0].flags & HAVE_VALUE)) | ||
808 | { | ||
809 | cpp_error(pfile, "syntax error - missing left operand"); | ||
810 | goto syntax_error; | ||
811 | } | ||
812 | if ((top[1].flags & RIGHT_OPERAND_REQUIRED) | ||
813 | && !(top[1].flags & HAVE_VALUE)) | ||
814 | { | ||
815 | cpp_error(pfile, "syntax error - missing right operand"); | ||
816 | goto syntax_error; | ||
817 | } | ||
818 | /* top[0].value = (top[1].op)(v1, v2); */ | ||
819 | switch (top[1].op) | ||
820 | { | ||
821 | case '+': | ||
822 | if (!(top->flags & HAVE_VALUE)) | ||
823 | { /* Unary '+' */ | ||
824 | top->value = v2; | ||
825 | top->unsignedp = unsigned2; | ||
826 | top->flags |= HAVE_VALUE; | ||
827 | } | ||
828 | else | ||
829 | { | ||
830 | top->value = v1 + v2; | ||
831 | top->unsignedp = unsigned1 || unsigned2; | ||
832 | if (!top->unsignedp && !skip_evaluation | ||
833 | && !possible_sum_sign(v1, v2, top->value)) | ||
834 | integer_overflow(pfile); | ||
835 | } | ||
836 | break; | ||
837 | case '-': | ||
838 | if (skip_evaluation); /* do nothing */ | ||
839 | else if (!(top->flags & HAVE_VALUE)) | ||
840 | { /* Unary '-' */ | ||
841 | top->value = -v2; | ||
842 | if ((top->value & v2) < 0 && !unsigned2) | ||
843 | integer_overflow(pfile); | ||
844 | top->unsignedp = unsigned2; | ||
845 | top->flags |= HAVE_VALUE; | ||
846 | } | ||
847 | else | ||
848 | { /* Binary '-' */ | ||
849 | top->value = v1 - v2; | ||
850 | top->unsignedp = unsigned1 || unsigned2; | ||
851 | if (!top->unsignedp | ||
852 | && !possible_sum_sign(top->value, v2, v1)) | ||
853 | integer_overflow(pfile); | ||
854 | } | ||
855 | break; | ||
856 | case '*': | ||
857 | top->unsignedp = unsigned1 || unsigned2; | ||
858 | if (top->unsignedp) | ||
859 | top->value = (unsigned long)v1 *v2; | ||
860 | |||
861 | else if (!skip_evaluation) | ||
862 | { | ||
863 | top->value = v1 * v2; | ||
864 | if (v1 | ||
865 | && (top->value / v1 != v2 | ||
866 | || (top->value & v1 & v2) < 0)) | ||
867 | integer_overflow(pfile); | ||
868 | } | ||
869 | break; | ||
870 | case '/': | ||
871 | if (skip_evaluation) | ||
872 | break; | ||
873 | if (v2 == 0) | ||
874 | { | ||
875 | cpp_error(pfile, "division by zero in #if"); | ||
876 | v2 = 1; | ||
877 | } | ||
878 | top->unsignedp = unsigned1 || unsigned2; | ||
879 | if (top->unsignedp) | ||
880 | top->value = (unsigned long)v1 / v2; | ||
881 | else | ||
882 | { | ||
883 | top->value = v1 / v2; | ||
884 | if ((top->value & v1 & v2) < 0) | ||
885 | integer_overflow(pfile); | ||
886 | } | ||
887 | break; | ||
888 | case '%': | ||
889 | if (skip_evaluation) | ||
890 | break; | ||
891 | if (v2 == 0) | ||
892 | { | ||
893 | cpp_error(pfile, "division by zero in #if"); | ||
894 | v2 = 1; | ||
895 | } | ||
896 | top->unsignedp = unsigned1 || unsigned2; | ||
897 | if (top->unsignedp) | ||
898 | top->value = (unsigned long)v1 % v2; | ||
899 | else | ||
900 | top->value = v1 % v2; | ||
901 | break; | ||
902 | case '!': | ||
903 | if (top->flags & HAVE_VALUE) | ||
904 | { | ||
905 | cpp_error(pfile, "syntax error"); | ||
906 | goto syntax_error; | ||
907 | } | ||
908 | top->value = !v2; | ||
909 | top->unsignedp = 0; | ||
910 | top->flags |= HAVE_VALUE; | ||
911 | break; | ||
912 | case '~': | ||
913 | if (top->flags & HAVE_VALUE) | ||
914 | { | ||
915 | cpp_error(pfile, "syntax error"); | ||
916 | goto syntax_error; | ||
917 | } | ||
918 | top->value = ~v2; | ||
919 | top->unsignedp = unsigned2; | ||
920 | top->flags |= HAVE_VALUE; | ||
921 | break; | ||
922 | case '<': | ||
923 | COMPARE(<); | ||
924 | break; | ||
925 | case '>': | ||
926 | COMPARE(>); | ||
927 | break; | ||
928 | case LEQ: | ||
929 | COMPARE(<=); | ||
930 | break; | ||
931 | case GEQ: | ||
932 | COMPARE(>=); | ||
933 | break; | ||
934 | case EQUAL: | ||
935 | top->value = (v1 == v2); | ||
936 | top->unsignedp = 0; | ||
937 | break; | ||
938 | case NOTEQUAL: | ||
939 | top->value = (v1 != v2); | ||
940 | top->unsignedp = 0; | ||
941 | break; | ||
942 | case LSH: | ||
943 | if (skip_evaluation) | ||
944 | break; | ||
945 | top->unsignedp = unsigned1; | ||
946 | if (v2 < 0 && !unsigned2) | ||
947 | top->value = right_shift(pfile, v1, unsigned1, -v2); | ||
948 | else | ||
949 | top->value = left_shift(pfile, v1, unsigned1, v2); | ||
950 | break; | ||
951 | case RSH: | ||
952 | if (skip_evaluation) | ||
953 | break; | ||
954 | top->unsignedp = unsigned1; | ||
955 | if (v2 < 0 && !unsigned2) | ||
956 | top->value = left_shift(pfile, v1, unsigned1, -v2); | ||
957 | else | ||
958 | top->value = right_shift(pfile, v1, unsigned1, v2); | ||
959 | break; | ||
960 | #define LOGICAL(OP) \ | ||
961 | top->value = v1 OP v2;\ | ||
962 | top->unsignedp = unsigned1 || unsigned2; | ||
963 | case '&': | ||
964 | LOGICAL(&); | ||
965 | break; | ||
966 | case '^': | ||
967 | LOGICAL(^); | ||
968 | break; | ||
969 | case '|': | ||
970 | LOGICAL(|); | ||
971 | break; | ||
972 | case ANDAND: | ||
973 | top->value = v1 && v2; | ||
974 | top->unsignedp = 0; | ||
975 | if (!v1) | ||
976 | skip_evaluation--; | ||
977 | break; | ||
978 | case OROR: | ||
979 | top->value = v1 || v2; | ||
980 | top->unsignedp = 0; | ||
981 | if (v1) | ||
982 | skip_evaluation--; | ||
983 | break; | ||
984 | case ',': | ||
985 | if (CPP_PEDANTIC(pfile)) | ||
986 | cpp_pedwarn(pfile, "comma operator in operand of `#if'"); | ||
987 | top->value = v2; | ||
988 | top->unsignedp = unsigned2; | ||
989 | break; | ||
990 | case '(': | ||
991 | case '?': | ||
992 | cpp_error(pfile, "syntax error in #if"); | ||
993 | goto syntax_error; | ||
994 | case ':': | ||
995 | if (top[0].op != '?') | ||
996 | { | ||
997 | cpp_error(pfile, | ||
998 | "syntax error ':' without preceding '?'"); | ||
999 | goto syntax_error; | ||
1000 | } | ||
1001 | else if (!(top[1].flags & HAVE_VALUE) | ||
1002 | || !(top[-1].flags & HAVE_VALUE) | ||
1003 | || !(top[0].flags & HAVE_VALUE)) | ||
1004 | { | ||
1005 | cpp_error(pfile, "bad syntax for ?: operator"); | ||
1006 | goto syntax_error; | ||
1007 | } | ||
1008 | else | ||
1009 | { | ||
1010 | top--; | ||
1011 | if (top->value) | ||
1012 | skip_evaluation--; | ||
1013 | top->value = top->value ? v1 : v2; | ||
1014 | top->unsignedp = unsigned1 || unsigned2; | ||
1015 | } | ||
1016 | break; | ||
1017 | case ')': | ||
1018 | if ((top[1].flags & HAVE_VALUE) | ||
1019 | || !(top[0].flags & HAVE_VALUE) | ||
1020 | || top[0].op != '(' || (top[-1].flags & HAVE_VALUE)) | ||
1021 | { | ||
1022 | cpp_error(pfile, "mismatched parentheses in #if"); | ||
1023 | goto syntax_error; | ||
1024 | } | ||
1025 | else | ||
1026 | { | ||
1027 | top--; | ||
1028 | top->value = v1; | ||
1029 | top->unsignedp = unsigned1; | ||
1030 | top->flags |= HAVE_VALUE; | ||
1031 | } | ||
1032 | break; | ||
1033 | default: | ||
1034 | fprintf(stderr, | ||
1035 | top[1].op >= ' ' && top[1].op <= '~' | ||
1036 | ? "unimplemented operator '%c'\n" | ||
1037 | : "unimplemented operator '\\%03o'\n", top[1].op); | ||
1038 | } | ||
1039 | } | ||
1040 | if (op.op == 0) | ||
1041 | { | ||
1042 | if (top != stack) | ||
1043 | cpp_error(pfile, "internal error in #if expression"); | ||
1044 | if (stack != init_stack) | ||
1045 | free(stack); | ||
1046 | return top->value; | ||
1047 | } | ||
1048 | top++; | ||
1049 | |||
1050 | /* Check for and handle stack overflow. */ | ||
1051 | if (top == limit) | ||
1052 | { | ||
1053 | struct operation *new_stack; | ||
1054 | int old_size = (char *)limit - (char *)stack; | ||
1055 | int new_size = 2 * old_size; | ||
1056 | |||
1057 | if (stack != init_stack) | ||
1058 | new_stack = (struct operation *)xrealloc(stack, new_size); | ||
1059 | else | ||
1060 | { | ||
1061 | new_stack = (struct operation *)xmalloc(new_size); | ||
1062 | memcpy((char *)new_stack, (char *)stack, old_size); | ||
1063 | } | ||
1064 | stack = new_stack; | ||
1065 | top = (struct operation *)((char *)new_stack + old_size); | ||
1066 | limit = (struct operation *)((char *)new_stack + new_size); | ||
1067 | } | ||
1068 | top->flags = flags; | ||
1069 | top->rprio = rprio; | ||
1070 | top->op = op.op; | ||
1071 | if ((op.op == OROR && top[-1].value) | ||
1072 | || (op.op == ANDAND && !top[-1].value) | ||
1073 | || (op.op == '?' && !top[-1].value)) | ||
1074 | { | ||
1075 | skip_evaluation++; | ||
1076 | } | ||
1077 | else if (op.op == ':') | ||
1078 | { | ||
1079 | if (top[-2].value) /* Was condition true? */ | ||
1080 | skip_evaluation++; | ||
1081 | else | ||
1082 | skip_evaluation--; | ||
1083 | } | ||
1084 | } | ||
1085 | syntax_error: | ||
1086 | if (stack != init_stack) | ||
1087 | free(stack); | ||
1088 | skip_rest_of_line(pfile); | ||
1089 | return 0; | ||
1090 | } | ||
diff --git a/libraries/edje/src/bin/epp/cpphash.c b/libraries/edje/src/bin/epp/cpphash.c new file mode 100644 index 0000000..e3b68e0 --- /dev/null +++ b/libraries/edje/src/bin/epp/cpphash.c | |||
@@ -0,0 +1,198 @@ | |||
1 | /* Part of CPP library. (Macro hash table support.) | ||
2 | * Copyright (C) 1986, 87, 89, 92, 93, 94, 1995 Free Software Foundation, Inc. | ||
3 | * Written by Per Bothner, 1994. | ||
4 | * Based on CCCP program by by Paul Rubin, June 1986 | ||
5 | * Adapted to ANSI C, Richard Stallman, Jan 1987 | ||
6 | * Copyright (C) 2003-2011 Kim Woelders | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2, or (at your option) any | ||
11 | * later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | * | ||
22 | * In other words, you are welcome to use, share and improve this program. | ||
23 | * You are forbidden to forbid anyone else to use, share and improve | ||
24 | * what you give them. Help stamp out software-hoarding! */ | ||
25 | |||
26 | #ifdef HAVE_CONFIG_H | ||
27 | # include <config.h> | ||
28 | #endif | ||
29 | |||
30 | #include <string.h> | ||
31 | #include <stdlib.h> | ||
32 | |||
33 | #include "cpplib.h" | ||
34 | #include "cpphash.h" | ||
35 | |||
36 | static HASHNODE *hashtab[HASHSIZE]; | ||
37 | |||
38 | #define IS_IDCHAR(ch) is_idchar[(unsigned char)(ch)] | ||
39 | |||
40 | /* | ||
41 | * return hash function on name. must be compatible with the one | ||
42 | * computed a step at a time, elsewhere | ||
43 | */ | ||
44 | int | ||
45 | hashf(const char *name, int len, int hashsize) | ||
46 | { | ||
47 | int r = 0; | ||
48 | |||
49 | while (len--) | ||
50 | r = HASHSTEP(r, *name++); | ||
51 | |||
52 | return MAKE_POS(r) % hashsize; | ||
53 | } | ||
54 | |||
55 | /* | ||
56 | * find the most recent hash node for name name (ending with first | ||
57 | * non-identifier char) installed by install | ||
58 | * | ||
59 | * If LEN is >= 0, it is the length of the name. | ||
60 | * Otherwise, compute the length by scanning the entire name. | ||
61 | * | ||
62 | * If HASH is >= 0, it is the precomputed hash code. | ||
63 | * Otherwise, compute the hash code. | ||
64 | */ | ||
65 | HASHNODE * | ||
66 | cpp_lookup(const char *name, int len, int hash) | ||
67 | { | ||
68 | const char *bp; | ||
69 | HASHNODE *bucket; | ||
70 | |||
71 | if (len < 0) | ||
72 | { | ||
73 | for (bp = name; IS_IDCHAR(*bp); bp++) | ||
74 | ; | ||
75 | len = bp - name; | ||
76 | } | ||
77 | if (hash < 0) | ||
78 | hash = hashf(name, len, HASHSIZE); | ||
79 | |||
80 | bucket = hashtab[hash]; | ||
81 | while (bucket) | ||
82 | { | ||
83 | if (bucket->length == len | ||
84 | && strncmp((const char *)bucket->name, name, len) == 0) | ||
85 | return bucket; | ||
86 | bucket = bucket->next; | ||
87 | } | ||
88 | return (HASHNODE *) 0; | ||
89 | } | ||
90 | |||
91 | /* | ||
92 | * Delete a hash node. Some weirdness to free junk from macros. | ||
93 | * More such weirdness will have to be added if you define more hash | ||
94 | * types that need it. | ||
95 | */ | ||
96 | |||
97 | /* Note that the DEFINITION of a macro is removed from the hash table | ||
98 | * but its storage is not freed. This would be a storage leak | ||
99 | * except that it is not reasonable to keep undefining and redefining | ||
100 | * large numbers of macros many times. | ||
101 | * In any case, this is necessary, because a macro can be #undef'd | ||
102 | * in the middle of reading the arguments to a call to it. | ||
103 | * If #undef freed the DEFINITION, that would crash. */ | ||
104 | |||
105 | void | ||
106 | delete_macro(HASHNODE * hp) | ||
107 | { | ||
108 | |||
109 | if (hp->prev) | ||
110 | hp->prev->next = hp->next; | ||
111 | if (hp->next) | ||
112 | hp->next->prev = hp->prev; | ||
113 | |||
114 | /* make sure that the bucket chain header that | ||
115 | * the deleted guy was on points to the right thing afterwards. */ | ||
116 | if (hp == *hp->bucket_hdr) | ||
117 | *hp->bucket_hdr = hp->next; | ||
118 | |||
119 | if (hp->type == T_MACRO) | ||
120 | { | ||
121 | DEFINITION *d = hp->value.defn; | ||
122 | struct reflist *ap, *nextap; | ||
123 | |||
124 | for (ap = d->pattern; ap; ap = nextap) | ||
125 | { | ||
126 | nextap = ap->next; | ||
127 | free(ap); | ||
128 | } | ||
129 | if (d->nargs >= 0) | ||
130 | free(d->args.argnames); | ||
131 | free(d); | ||
132 | } | ||
133 | free(hp); | ||
134 | } | ||
135 | /* | ||
136 | * install a name in the main hash table, even if it is already there. | ||
137 | * name stops with first non alphanumeric, except leading '#'. | ||
138 | * caller must check against redefinition if that is desired. | ||
139 | * delete_macro () removes things installed by install () in fifo order. | ||
140 | * this is important because of the `defined' special symbol used | ||
141 | * in #if, and also if pushdef/popdef directives are ever implemented. | ||
142 | * | ||
143 | * If LEN is >= 0, it is the length of the name. | ||
144 | * Otherwise, compute the length by scanning the entire name. | ||
145 | * | ||
146 | * If HASH is >= 0, it is the precomputed hash code. | ||
147 | * Otherwise, compute the hash code. | ||
148 | */ | ||
149 | HASHNODE * | ||
150 | install(const char *name, int len, enum node_type type, int ivalue, char *value, | ||
151 | int hash) | ||
152 | { | ||
153 | HASHNODE *hp; | ||
154 | int i, bucket; | ||
155 | const char *p; | ||
156 | |||
157 | if (len < 0) | ||
158 | { | ||
159 | p = name; | ||
160 | while (IS_IDCHAR(*p)) | ||
161 | p++; | ||
162 | len = p - name; | ||
163 | } | ||
164 | if (hash < 0) | ||
165 | hash = hashf(name, len, HASHSIZE); | ||
166 | |||
167 | i = sizeof(HASHNODE) + len + 1; | ||
168 | hp = (HASHNODE *) xmalloc(i); | ||
169 | bucket = hash; | ||
170 | hp->bucket_hdr = &hashtab[bucket]; | ||
171 | hp->next = hashtab[bucket]; | ||
172 | hashtab[bucket] = hp; | ||
173 | hp->prev = NULL; | ||
174 | if (hp->next) | ||
175 | hp->next->prev = hp; | ||
176 | hp->type = type; | ||
177 | hp->length = len; | ||
178 | if (hp->type == T_CONST) | ||
179 | hp->value.ival = ivalue; | ||
180 | else | ||
181 | hp->value.cpval = value; | ||
182 | hp->name = ((char *)hp) + sizeof(HASHNODE); | ||
183 | memcpy(hp->name, name, len); | ||
184 | hp->name[len] = 0; | ||
185 | return hp; | ||
186 | } | ||
187 | |||
188 | void | ||
189 | cpp_hash_cleanup(cpp_reader * pfile __UNUSED__) | ||
190 | { | ||
191 | int i; | ||
192 | |||
193 | for (i = HASHSIZE; --i >= 0;) | ||
194 | { | ||
195 | while (hashtab[i]) | ||
196 | delete_macro(hashtab[i]); | ||
197 | } | ||
198 | } | ||
diff --git a/libraries/edje/src/bin/epp/cpphash.h b/libraries/edje/src/bin/epp/cpphash.h new file mode 100644 index 0000000..524a850 --- /dev/null +++ b/libraries/edje/src/bin/epp/cpphash.h | |||
@@ -0,0 +1,41 @@ | |||
1 | enum node_type; | ||
2 | |||
3 | /* different kinds of things that can appear in the value field | ||
4 | of a hash node. Actually, this may be useless now. */ | ||
5 | union hashval { | ||
6 | int ival; | ||
7 | char *cpval; | ||
8 | DEFINITION *defn; | ||
9 | }; | ||
10 | |||
11 | struct hashnode { | ||
12 | struct hashnode *next; /* double links for easy deletion */ | ||
13 | struct hashnode *prev; | ||
14 | struct hashnode **bucket_hdr; /* also, a back pointer to this node's hash | ||
15 | * chain is kept, in case the node is the head | ||
16 | * of the chain and gets deleted. */ | ||
17 | enum node_type type; /* type of special token */ | ||
18 | int length; /* length of token, for quick comparison */ | ||
19 | char *name; /* the actual name */ | ||
20 | union hashval value; /* pointer to expansion, or whatever */ | ||
21 | }; | ||
22 | |||
23 | typedef struct hashnode HASHNODE; | ||
24 | |||
25 | /* Some definitions for the hash table. The hash function MUST be | ||
26 | computed as shown in hashf () below. That is because the rescan | ||
27 | loop computes the hash value `on the fly' for most tokens, | ||
28 | in order to avoid the overhead of a lot of procedure calls to | ||
29 | the hashf () function. Hashf () only exists for the sake of | ||
30 | politeness, for use when speed isn't so important. */ | ||
31 | |||
32 | #define HASHSIZE 1403 | ||
33 | #define HASHSTEP(old, c) ((old << 2) + c) | ||
34 | #define MAKE_POS(v) (v & 0x7fffffff) /* make number positive */ | ||
35 | |||
36 | extern int hashf(const char *name, int len, int hashsize); | ||
37 | extern HASHNODE *cpp_lookup(const char *name, int len, int hash); | ||
38 | extern void delete_macro(HASHNODE * hp); | ||
39 | extern HASHNODE *install(const char *name, int len, enum node_type type, | ||
40 | int ivalue, char *value, int hash); | ||
41 | extern void cpp_hash_cleanup(cpp_reader * pfile); | ||
diff --git a/libraries/edje/src/bin/epp/cpplib.c b/libraries/edje/src/bin/epp/cpplib.c new file mode 100644 index 0000000..132d2a9 --- /dev/null +++ b/libraries/edje/src/bin/epp/cpplib.c | |||
@@ -0,0 +1,7427 @@ | |||
1 | /* CPP Library. | ||
2 | * Copyright (C) 1986, 87, 89, 92, 93, 94, 1995 Free Software Foundation, Inc. | ||
3 | * Written by Per Bothner, 1994-95. | ||
4 | * Based on CCCP program by by Paul Rubin, June 1986 | ||
5 | * Adapted to ANSI C, Richard Stallman, Jan 1987 | ||
6 | * Copyright (C) 2003-2011 Kim Woelders | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2, or (at your option) any | ||
11 | * later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | * | ||
22 | * In other words, you are welcome to use, share and improve this program. | ||
23 | * You are forbidden to forbid anyone else to use, share and improve | ||
24 | * what you give them. Help stamp out software-hoarding! */ | ||
25 | |||
26 | #ifdef HAVE_CONFIG_H | ||
27 | # include <config.h> | ||
28 | #endif | ||
29 | |||
30 | #ifdef HAVE_ALLOCA_H | ||
31 | # include <alloca.h> | ||
32 | #elif defined __GNUC__ | ||
33 | # define alloca __builtin_alloca | ||
34 | #elif defined _AIX | ||
35 | # define alloca __alloca | ||
36 | #elif defined _MSC_VER | ||
37 | # include <malloc.h> | ||
38 | # define alloca _alloca | ||
39 | #else | ||
40 | # include <stddef.h> | ||
41 | void *alloca (size_t); | ||
42 | #endif | ||
43 | |||
44 | #ifdef __EMX__ | ||
45 | #include <strings.h> | ||
46 | #endif | ||
47 | |||
48 | #ifndef STANDARD_INCLUDE_DIR | ||
49 | #define STANDARD_INCLUDE_DIR "/usr/include" | ||
50 | #endif | ||
51 | |||
52 | #ifndef LOCAL_INCLUDE_DIR | ||
53 | #define LOCAL_INCLUDE_DIR "/usr/local/include" | ||
54 | #endif | ||
55 | |||
56 | #include "cpplib.h" | ||
57 | #include "cpphash.h" | ||
58 | |||
59 | /* | ||
60 | * On Windows, if the file is not opened in binary mode, | ||
61 | * read does not return the correct size, because of | ||
62 | * CR / LF translation. | ||
63 | */ | ||
64 | #ifndef O_BINARY | ||
65 | # define O_BINARY 0 | ||
66 | #endif | ||
67 | |||
68 | const char *version_string = "0.0.0"; | ||
69 | |||
70 | #ifndef STDC_VALUE | ||
71 | #define STDC_VALUE 1 | ||
72 | #endif | ||
73 | |||
74 | /* By default, colon separates directories in a path. */ | ||
75 | #ifndef PATH_SEPARATOR | ||
76 | #define PATH_SEPARATOR ':' | ||
77 | #endif | ||
78 | |||
79 | #include <ctype.h> | ||
80 | #include <stdio.h> | ||
81 | #include <string.h> | ||
82 | #include <signal.h> | ||
83 | #include <stdlib.h> | ||
84 | #include <unistd.h> | ||
85 | #include <sys/types.h> | ||
86 | #include <sys/stat.h> | ||
87 | #include <fcntl.h> | ||
88 | #include <stdlib.h> | ||
89 | |||
90 | #ifndef VMS | ||
91 | #ifndef USG | ||
92 | #include <time.h> | ||
93 | #include <sys/time.h> /* for __DATE__ and __TIME__ */ | ||
94 | #ifdef HAVE_SYS_RESOURCE_H | ||
95 | # include <sys/resource.h> | ||
96 | #endif | ||
97 | #else | ||
98 | #include <sys/param.h> /* CYGNUS LOCAL: shebs -noquiet */ | ||
99 | #include <sys/times.h> | ||
100 | #include <time.h> | ||
101 | #include <fcntl.h> | ||
102 | #endif /* USG */ | ||
103 | #endif /* not VMS */ | ||
104 | |||
105 | /* This defines "errno" properly for VMS, and gives us EACCES. */ | ||
106 | #include <errno.h> | ||
107 | |||
108 | #ifndef O_RDONLY | ||
109 | #define O_RDONLY 0 | ||
110 | #endif | ||
111 | |||
112 | #undef MIN | ||
113 | #undef MAX | ||
114 | #define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) | ||
115 | #define MAX(X,Y) ((X) > (Y) ? (X) : (Y)) | ||
116 | |||
117 | #ifndef S_ISREG | ||
118 | #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) | ||
119 | #endif | ||
120 | |||
121 | #ifndef S_ISDIR | ||
122 | #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) | ||
123 | #endif | ||
124 | |||
125 | /* Define a generic NULL if one hasn't already been defined. */ | ||
126 | |||
127 | #ifndef GENERIC_PTR | ||
128 | #if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) | ||
129 | #define GENERIC_PTR void * | ||
130 | #else | ||
131 | #define GENERIC_PTR char * | ||
132 | #endif | ||
133 | #endif | ||
134 | |||
135 | #ifndef INCLUDE_LEN_FUDGE | ||
136 | #define INCLUDE_LEN_FUDGE 0 | ||
137 | #endif | ||
138 | |||
139 | #define USE_FILE_NAME_MAPS 0 | ||
140 | |||
141 | /* Symbols to predefine. */ | ||
142 | |||
143 | #ifdef CPP_PREDEFINES | ||
144 | static const char *predefs = CPP_PREDEFINES; | ||
145 | |||
146 | #else | ||
147 | static const char *predefs = ""; | ||
148 | |||
149 | #endif | ||
150 | |||
151 | /* We let tm.h override the types used here, to handle trivial differences | ||
152 | * such as the choice of unsigned int or long unsigned int for size_t. | ||
153 | * When machines start needing nontrivial differences in the size type, | ||
154 | * it would be best to do something here to figure out automatically | ||
155 | * from other information what type to use. */ | ||
156 | |||
157 | /* The string value for __SIZE_TYPE__. */ | ||
158 | |||
159 | #ifndef SIZE_TYPE | ||
160 | #define SIZE_TYPE "long unsigned int" | ||
161 | #endif | ||
162 | |||
163 | /* The string value for __PTRDIFF_TYPE__. */ | ||
164 | |||
165 | #ifndef PTRDIFF_TYPE | ||
166 | #define PTRDIFF_TYPE "long int" | ||
167 | #endif | ||
168 | |||
169 | /* The string value for __WCHAR_TYPE__. */ | ||
170 | |||
171 | #ifndef WCHAR_TYPE | ||
172 | #define WCHAR_TYPE "int" | ||
173 | #endif | ||
174 | #define CPP_WCHAR_TYPE(PFILE) \ | ||
175 | (CPP_OPTIONS (PFILE)->cplusplus ? "__wchar_t" : WCHAR_TYPE) | ||
176 | |||
177 | /* The string value for __USER_LABEL_PREFIX__ */ | ||
178 | |||
179 | #ifndef USER_LABEL_PREFIX | ||
180 | #define USER_LABEL_PREFIX "" | ||
181 | #endif | ||
182 | |||
183 | /* The string value for __REGISTER_PREFIX__ */ | ||
184 | |||
185 | #ifndef REGISTER_PREFIX | ||
186 | #define REGISTER_PREFIX "" | ||
187 | #endif | ||
188 | |||
189 | struct directive { | ||
190 | int length; | ||
191 | int (*func) (cpp_reader * pfile, struct directive * keyword, | ||
192 | unsigned char *buf, unsigned char *limit); | ||
193 | const char *name; | ||
194 | enum node_type type; | ||
195 | char command_reads_line; | ||
196 | char traditional_comments; | ||
197 | char pass_thru; | ||
198 | }; | ||
199 | |||
200 | /* In the definition of a #assert name, this structure forms | ||
201 | * a list of the individual values asserted. | ||
202 | * Each value is itself a list of "tokens". | ||
203 | * These are strings that are compared by name. */ | ||
204 | |||
205 | struct tokenlist_list { | ||
206 | struct tokenlist_list *next; | ||
207 | struct arglist *tokens; | ||
208 | }; | ||
209 | |||
210 | struct assertion_hashnode { | ||
211 | struct assertion_hashnode *next; /* double links for easy deletion */ | ||
212 | struct assertion_hashnode *prev; | ||
213 | /* also, a back pointer to this node's hash | ||
214 | * chain is kept, in case the node is the head | ||
215 | * of the chain and gets deleted. */ | ||
216 | struct assertion_hashnode **bucket_hdr; | ||
217 | int length; /* length of token, for quick comparison */ | ||
218 | char *name; /* the actual name */ | ||
219 | /* List of token-sequences. */ | ||
220 | struct tokenlist_list *value; | ||
221 | }; | ||
222 | |||
223 | #define SKIP_WHITE_SPACE(p) do { while (is_hor_space[(unsigned char)(*p)]) p++; } while (0) | ||
224 | #define SKIP_ALL_WHITE_SPACE(p) do { while (is_space[(unsigned char)(*p)]) p++; } while (0) | ||
225 | |||
226 | #define PEEKN(N) (CPP_BUFFER (pfile)->rlimit - CPP_BUFFER (pfile)->cur >= (N) ? CPP_BUFFER (pfile)->cur[N] : EOF) | ||
227 | #define FORWARD(N) CPP_FORWARD (CPP_BUFFER (pfile), (N)) | ||
228 | #define GETC() CPP_BUF_GET (CPP_BUFFER (pfile)) | ||
229 | #define PEEKC() CPP_BUF_PEEK (CPP_BUFFER (pfile)) | ||
230 | /* CPP_IS_MACRO_BUFFER is true if the buffer contains macro expansion. | ||
231 | * (Note that it is false while we're expanding marco *arguments*.) */ | ||
232 | #define CPP_IS_MACRO_BUFFER(PBUF) ((PBUF)->cleanup == macro_cleanup) | ||
233 | |||
234 | /* Move all backslash-newline pairs out of embarrassing places. | ||
235 | * Exchange all such pairs following BP | ||
236 | * with any potentially-embarrassing characters that follow them. | ||
237 | * Potentially-embarrassing characters are / and * | ||
238 | * (because a backslash-newline inside a comment delimiter | ||
239 | * would cause it not to be recognized). */ | ||
240 | |||
241 | #define NEWLINE_FIX \ | ||
242 | do {while (PEEKC() == '\\' && PEEKN(1) == '\n') FORWARD(2); } while(0) | ||
243 | |||
244 | /* Same, but assume we've already read the potential '\\' into C. */ | ||
245 | #define NEWLINE_FIX1(C) do { \ | ||
246 | while ((C) == '\\' && PEEKC() == '\n') { FORWARD(1); (C) = GETC(); }\ | ||
247 | } while(0) | ||
248 | |||
249 | /* Name under which this program was invoked. */ | ||
250 | |||
251 | char *progname; | ||
252 | |||
253 | struct cpp_pending { | ||
254 | struct cpp_pending *next; | ||
255 | const char *cmd; | ||
256 | const char *arg; | ||
257 | }; | ||
258 | |||
259 | /* Structure returned by create_definition */ | ||
260 | typedef struct { | ||
261 | struct definition *defn; | ||
262 | char *symnam; | ||
263 | int symlen; | ||
264 | } MACRODEF; | ||
265 | |||
266 | /* Forward declarations. */ | ||
267 | typedef struct file_name_list file_name_list; | ||
268 | |||
269 | static void add_import(cpp_reader * pfile, int fd, char *fname); | ||
270 | static int finclude(cpp_reader * pfile, int f, const char *fname, | ||
271 | int system_header_p, file_name_list * dirptr); | ||
272 | static void validate_else(cpp_reader * pfile, const char *directive); | ||
273 | static int comp_def_part(int first, unsigned char *beg1, int len1, | ||
274 | unsigned char *beg2, int len2, int last); | ||
275 | static int lookup_import(cpp_reader * pfile, char *filename, | ||
276 | file_name_list * searchptr); | ||
277 | static int redundant_include_p(cpp_reader * pfile, char *name); | ||
278 | |||
279 | static int is_system_include(cpp_reader * pfile, char *filename); | ||
280 | |||
281 | static int open_include_file(cpp_reader * pfile, char *filename, | ||
282 | file_name_list * searchptr); | ||
283 | static int check_macro_name(cpp_reader * pfile, unsigned char *symname, | ||
284 | const char *usage); | ||
285 | |||
286 | static int compare_token_lists(struct arglist *l1, struct arglist *l2); | ||
287 | static HOST_WIDE_INT eval_if_expression(cpp_reader * pfile, unsigned char *buf, | ||
288 | int length); | ||
289 | |||
290 | static int file_size_and_mode(int fd, int *mode_pointer, | ||
291 | long int *size_pointer); | ||
292 | static struct arglist *read_token_list(cpp_reader * pfile, int *error_flag); | ||
293 | static void free_token_list(struct arglist *tokens); | ||
294 | static int safe_read(int desc, char *ptr, int len); | ||
295 | static void push_macro_expansion(cpp_reader * pfile, | ||
296 | unsigned char *x, | ||
297 | int xbuf_len, HASHNODE * hp); | ||
298 | |||
299 | static struct cpp_pending *nreverse_pending(struct cpp_pending *list); | ||
300 | static char *savestring(const char *input); | ||
301 | |||
302 | static void conditional_skip(cpp_reader * pfile, int skip, | ||
303 | enum node_type type, | ||
304 | unsigned char *control_macro); | ||
305 | static void skip_if_group(cpp_reader * pfile, int any); | ||
306 | |||
307 | static void cpp_error_with_line(cpp_reader * pfile, int line, | ||
308 | int column, const char *msg); | ||
309 | static void cpp_pedwarn_with_line(cpp_reader * pfile, int line, | ||
310 | int column, const char *msg); | ||
311 | static void cpp_pedwarn_with_file_and_line(cpp_reader * pfile, | ||
312 | const char *file, int line, | ||
313 | const char *msg, | ||
314 | const char *arg1, | ||
315 | const char *arg2, | ||
316 | const char *arg3); | ||
317 | static void cpp_error_from_errno(cpp_reader * pfile, const char *name); | ||
318 | |||
319 | static cpp_buffer *cpp_push_buffer(cpp_reader * pfile, unsigned char *buffer, | ||
320 | long length); | ||
321 | static cpp_buffer *cpp_pop_buffer(cpp_reader * pfile); | ||
322 | |||
323 | /* Last arg to output_line_command. */ | ||
324 | enum file_change_code { | ||
325 | same_file, enter_file, leave_file | ||
326 | }; | ||
327 | |||
328 | /* These functions are declared to return int instead of void since they | ||
329 | * are going to be placed in a table and some old compilers have trouble with | ||
330 | * pointers to functions returning void. */ | ||
331 | |||
332 | static int do_define(cpp_reader * pfile, struct directive *keyword, | ||
333 | unsigned char *buf, unsigned char *limit); | ||
334 | |||
335 | static int do_line(cpp_reader * pfile, struct directive *keyword, | ||
336 | unsigned char *unused1, unsigned char *unused2); | ||
337 | |||
338 | static int do_include(cpp_reader * pfile, struct directive *keyword, | ||
339 | unsigned char *unused1, unsigned char *unused2); | ||
340 | |||
341 | static int do_undef(cpp_reader * pfile, struct directive *keyword, | ||
342 | unsigned char *buf, unsigned char *limit); | ||
343 | |||
344 | static int do_error(cpp_reader * pfile, struct directive *keyword, | ||
345 | unsigned char *buf, unsigned char *limit); | ||
346 | |||
347 | static int do_pragma(cpp_reader * pfile, struct directive *keyword, | ||
348 | unsigned char *buf, unsigned char *limit); | ||
349 | |||
350 | static int do_ident(cpp_reader * pfile, struct directive *keyword, | ||
351 | unsigned char *buf, unsigned char *limit); | ||
352 | |||
353 | static int do_if(cpp_reader * pfile, struct directive *keyword, | ||
354 | unsigned char *buf, unsigned char *limit); | ||
355 | |||
356 | static int do_xifdef(cpp_reader * pfile, struct directive *keyword, | ||
357 | unsigned char *buf, unsigned char *limit); | ||
358 | |||
359 | static int do_else(cpp_reader * pfile, struct directive *keyword, | ||
360 | unsigned char *buf, unsigned char *limit); | ||
361 | |||
362 | static int do_elif(cpp_reader * pfile, struct directive *keyword, | ||
363 | unsigned char *buf, unsigned char *limit); | ||
364 | |||
365 | static int do_endif(cpp_reader * pfile, struct directive *keyword, | ||
366 | unsigned char *buf, unsigned char *limit); | ||
367 | |||
368 | static int do_assert(cpp_reader * pfile, struct directive *keyword, | ||
369 | unsigned char *buf, unsigned char *limit); | ||
370 | |||
371 | static int do_unassert(cpp_reader * pfile, struct directive *keyword, | ||
372 | unsigned char *buf, unsigned char *limit); | ||
373 | |||
374 | static int do_warning(cpp_reader * pfile, struct directive *keyword, | ||
375 | unsigned char *buf, unsigned char *limit); | ||
376 | |||
377 | struct arglist *reverse_token_list(struct arglist *tokens); | ||
378 | |||
379 | static int parse_name(cpp_reader * pfile, int c); | ||
380 | |||
381 | static void parse_set_mark(struct parse_marker *pmark, | ||
382 | cpp_reader * pfile); | ||
383 | static void parse_clear_mark(struct parse_marker *pmark); | ||
384 | static void parse_goto_mark(struct parse_marker *pmark, | ||
385 | cpp_reader * pfile); | ||
386 | static void parse_move_mark(struct parse_marker *pmark, | ||
387 | cpp_reader * pfile); | ||
388 | |||
389 | struct file_name_list { | ||
390 | file_name_list *next; | ||
391 | char *fname; | ||
392 | /* If the following is nonzero, it is a macro name. | ||
393 | * Don't include the file again if that macro is defined. */ | ||
394 | unsigned char *control_macro; | ||
395 | /* If the following is nonzero, it is a C-language system include | ||
396 | * directory. */ | ||
397 | int c_system_include_path; | ||
398 | /* Mapping of file names for this directory. */ | ||
399 | struct file_name_map *name_map; | ||
400 | /* Non-zero if name_map is valid. */ | ||
401 | int got_name_map; | ||
402 | }; | ||
403 | |||
404 | /* If a buffer's dir field is SELF_DIR_DUMMY, it means the file was found | ||
405 | * via the same directory as the file that #included it. */ | ||
406 | #define SELF_DIR_DUMMY ((file_name_list*)(~0)) | ||
407 | |||
408 | /* #include "file" looks in source file dir, then stack. */ | ||
409 | /* #include <file> just looks in the stack. */ | ||
410 | /* -I directories are added to the end, then the defaults are added. */ | ||
411 | /* The */ | ||
412 | static struct default_include { | ||
413 | const char *fname; /* The name of the directory. */ | ||
414 | int cplusplus; /* Only look here if we're compiling C++. */ | ||
415 | int cxx_aware; /* Includes in this directory don't need to | ||
416 | * be wrapped in extern "C" when compiling | ||
417 | * C++. */ | ||
418 | } include_defaults_array[] | ||
419 | #ifdef INCLUDE_DEFAULTS | ||
420 | = INCLUDE_DEFAULTS; | ||
421 | |||
422 | #else | ||
423 | = | ||
424 | { | ||
425 | /* Pick up GNU C++ specific include files. */ | ||
426 | { | ||
427 | GPLUSPLUS_INCLUDE_DIR, 1, 1} | ||
428 | , | ||
429 | #ifdef CROSS_COMPILE | ||
430 | /* This is the dir for fixincludes. Put it just before | ||
431 | * the files that we fix. */ | ||
432 | { | ||
433 | GCC_INCLUDE_DIR, 0, 0} | ||
434 | , | ||
435 | /* For cross-compilation, this dir name is generated | ||
436 | * automatically in Makefile.in. */ | ||
437 | { | ||
438 | CROSS_INCLUDE_DIR, 0, 0} | ||
439 | , | ||
440 | /* This is another place that the target system's headers might be. */ | ||
441 | { | ||
442 | TOOL_INCLUDE_DIR, 0, 1} | ||
443 | , | ||
444 | #else /* not CROSS_COMPILE */ | ||
445 | /* This should be /usr/local/include and should come before | ||
446 | * the fixincludes-fixed header files. */ | ||
447 | { | ||
448 | LOCAL_INCLUDE_DIR, 0, 1} | ||
449 | , | ||
450 | /* This is here ahead of GCC_INCLUDE_DIR because assert.h goes here. | ||
451 | * Likewise, behind LOCAL_INCLUDE_DIR, where glibc puts its assert.h. */ | ||
452 | { | ||
453 | TOOL_INCLUDE_DIR, 0, 1} | ||
454 | , | ||
455 | /* This is the dir for fixincludes. Put it just before | ||
456 | * the files that we fix. */ | ||
457 | { | ||
458 | GCC_INCLUDE_DIR, 0, 0} | ||
459 | , | ||
460 | /* Some systems have an extra dir of include files. */ | ||
461 | #ifdef SYSTEM_INCLUDE_DIR | ||
462 | { | ||
463 | SYSTEM_INCLUDE_DIR, 0, 0} | ||
464 | , | ||
465 | #endif | ||
466 | { | ||
467 | STANDARD_INCLUDE_DIR, 0, 0} | ||
468 | , | ||
469 | #endif /* not CROSS_COMPILE */ | ||
470 | { | ||
471 | 0, 0, 0} | ||
472 | }; | ||
473 | |||
474 | #endif /* no INCLUDE_DEFAULTS */ | ||
475 | |||
476 | /* Here is the actual list of #-directives, most-often-used first. | ||
477 | * The initialize_builtins function assumes #define is the very first. */ | ||
478 | |||
479 | static struct directive directive_table[] = { | ||
480 | {6, do_define, "define", T_DEFINE, 0, 1, 0}, | ||
481 | {5, do_xifdef, "ifdef", T_IFDEF, 1, 0, 0}, | ||
482 | {6, do_xifdef, "ifndef", T_IFNDEF, 1, 0, 0}, | ||
483 | {7, do_include, "include", T_INCLUDE, 1, 0, 0}, | ||
484 | {12, do_include, "include_next", T_INCLUDE_NEXT, 1, 0, 0}, | ||
485 | {6, do_include, "import", T_IMPORT, 1, 0, 0}, | ||
486 | {5, do_endif, "endif", T_ENDIF, 1, 0, 0}, | ||
487 | {4, do_else, "else", T_ELSE, 1, 0, 0}, | ||
488 | {2, do_if, "if", T_IF, 1, 0, 0}, | ||
489 | {4, do_elif, "elif", T_ELIF, 1, 0, 0}, | ||
490 | {5, do_undef, "undef", T_UNDEF, 0, 0, 0}, | ||
491 | {5, do_error, "error", T_ERROR, 0, 0, 0}, | ||
492 | {7, do_warning, "warning", T_WARNING, 0, 0, 0}, | ||
493 | {6, do_pragma, "pragma", T_PRAGMA, 0, 0, 1}, | ||
494 | {4, do_line, "line", T_LINE, 1, 0, 0}, | ||
495 | {5, do_ident, "ident", T_IDENT, 1, 0, 1}, | ||
496 | #ifdef SCCS_DIRECTIVE | ||
497 | {4, do_sccs, "sccs", T_SCCS, 0, 0, 0}, | ||
498 | #endif | ||
499 | {6, do_assert, "assert", T_ASSERT, 1, 0, 0}, | ||
500 | {8, do_unassert, "unassert", T_UNASSERT, 1, 0, 0}, | ||
501 | {-1, 0, "", T_UNUSED, 0, 0, 0}, | ||
502 | }; | ||
503 | |||
504 | /* table to tell if char can be part of a C identifier. */ | ||
505 | unsigned char is_idchar[256]; | ||
506 | |||
507 | /* table to tell if char can be first char of a c identifier. */ | ||
508 | unsigned char is_idstart[256]; | ||
509 | |||
510 | /* table to tell if c is horizontal space. */ | ||
511 | unsigned char is_hor_space[256]; | ||
512 | |||
513 | /* table to tell if c is horizontal or vertical space. */ | ||
514 | static unsigned char is_space[256]; | ||
515 | |||
516 | /* Initialize syntactic classifications of characters. */ | ||
517 | |||
518 | static void | ||
519 | initialize_char_syntax(struct cpp_options *opts) | ||
520 | { | ||
521 | int i; | ||
522 | |||
523 | /* | ||
524 | * Set up is_idchar and is_idstart tables. These should be | ||
525 | * faster than saying (is_alpha (c) || c == '_'), etc. | ||
526 | * Set up these things before calling any routines tthat | ||
527 | * refer to them. | ||
528 | */ | ||
529 | for (i = 'a'; i <= 'z'; i++) | ||
530 | { | ||
531 | is_idchar[i - 'a' + 'A'] = 1; | ||
532 | is_idchar[i] = 1; | ||
533 | is_idstart[i - 'a' + 'A'] = 1; | ||
534 | is_idstart[i] = 1; | ||
535 | } | ||
536 | for (i = '0'; i <= '9'; i++) | ||
537 | is_idchar[i] = 1; | ||
538 | is_idchar[(unsigned char)'_'] = 1; | ||
539 | is_idstart[(unsigned char)'_'] = 1; | ||
540 | is_idchar[(unsigned char)'$'] = opts->dollars_in_ident; | ||
541 | is_idstart[(unsigned char)'$'] = opts->dollars_in_ident; | ||
542 | |||
543 | /* horizontal space table */ | ||
544 | is_hor_space[(unsigned char)' '] = 1; | ||
545 | is_hor_space[(unsigned char)'\t'] = 1; | ||
546 | is_hor_space[(unsigned char)'\v'] = 1; | ||
547 | is_hor_space[(unsigned char)'\f'] = 1; | ||
548 | is_hor_space[(unsigned char)'\r'] = 1; | ||
549 | |||
550 | is_space[(unsigned char)' '] = 1; | ||
551 | is_space[(unsigned char)'\t'] = 1; | ||
552 | is_space[(unsigned char)'\v'] = 1; | ||
553 | is_space[(unsigned char)'\f'] = 1; | ||
554 | is_space[(unsigned char)'\n'] = 1; | ||
555 | is_space[(unsigned char)'\r'] = 1; | ||
556 | } | ||
557 | |||
558 | /* Place into PFILE a quoted string representing the string SRC. | ||
559 | * Caller must reserve enough space in pfile->token_buffer. */ | ||
560 | static void | ||
561 | quote_string(cpp_reader * pfile, const char *src) | ||
562 | { | ||
563 | unsigned char c; | ||
564 | |||
565 | CPP_PUTC_Q(pfile, '\"'); | ||
566 | for (;;) | ||
567 | switch ((c = *src++)) | ||
568 | { | ||
569 | default: | ||
570 | if (isprint(c)) | ||
571 | CPP_PUTC_Q(pfile, c); | ||
572 | else | ||
573 | { | ||
574 | sprintf((char *)CPP_PWRITTEN(pfile), "\\%03o", c); | ||
575 | CPP_ADJUST_WRITTEN(pfile, 4); | ||
576 | } | ||
577 | break; | ||
578 | |||
579 | case '\"': | ||
580 | case '\\': | ||
581 | CPP_PUTC_Q(pfile, '\\'); | ||
582 | CPP_PUTC_Q(pfile, c); | ||
583 | break; | ||
584 | |||
585 | case '\0': | ||
586 | CPP_PUTC_Q(pfile, '\"'); | ||
587 | CPP_NUL_TERMINATE_Q(pfile); | ||
588 | return; | ||
589 | } | ||
590 | } | ||
591 | |||
592 | /* Make sure PFILE->token_buffer will hold at least N more chars. */ | ||
593 | |||
594 | void | ||
595 | cpp_grow_buffer(cpp_reader * pfile, long n) | ||
596 | { | ||
597 | long old_written = CPP_WRITTEN(pfile); | ||
598 | |||
599 | pfile->token_buffer_size = n + 2 * pfile->token_buffer_size; | ||
600 | pfile->token_buffer = | ||
601 | (unsigned char *)xrealloc(pfile->token_buffer, pfile->token_buffer_size); | ||
602 | CPP_SET_WRITTEN(pfile, old_written); | ||
603 | } | ||
604 | |||
605 | /* | ||
606 | * process a given definition string, for initialization | ||
607 | * If STR is just an identifier, define it with value 1. | ||
608 | * If STR has anything after the identifier, then it should | ||
609 | * be identifier=definition. | ||
610 | */ | ||
611 | |||
612 | void | ||
613 | cpp_define(cpp_reader * pfile, unsigned char *str) | ||
614 | { | ||
615 | unsigned char *buf, *p; | ||
616 | |||
617 | buf = str; | ||
618 | p = str; | ||
619 | if (!is_idstart[*p]) | ||
620 | { | ||
621 | cpp_error(pfile, "malformed option `-D %s'", str); | ||
622 | return; | ||
623 | } | ||
624 | while (is_idchar[*++p]) | ||
625 | ; | ||
626 | if (*p == 0) | ||
627 | { | ||
628 | buf = (unsigned char *)alloca(p - buf + 4); | ||
629 | strcpy((char *)buf, (const char *)str); | ||
630 | strcat((char *)buf, " 1"); | ||
631 | } | ||
632 | else if (*p != '=') | ||
633 | { | ||
634 | cpp_error(pfile, "malformed option `-D %s'", str); | ||
635 | return; | ||
636 | } | ||
637 | else | ||
638 | { | ||
639 | unsigned char *q; | ||
640 | |||
641 | /* Copy the entire option so we can modify it. */ | ||
642 | buf = (unsigned char *)alloca(2 * strlen((char *)str) + 1); | ||
643 | strncpy((char *)buf, (const char *)str, p - str); | ||
644 | /* Change the = to a space. */ | ||
645 | buf[p - str] = ' '; | ||
646 | /* Scan for any backslash-newline and remove it. */ | ||
647 | p++; | ||
648 | q = &buf[p - str]; | ||
649 | while (*p) | ||
650 | { | ||
651 | if (*p == '\\' && p[1] == '\n') | ||
652 | p += 2; | ||
653 | else | ||
654 | *q++ = *p++; | ||
655 | } | ||
656 | *q = 0; | ||
657 | } | ||
658 | |||
659 | do_define(pfile, NULL, buf, buf + strlen((char *)buf)); | ||
660 | } | ||
661 | |||
662 | /* Process the string STR as if it appeared as the body of a #assert. | ||
663 | * OPTION is the option name for which STR was the argument. */ | ||
664 | |||
665 | static void | ||
666 | make_assertion(cpp_reader * pfile, const char *option, const char *str) | ||
667 | { | ||
668 | unsigned char *buf, *p, *q; | ||
669 | |||
670 | /* Copy the entire option so we can modify it. */ | ||
671 | buf = (unsigned char *)alloca(strlen((char *)str) + 1); | ||
672 | strcpy((char *)buf, (const char *)str); | ||
673 | /* Scan for any backslash-newline and remove it. */ | ||
674 | p = q = buf; | ||
675 | while (*p) | ||
676 | { | ||
677 | *q++ = *p++; | ||
678 | } | ||
679 | *q = 0; | ||
680 | |||
681 | p = buf; | ||
682 | if (!is_idstart[*p]) | ||
683 | { | ||
684 | cpp_error(pfile, "malformed option `%s %s'", option, str); | ||
685 | return; | ||
686 | } | ||
687 | while (is_idchar[*++p]) | ||
688 | ; | ||
689 | while (*p == ' ' || *p == '\t') | ||
690 | p++; | ||
691 | if (!(*p == 0 || *p == '(')) | ||
692 | { | ||
693 | cpp_error(pfile, "malformed option `%s %s'", option, str); | ||
694 | return; | ||
695 | } | ||
696 | cpp_push_buffer(pfile, buf, strlen((char *)buf)); | ||
697 | do_assert(pfile, NULL, NULL, NULL); | ||
698 | cpp_pop_buffer(pfile); | ||
699 | } | ||
700 | |||
701 | /* Append a chain of `file_name_list's | ||
702 | * to the end of the main include chain. | ||
703 | * FIRST is the beginning of the chain to append, and LAST is the end. */ | ||
704 | |||
705 | static void | ||
706 | append_include_chain(cpp_reader * pfile, file_name_list * first, | ||
707 | file_name_list * last) | ||
708 | { | ||
709 | struct cpp_options *opts = CPP_OPTIONS(pfile); | ||
710 | file_name_list *dir; | ||
711 | |||
712 | if (!first || !last) | ||
713 | return; | ||
714 | |||
715 | if (!opts->include) | ||
716 | opts->include = first; | ||
717 | else | ||
718 | opts->last_include->next = first; | ||
719 | |||
720 | if (!opts->first_bracket_include) | ||
721 | opts->first_bracket_include = first; | ||
722 | |||
723 | for (dir = first;; dir = dir->next) | ||
724 | { | ||
725 | int len = strlen(dir->fname) + INCLUDE_LEN_FUDGE; | ||
726 | |||
727 | if (len > pfile->max_include_len) | ||
728 | pfile->max_include_len = len; | ||
729 | if (dir == last) | ||
730 | break; | ||
731 | } | ||
732 | |||
733 | last->next = NULL; | ||
734 | opts->last_include = last; | ||
735 | } | ||
736 | |||
737 | /* Add output to `deps_buffer' for the -M switch. | ||
738 | * STRING points to the text to be output. | ||
739 | * SPACER is ':' for targets, ' ' for dependencies, zero for text | ||
740 | * to be inserted literally. */ | ||
741 | |||
742 | static void | ||
743 | deps_output(cpp_reader * pfile, const char *string, int spacer) | ||
744 | { | ||
745 | int size = strlen(string); | ||
746 | |||
747 | if (size == 0) | ||
748 | return; | ||
749 | |||
750 | #ifndef MAX_OUTPUT_COLUMNS | ||
751 | #define MAX_OUTPUT_COLUMNS 72 | ||
752 | #endif | ||
753 | if (spacer | ||
754 | && pfile->deps_column > 0 | ||
755 | && (pfile->deps_column + size) > MAX_OUTPUT_COLUMNS) | ||
756 | { | ||
757 | deps_output(pfile, " \\\n ", 0); | ||
758 | pfile->deps_column = 0; | ||
759 | } | ||
760 | if (pfile->deps_size + size + 8 > pfile->deps_allocated_size) | ||
761 | { | ||
762 | pfile->deps_allocated_size = (pfile->deps_size + size + 50) * 2; | ||
763 | pfile->deps_buffer = (char *)xrealloc(pfile->deps_buffer, | ||
764 | pfile->deps_allocated_size); | ||
765 | } | ||
766 | if (spacer == ' ' && pfile->deps_column > 0) | ||
767 | pfile->deps_buffer[pfile->deps_size++] = ' '; | ||
768 | memcpy(&pfile->deps_buffer[pfile->deps_size], string, size); | ||
769 | pfile->deps_size += size; | ||
770 | pfile->deps_column += size; | ||
771 | if (spacer == ':') | ||
772 | pfile->deps_buffer[pfile->deps_size++] = ':'; | ||
773 | pfile->deps_buffer[pfile->deps_size] = 0; | ||
774 | } | ||
775 | |||
776 | /* Given a colon-separated list of file names PATH, | ||
777 | * add all the names to the search path for include files. */ | ||
778 | |||
779 | static void | ||
780 | path_include(cpp_reader * pfile, char *path) | ||
781 | { | ||
782 | char *p; | ||
783 | |||
784 | p = path; | ||
785 | |||
786 | if (*p) | ||
787 | while (1) | ||
788 | { | ||
789 | char *q = p; | ||
790 | char *name; | ||
791 | file_name_list *dirtmp; | ||
792 | |||
793 | /* Find the end of this name. */ | ||
794 | while (*q != 0 && *q != PATH_SEPARATOR) | ||
795 | q++; | ||
796 | if (p == q) | ||
797 | { | ||
798 | /* An empty name in the path stands for the current directory. */ | ||
799 | name = (char *)xmalloc(2); | ||
800 | name[0] = '.'; | ||
801 | name[1] = 0; | ||
802 | } | ||
803 | else | ||
804 | { | ||
805 | /* Otherwise use the directory that is named. */ | ||
806 | name = (char *)xmalloc(q - p + 1); | ||
807 | memcpy(name, p, q - p); | ||
808 | name[q - p] = 0; | ||
809 | } | ||
810 | |||
811 | dirtmp = (file_name_list *) xmalloc(sizeof(file_name_list)); | ||
812 | |||
813 | dirtmp->next = 0; /* New one goes on the end */ | ||
814 | dirtmp->control_macro = 0; | ||
815 | dirtmp->c_system_include_path = 0; | ||
816 | dirtmp->fname = name; | ||
817 | dirtmp->got_name_map = 0; | ||
818 | append_include_chain(pfile, dirtmp, dirtmp); | ||
819 | |||
820 | /* Advance past this name. */ | ||
821 | p = q; | ||
822 | if (*p == 0) | ||
823 | break; | ||
824 | /* Skip the colon. */ | ||
825 | p++; | ||
826 | } | ||
827 | } | ||
828 | |||
829 | void | ||
830 | init_parse_options(struct cpp_options *opts) | ||
831 | { | ||
832 | memset((char *)opts, 0, sizeof *opts); | ||
833 | opts->in_fname = NULL; | ||
834 | opts->out_fname = NULL; | ||
835 | |||
836 | /* Initialize is_idchar to allow $. */ | ||
837 | opts->dollars_in_ident = 1; | ||
838 | initialize_char_syntax(opts); | ||
839 | opts->dollars_in_ident = DOLLARS_IN_IDENTIFIERS > 0; | ||
840 | |||
841 | opts->no_line_commands = 0; | ||
842 | opts->no_trigraphs = 1; | ||
843 | opts->put_out_comments = 0; | ||
844 | opts->print_include_names = 0; | ||
845 | opts->dump_macros = dump_none; | ||
846 | opts->no_output = 0; | ||
847 | opts->cplusplus = 0; | ||
848 | opts->cplusplus_comments = 1; | ||
849 | |||
850 | opts->verbose = 0; | ||
851 | opts->objc = 0; | ||
852 | opts->lang_asm = 0; | ||
853 | opts->for_lint = 0; | ||
854 | opts->chill = 0; | ||
855 | opts->pedantic_errors = 0; | ||
856 | opts->inhibit_warnings = 0; | ||
857 | opts->warn_comments = 0; | ||
858 | opts->warn_import = 1; | ||
859 | opts->warnings_are_errors = 0; | ||
860 | } | ||
861 | |||
862 | static enum cpp_token | ||
863 | null_underflow(cpp_reader * pfile __UNUSED__) | ||
864 | { | ||
865 | return CPP_EOF; | ||
866 | } | ||
867 | |||
868 | static int | ||
869 | null_cleanup(cpp_buffer * pbuf __UNUSED__, cpp_reader * pfile __UNUSED__) | ||
870 | { | ||
871 | return 0; | ||
872 | } | ||
873 | |||
874 | static int | ||
875 | macro_cleanup(cpp_buffer * pbuf, cpp_reader * pfile __UNUSED__) | ||
876 | { | ||
877 | HASHNODE *macro = (HASHNODE *) pbuf->data; | ||
878 | |||
879 | if (macro->type == T_DISABLED) | ||
880 | macro->type = T_MACRO; | ||
881 | if (macro->type != T_MACRO || pbuf->buf != macro->value.defn->expansion) | ||
882 | free(pbuf->buf); | ||
883 | return 0; | ||
884 | } | ||
885 | |||
886 | static int | ||
887 | file_cleanup(cpp_buffer * pbuf, cpp_reader * pfile __UNUSED__) | ||
888 | { | ||
889 | if (pbuf->buf) | ||
890 | { | ||
891 | free(pbuf->buf); | ||
892 | pbuf->buf = 0; | ||
893 | } | ||
894 | return 0; | ||
895 | } | ||
896 | |||
897 | /* Assuming we have read '/'. | ||
898 | * If this is the start of a comment (followed by '*' or '/'), | ||
899 | * skip to the end of the comment, and return ' '. | ||
900 | * Return EOF if we reached the end of file before the end of the comment. | ||
901 | * If not the start of a comment, return '/'. */ | ||
902 | |||
903 | static int | ||
904 | skip_comment(cpp_reader * pfile, long *linep) | ||
905 | { | ||
906 | int c = 0; | ||
907 | |||
908 | while (PEEKC() == '\\' && PEEKN(1) == '\n') | ||
909 | { | ||
910 | if (linep) | ||
911 | (*linep)++; | ||
912 | FORWARD(2); | ||
913 | } | ||
914 | if (PEEKC() == '*') | ||
915 | { | ||
916 | FORWARD(1); | ||
917 | for (;;) | ||
918 | { | ||
919 | int prev_c = c; | ||
920 | |||
921 | c = GETC(); | ||
922 | if (c == EOF) | ||
923 | return EOF; | ||
924 | while (c == '\\' && PEEKC() == '\n') | ||
925 | { | ||
926 | if (linep) | ||
927 | (*linep)++; | ||
928 | FORWARD(1), c = GETC(); | ||
929 | } | ||
930 | if (prev_c == '*' && c == '/') | ||
931 | return ' '; | ||
932 | if (c == '\n' && linep) | ||
933 | (*linep)++; | ||
934 | } | ||
935 | } | ||
936 | else if (PEEKC() == '/' && CPP_OPTIONS(pfile)->cplusplus_comments) | ||
937 | { | ||
938 | FORWARD(1); | ||
939 | for (;;) | ||
940 | { | ||
941 | c = GETC(); | ||
942 | if (c == EOF) | ||
943 | return ' '; /* Allow // to be terminated by EOF. */ | ||
944 | while (c == '\\' && PEEKC() == '\n') | ||
945 | { | ||
946 | FORWARD(1); | ||
947 | c = GETC(); | ||
948 | if (linep) | ||
949 | (*linep)++; | ||
950 | } | ||
951 | if (c == '\n') | ||
952 | { | ||
953 | /* Don't consider final '\n' to be part of comment. */ | ||
954 | FORWARD(-1); | ||
955 | return ' '; | ||
956 | } | ||
957 | } | ||
958 | } | ||
959 | else | ||
960 | return '/'; | ||
961 | } | ||
962 | |||
963 | /* Skip whitespace \-newline and comments. Does not macro-expand. */ | ||
964 | void | ||
965 | cpp_skip_hspace(cpp_reader * pfile) | ||
966 | { | ||
967 | while (1) | ||
968 | { | ||
969 | int c = PEEKC(); | ||
970 | |||
971 | if (c == EOF) | ||
972 | return; /* FIXME */ | ||
973 | if (is_hor_space[c]) | ||
974 | { | ||
975 | if ((c == '\f' || c == '\v') && CPP_PEDANTIC(pfile)) | ||
976 | cpp_pedwarn(pfile, "%s in preprocessing directive", | ||
977 | c == '\f' ? "formfeed" : "vertical tab"); | ||
978 | FORWARD(1); | ||
979 | } | ||
980 | else if (c == '/') | ||
981 | { | ||
982 | FORWARD(1); | ||
983 | c = skip_comment(pfile, NULL); | ||
984 | if (c == '/') | ||
985 | FORWARD(-1); | ||
986 | if (c == EOF || c == '/') | ||
987 | return; | ||
988 | } | ||
989 | else if (c == '\\' && PEEKN(1) == '\n') | ||
990 | { | ||
991 | FORWARD(2); | ||
992 | } | ||
993 | else if (c == '@' && CPP_BUFFER(pfile)->has_escapes | ||
994 | && is_hor_space[PEEKN(1)]) | ||
995 | { | ||
996 | FORWARD(1); | ||
997 | } | ||
998 | else | ||
999 | return; | ||
1000 | } | ||
1001 | } | ||
1002 | |||
1003 | /* Read the rest of the current line. | ||
1004 | * The line is appended to PFILE's output buffer. */ | ||
1005 | |||
1006 | static void | ||
1007 | copy_rest_of_line(cpp_reader * pfile) | ||
1008 | { | ||
1009 | struct cpp_options *opts = CPP_OPTIONS(pfile); | ||
1010 | |||
1011 | for (;;) | ||
1012 | { | ||
1013 | int c = GETC(); | ||
1014 | int nextc; | ||
1015 | |||
1016 | switch (c) | ||
1017 | { | ||
1018 | case EOF: | ||
1019 | goto end_directive; | ||
1020 | case '\\': | ||
1021 | if (PEEKC() == '\n') | ||
1022 | { | ||
1023 | FORWARD(1); | ||
1024 | continue; | ||
1025 | } | ||
1026 | case '\'': | ||
1027 | case '\"': | ||
1028 | goto scan_directive_token; | ||
1029 | break; | ||
1030 | case '/': | ||
1031 | nextc = PEEKC(); | ||
1032 | if (nextc == '*' || (opts->cplusplus_comments && nextc == '*')) | ||
1033 | goto scan_directive_token; | ||
1034 | break; | ||
1035 | case '\f': | ||
1036 | case '\v': | ||
1037 | if (CPP_PEDANTIC(pfile)) | ||
1038 | cpp_pedwarn(pfile, "%s in preprocessing directive", | ||
1039 | c == '\f' ? "formfeed" : "vertical tab"); | ||
1040 | break; | ||
1041 | |||
1042 | case '\n': | ||
1043 | FORWARD(-1); | ||
1044 | goto end_directive; | ||
1045 | scan_directive_token: | ||
1046 | FORWARD(-1); | ||
1047 | cpp_get_token(pfile); | ||
1048 | continue; | ||
1049 | } | ||
1050 | CPP_PUTC(pfile, c); | ||
1051 | } | ||
1052 | end_directive:; | ||
1053 | CPP_NUL_TERMINATE(pfile); | ||
1054 | } | ||
1055 | |||
1056 | void | ||
1057 | skip_rest_of_line(cpp_reader * pfile) | ||
1058 | { | ||
1059 | long old = CPP_WRITTEN(pfile); | ||
1060 | |||
1061 | copy_rest_of_line(pfile); | ||
1062 | CPP_SET_WRITTEN(pfile, old); | ||
1063 | } | ||
1064 | |||
1065 | /* Handle a possible # directive. | ||
1066 | * '#' has already been read. */ | ||
1067 | |||
1068 | static int | ||
1069 | handle_directive(cpp_reader * pfile) | ||
1070 | { | ||
1071 | int c; | ||
1072 | struct directive *kt; | ||
1073 | int ident_length; | ||
1074 | long after_ident = 0; | ||
1075 | unsigned char *ident, *line_end; | ||
1076 | long old_written = CPP_WRITTEN(pfile); | ||
1077 | |||
1078 | cpp_skip_hspace(pfile); | ||
1079 | |||
1080 | c = PEEKC(); | ||
1081 | if (c >= '0' && c <= '9') | ||
1082 | { | ||
1083 | /* Handle # followed by a line number. */ | ||
1084 | if (CPP_PEDANTIC(pfile)) | ||
1085 | cpp_pedwarn(pfile, "`#' followed by integer"); | ||
1086 | do_line(pfile, NULL, NULL, NULL); | ||
1087 | goto done_a_directive; | ||
1088 | } | ||
1089 | /* Now find the directive name. */ | ||
1090 | CPP_PUTC(pfile, '#'); | ||
1091 | parse_name(pfile, GETC()); | ||
1092 | ident = pfile->token_buffer + old_written + 1; | ||
1093 | ident_length = CPP_PWRITTEN(pfile) - ident; | ||
1094 | if (ident_length == 0 && PEEKC() == '\n') | ||
1095 | { | ||
1096 | /* A line of just `#' becomes blank. */ | ||
1097 | goto done_a_directive; | ||
1098 | } | ||
1099 | /* | ||
1100 | * Decode the keyword and call the appropriate expansion | ||
1101 | * routine, after moving the input pointer up to the next line. | ||
1102 | */ | ||
1103 | for (kt = directive_table;; kt++) | ||
1104 | { | ||
1105 | if (kt->length <= 0) | ||
1106 | goto not_a_directive; | ||
1107 | if (kt->length == ident_length | ||
1108 | && !strncmp(kt->name, (const char *)ident, ident_length)) | ||
1109 | break; | ||
1110 | } | ||
1111 | |||
1112 | if (!kt->command_reads_line) | ||
1113 | { | ||
1114 | /* Nonzero means do not delete comments within the directive. | ||
1115 | * #define needs this when -traditional. */ | ||
1116 | int comments = 0; | ||
1117 | int save_put_out_comments = | ||
1118 | CPP_OPTIONS(pfile)->put_out_comments; | ||
1119 | |||
1120 | CPP_OPTIONS(pfile)->put_out_comments = comments; | ||
1121 | after_ident = CPP_WRITTEN(pfile); | ||
1122 | copy_rest_of_line(pfile); | ||
1123 | CPP_OPTIONS(pfile)->put_out_comments = save_put_out_comments; | ||
1124 | } | ||
1125 | /* For #pragma and #define, we may want to pass through the directive. | ||
1126 | * Other directives may create output, but we don't want the directive | ||
1127 | * itself out, so we pop it now. For example #include may write a #line | ||
1128 | * command (see comment in do_include), and conditionals may emit | ||
1129 | * #failed ... #endfailed stuff. But note that popping the buffer | ||
1130 | * means the parameters to kt->func may point after pfile->limit | ||
1131 | * so these parameters are invalid as soon as something gets appended | ||
1132 | * to the token_buffer. */ | ||
1133 | |||
1134 | line_end = CPP_PWRITTEN(pfile); | ||
1135 | if (!kt->pass_thru && kt->type != T_DEFINE) | ||
1136 | CPP_SET_WRITTEN(pfile, old_written); | ||
1137 | |||
1138 | (*kt->func) (pfile, kt, pfile->token_buffer + after_ident, line_end); | ||
1139 | if (kt->pass_thru | ||
1140 | || (kt->type == T_DEFINE | ||
1141 | && CPP_OPTIONS(pfile)->dump_macros == dump_definitions)) | ||
1142 | { | ||
1143 | /* Just leave the entire #define in the output stack. */ | ||
1144 | } | ||
1145 | else if (kt->type == T_DEFINE | ||
1146 | && CPP_OPTIONS(pfile)->dump_macros == dump_names) | ||
1147 | { | ||
1148 | unsigned char *p = pfile->token_buffer + old_written + 7; /* Skip "#define". */ | ||
1149 | |||
1150 | SKIP_WHITE_SPACE(p); | ||
1151 | while (is_idchar[*p]) | ||
1152 | p++; | ||
1153 | pfile->limit = p; | ||
1154 | CPP_PUTC(pfile, '\n'); | ||
1155 | } | ||
1156 | else if (kt->type == T_DEFINE) | ||
1157 | CPP_SET_WRITTEN(pfile, old_written); | ||
1158 | done_a_directive: | ||
1159 | return 1; | ||
1160 | |||
1161 | not_a_directive: | ||
1162 | return 0; | ||
1163 | } | ||
1164 | |||
1165 | /* Pass a directive through to the output file. | ||
1166 | * BUF points to the contents of the directive, as a contiguous string. | ||
1167 | * LIMIT points to the first character past the end of the directive. | ||
1168 | * KEYWORD is the keyword-table entry for the directive. */ | ||
1169 | |||
1170 | static void | ||
1171 | pass_thru_directive(char *buf, char *limit, cpp_reader * pfile, | ||
1172 | struct directive *keyword) | ||
1173 | { | ||
1174 | unsigned keyword_length = keyword->length; | ||
1175 | |||
1176 | CPP_RESERVE(pfile, 1 + keyword_length + (limit - buf)); | ||
1177 | CPP_PUTC_Q(pfile, '#'); | ||
1178 | CPP_PUTS_Q(pfile, keyword->name, keyword_length); | ||
1179 | if (limit != buf && buf[0] != ' ') | ||
1180 | CPP_PUTC_Q(pfile, ' '); | ||
1181 | CPP_PUTS_Q(pfile, buf, limit - buf); | ||
1182 | } | ||
1183 | |||
1184 | /* The arglist structure is built by do_define to tell | ||
1185 | * collect_definition where the argument names begin. That | ||
1186 | * is, for a define like "#define f(x,y,z) foo+x-bar*y", the arglist | ||
1187 | * would contain pointers to the strings x, y, and z. | ||
1188 | * Collect_definition would then build a DEFINITION node, | ||
1189 | * with reflist nodes pointing to the places x, y, and z had | ||
1190 | * appeared. So the arglist is just convenience data passed | ||
1191 | * between these two routines. It is not kept around after | ||
1192 | * the current #define has been processed and entered into the | ||
1193 | * hash table. */ | ||
1194 | |||
1195 | struct arglist { | ||
1196 | struct arglist *next; | ||
1197 | char *name; | ||
1198 | int length; | ||
1199 | int argno; | ||
1200 | char rest_args; | ||
1201 | }; | ||
1202 | |||
1203 | /* Read a replacement list for a macro with parameters. | ||
1204 | * Build the DEFINITION structure. | ||
1205 | * Reads characters of text starting at BUF until END. | ||
1206 | * ARGLIST specifies the formal parameters to look for | ||
1207 | * in the text of the definition; NARGS is the number of args | ||
1208 | * in that list, or -1 for a macro name that wants no argument list. | ||
1209 | * MACRONAME is the macro name itself (so we can avoid recursive expansion) | ||
1210 | * and NAMELEN is its length in characters. | ||
1211 | * | ||
1212 | * Note that comments, backslash-newlines, and leading white space | ||
1213 | * have already been deleted from the argument. */ | ||
1214 | |||
1215 | static DEFINITION * | ||
1216 | collect_expansion(cpp_reader * pfile, unsigned char *buf, unsigned char *limit, | ||
1217 | int nargs, struct arglist *arglist) | ||
1218 | { | ||
1219 | DEFINITION *defn; | ||
1220 | unsigned char *p, *lastp, *exp_p; | ||
1221 | reflist *endpat = NULL; | ||
1222 | |||
1223 | /* Pointer to first nonspace after last ## seen. */ | ||
1224 | unsigned char *concat = 0; | ||
1225 | |||
1226 | /* Pointer to first nonspace after last single-# seen. */ | ||
1227 | unsigned char *stringify = 0; | ||
1228 | int maxsize; | ||
1229 | int expected_delimiter = '\0'; | ||
1230 | |||
1231 | /* Scan thru the replacement list, ignoring comments and quoted | ||
1232 | * strings, picking up on the macro calls. It does a linear search | ||
1233 | * thru the arg list on every potential symbol. Profiling might say | ||
1234 | * that something smarter should happen. */ | ||
1235 | |||
1236 | if (limit < buf) | ||
1237 | abort(); | ||
1238 | |||
1239 | /* Find the beginning of the trailing whitespace. */ | ||
1240 | p = buf; | ||
1241 | while (p < limit && is_space[limit[-1]]) | ||
1242 | limit--; | ||
1243 | |||
1244 | /* Allocate space for the text in the macro definition. | ||
1245 | * Leading and trailing whitespace chars need 2 bytes each. | ||
1246 | * Each other input char may or may not need 1 byte, | ||
1247 | * so this is an upper bound. The extra 5 are for invented | ||
1248 | * leading and trailing newline-marker and final null. */ | ||
1249 | maxsize = (sizeof(DEFINITION) + (limit - p) + 5); | ||
1250 | /* Occurrences of '@' get doubled, so allocate extra space for them. */ | ||
1251 | while (p < limit) | ||
1252 | if (*p++ == '@') | ||
1253 | maxsize++; | ||
1254 | defn = (DEFINITION *) xcalloc(1, maxsize); | ||
1255 | |||
1256 | defn->nargs = nargs; | ||
1257 | exp_p = defn->expansion = (unsigned char *)defn + sizeof(DEFINITION); | ||
1258 | lastp = exp_p; | ||
1259 | |||
1260 | p = buf; | ||
1261 | |||
1262 | /* Add one initial space escape-marker to prevent accidental | ||
1263 | * token-pasting (often removed by macroexpand). */ | ||
1264 | *exp_p++ = '@'; | ||
1265 | *exp_p++ = ' '; | ||
1266 | |||
1267 | if (limit - p >= 2 && p[0] == '#' && p[1] == '#') | ||
1268 | { | ||
1269 | cpp_error(pfile, "`##' at start of macro definition"); | ||
1270 | p += 2; | ||
1271 | } | ||
1272 | /* Process the main body of the definition. */ | ||
1273 | while (p < limit) | ||
1274 | { | ||
1275 | int skipped_arg = 0; | ||
1276 | unsigned char c = *p++; | ||
1277 | |||
1278 | *exp_p++ = c; | ||
1279 | |||
1280 | switch (c) | ||
1281 | { | ||
1282 | case '\'': | ||
1283 | case '\"': | ||
1284 | if (expected_delimiter != '\0') | ||
1285 | { | ||
1286 | if (c == expected_delimiter) | ||
1287 | expected_delimiter = '\0'; | ||
1288 | } | ||
1289 | else | ||
1290 | expected_delimiter = c; | ||
1291 | break; | ||
1292 | |||
1293 | case '\\': | ||
1294 | if (p < limit && expected_delimiter) | ||
1295 | { | ||
1296 | /* In a string, backslash goes through | ||
1297 | * and makes next char ordinary. */ | ||
1298 | *exp_p++ = *p++; | ||
1299 | } | ||
1300 | break; | ||
1301 | |||
1302 | case '@': | ||
1303 | /* An '@' in a string or character constant stands for itself, | ||
1304 | * and does not need to be escaped. */ | ||
1305 | if (!expected_delimiter) | ||
1306 | *exp_p++ = c; | ||
1307 | break; | ||
1308 | |||
1309 | case '#': | ||
1310 | /* # is ordinary inside a string. */ | ||
1311 | if (expected_delimiter) | ||
1312 | break; | ||
1313 | if (p < limit && *p == '#') | ||
1314 | { | ||
1315 | /* ##: concatenate preceding and following tokens. */ | ||
1316 | /* Take out the first #, discard preceding whitespace. */ | ||
1317 | exp_p--; | ||
1318 | while (exp_p > lastp && is_hor_space[exp_p[-1]]) | ||
1319 | --exp_p; | ||
1320 | /* Skip the second #. */ | ||
1321 | p++; | ||
1322 | /* Discard following whitespace. */ | ||
1323 | SKIP_WHITE_SPACE(p); | ||
1324 | concat = p; | ||
1325 | if (p == limit) | ||
1326 | cpp_error(pfile, "`##' at end of macro definition"); | ||
1327 | } | ||
1328 | else if (nargs >= 0) | ||
1329 | { | ||
1330 | /* Single #: stringify following argument ref. | ||
1331 | * Don't leave the # in the expansion. */ | ||
1332 | exp_p--; | ||
1333 | SKIP_WHITE_SPACE(p); | ||
1334 | if (p == limit || !is_idstart[*p]) | ||
1335 | cpp_error(pfile, | ||
1336 | "`#' operator is not followed by a macro argument name"); | ||
1337 | else | ||
1338 | stringify = p; | ||
1339 | } | ||
1340 | break; | ||
1341 | } | ||
1342 | |||
1343 | /* Handle the start of a symbol. */ | ||
1344 | if (is_idchar[c] && nargs > 0) | ||
1345 | { | ||
1346 | unsigned char *id_beg = p - 1; | ||
1347 | int id_len; | ||
1348 | |||
1349 | --exp_p; | ||
1350 | while (p != limit && is_idchar[*p]) | ||
1351 | p++; | ||
1352 | id_len = p - id_beg; | ||
1353 | |||
1354 | if (is_idstart[c]) | ||
1355 | { | ||
1356 | struct arglist *arg; | ||
1357 | |||
1358 | for (arg = arglist; arg; arg = arg->next) | ||
1359 | { | ||
1360 | reflist *tpat; | ||
1361 | |||
1362 | if (arg->name[0] == c | ||
1363 | && arg->length == id_len | ||
1364 | && strncmp((const char *)arg->name, | ||
1365 | (const char *)id_beg, id_len) == 0) | ||
1366 | { | ||
1367 | if (expected_delimiter | ||
1368 | && CPP_OPTIONS(pfile)->warn_stringify) | ||
1369 | { | ||
1370 | cpp_warning(pfile, | ||
1371 | "macro arg `%.*s' would be stringified with -traditional.", | ||
1372 | id_len, arg->name); | ||
1373 | } | ||
1374 | /* If ANSI, don't actually substitute inside a string. */ | ||
1375 | if (expected_delimiter) | ||
1376 | break; | ||
1377 | /* make a pat node for this arg and append it to the end of | ||
1378 | * the pat list */ | ||
1379 | tpat = (reflist *) xmalloc(sizeof(reflist)); | ||
1380 | |||
1381 | tpat->next = NULL; | ||
1382 | tpat->raw_before = concat == id_beg; | ||
1383 | tpat->raw_after = 0; | ||
1384 | tpat->rest_args = arg->rest_args; | ||
1385 | tpat->stringify = (stringify == id_beg); | ||
1386 | |||
1387 | if (!endpat) | ||
1388 | defn->pattern = tpat; | ||
1389 | else | ||
1390 | endpat->next = tpat; | ||
1391 | endpat = tpat; | ||
1392 | |||
1393 | tpat->argno = arg->argno; | ||
1394 | tpat->nchars = exp_p - lastp; | ||
1395 | { | ||
1396 | unsigned char *p1 = p; | ||
1397 | |||
1398 | SKIP_WHITE_SPACE(p1); | ||
1399 | if (p1 + 2 <= limit && p1[0] == '#' | ||
1400 | && p1[1] == '#') | ||
1401 | tpat->raw_after = 1; | ||
1402 | } | ||
1403 | lastp = exp_p; /* place to start copying from next time */ | ||
1404 | skipped_arg = 1; | ||
1405 | break; | ||
1406 | } | ||
1407 | } | ||
1408 | } | ||
1409 | /* If this was not a macro arg, copy it into the expansion. */ | ||
1410 | if (!skipped_arg) | ||
1411 | { | ||
1412 | unsigned char *lim1 = p; | ||
1413 | |||
1414 | p = id_beg; | ||
1415 | while (p != lim1) | ||
1416 | *exp_p++ = *p++; | ||
1417 | if (stringify == id_beg) | ||
1418 | cpp_error(pfile, | ||
1419 | "`#' operator should be followed by a macro argument name"); | ||
1420 | } | ||
1421 | } | ||
1422 | } | ||
1423 | |||
1424 | if (expected_delimiter == 0) | ||
1425 | { | ||
1426 | /* If ANSI, put in a "@ " marker to prevent token pasting. | ||
1427 | * But not if "inside a string" (which in ANSI mode | ||
1428 | * happens only for -D option). */ | ||
1429 | *exp_p++ = '@'; | ||
1430 | *exp_p++ = ' '; | ||
1431 | } | ||
1432 | *exp_p = '\0'; | ||
1433 | |||
1434 | defn->length = exp_p - defn->expansion; | ||
1435 | |||
1436 | /* Crash now if we overrun the allocated size. */ | ||
1437 | if (defn->length + 1 > maxsize) | ||
1438 | abort(); | ||
1439 | |||
1440 | return defn; | ||
1441 | } | ||
1442 | |||
1443 | /* | ||
1444 | * special extension string that can be added to the last macro argument to | ||
1445 | * allow it to absorb the "rest" of the arguments when expanded. Ex: | ||
1446 | * #define wow(a, b...) process (b, a, b) | ||
1447 | * { wow (1, 2, 3); } -> { process (2, 3, 1, 2, 3); } | ||
1448 | * { wow (one, two); } -> { process (two, one, two); } | ||
1449 | * if this "rest_arg" is used with the concat token '##' and if it is not | ||
1450 | * supplied then the token attached to with ## will not be outputted. Ex: | ||
1451 | * #define wow (a, b...) process (b ## , a, ## b) | ||
1452 | * { wow (1, 2); } -> { process (2, 1, 2); } | ||
1453 | * { wow (one); } -> { process (one); { | ||
1454 | */ | ||
1455 | static char rest_extension[] = "..."; | ||
1456 | |||
1457 | #define REST_EXTENSION_LENGTH (sizeof (rest_extension) - 1) | ||
1458 | |||
1459 | /* Create a DEFINITION node from a #define directive. Arguments are | ||
1460 | * as for do_define. */ | ||
1461 | static void | ||
1462 | create_definition(MACRODEF * mdef, unsigned char *buf, unsigned char *limit, | ||
1463 | cpp_reader * pfile, int predefinition) | ||
1464 | { | ||
1465 | unsigned char *bp; /* temp ptr into input buffer */ | ||
1466 | unsigned char *symname; /* remember where symbol name starts */ | ||
1467 | int sym_length; /* and how long it is */ | ||
1468 | int rest_args = 0; | ||
1469 | long line, col; | ||
1470 | const char *file = | ||
1471 | CPP_BUFFER(pfile) ? CPP_BUFFER(pfile)->nominal_fname : ""; | ||
1472 | DEFINITION *defn; | ||
1473 | int arglengths = 0; /* Accumulate lengths of arg names | ||
1474 | * plus number of args. */ | ||
1475 | |||
1476 | cpp_buf_line_and_col(CPP_BUFFER(pfile), &line, &col); | ||
1477 | |||
1478 | bp = buf; | ||
1479 | |||
1480 | while (is_hor_space[*bp]) | ||
1481 | bp++; | ||
1482 | |||
1483 | symname = bp; /* remember where it starts */ | ||
1484 | |||
1485 | sym_length = check_macro_name(pfile, bp, "macro"); | ||
1486 | bp += sym_length; | ||
1487 | |||
1488 | /* Lossage will occur if identifiers or control keywords are broken | ||
1489 | * across lines using backslash. This is not the right place to take | ||
1490 | * care of that. */ | ||
1491 | |||
1492 | if (*bp == '(') | ||
1493 | { | ||
1494 | struct arglist *arg_ptrs = NULL; | ||
1495 | int argno = 0; | ||
1496 | |||
1497 | bp++; /* skip '(' */ | ||
1498 | SKIP_WHITE_SPACE(bp); | ||
1499 | |||
1500 | /* Loop over macro argument names. */ | ||
1501 | while (*bp != ')') | ||
1502 | { | ||
1503 | struct arglist *temp; | ||
1504 | |||
1505 | temp = (struct arglist *)alloca(sizeof(struct arglist)); | ||
1506 | |||
1507 | temp->name = (char *)bp; | ||
1508 | temp->next = arg_ptrs; | ||
1509 | temp->argno = argno++; | ||
1510 | temp->rest_args = 0; | ||
1511 | arg_ptrs = temp; | ||
1512 | |||
1513 | if (rest_args) | ||
1514 | cpp_pedwarn(pfile, "another parameter follows `%s'", | ||
1515 | rest_extension); | ||
1516 | |||
1517 | if (!is_idstart[*bp]) | ||
1518 | cpp_pedwarn(pfile, "invalid character in macro parameter name"); | ||
1519 | |||
1520 | /* Find the end of the arg name. */ | ||
1521 | while (is_idchar[*bp]) | ||
1522 | { | ||
1523 | bp++; | ||
1524 | /* do we have a "special" rest-args extension here? */ | ||
1525 | if ((unsigned)(limit - bp) > REST_EXTENSION_LENGTH && | ||
1526 | strncmp(rest_extension, (const char *)bp, | ||
1527 | REST_EXTENSION_LENGTH) == 0) | ||
1528 | { | ||
1529 | rest_args = 1; | ||
1530 | temp->rest_args = 1; | ||
1531 | break; | ||
1532 | } | ||
1533 | } | ||
1534 | temp->length = (char *)bp - temp->name; | ||
1535 | if (rest_args == 1) | ||
1536 | bp += REST_EXTENSION_LENGTH; | ||
1537 | arglengths += temp->length + 2; | ||
1538 | SKIP_WHITE_SPACE(bp); | ||
1539 | if (temp->length == 0 || (*bp != ',' && *bp != ')')) | ||
1540 | { | ||
1541 | cpp_error(pfile, | ||
1542 | "badly punctuated parameter list in `#define'"); | ||
1543 | goto nope; | ||
1544 | } | ||
1545 | if (*bp == ',') | ||
1546 | { | ||
1547 | bp++; | ||
1548 | SKIP_WHITE_SPACE(bp); | ||
1549 | } | ||
1550 | if (bp >= limit) | ||
1551 | { | ||
1552 | cpp_error(pfile, "unterminated parameter list in `#define'"); | ||
1553 | goto nope; | ||
1554 | } | ||
1555 | { | ||
1556 | struct arglist *otemp; | ||
1557 | |||
1558 | for (otemp = temp->next; otemp; otemp = otemp->next) | ||
1559 | if (temp->length == otemp->length && | ||
1560 | strncmp((const char *)temp->name, | ||
1561 | (const char *)otemp->name, temp->length) == 0) | ||
1562 | { | ||
1563 | char *name; | ||
1564 | |||
1565 | name = (char *)alloca(temp->length + 1); | ||
1566 | strncpy(name, (const char *)temp->name, temp->length); | ||
1567 | name[temp->length] = '\0'; | ||
1568 | cpp_error(pfile, | ||
1569 | "duplicate argument name `%s' in `#define'", | ||
1570 | name); | ||
1571 | goto nope; | ||
1572 | } | ||
1573 | } | ||
1574 | } | ||
1575 | |||
1576 | ++bp; /* skip paren */ | ||
1577 | SKIP_WHITE_SPACE(bp); | ||
1578 | /* now everything from bp before limit is the definition. */ | ||
1579 | defn = collect_expansion(pfile, bp, limit, argno, arg_ptrs); | ||
1580 | defn->rest_args = rest_args; | ||
1581 | |||
1582 | /* Now set defn->args.argnames to the result of concatenating | ||
1583 | * the argument names in reverse order | ||
1584 | * with comma-space between them. */ | ||
1585 | defn->args.argnames = (unsigned char *)xmalloc(arglengths + 1); | ||
1586 | { | ||
1587 | struct arglist *temp; | ||
1588 | int i = 0; | ||
1589 | |||
1590 | for (temp = arg_ptrs; temp; temp = temp->next) | ||
1591 | { | ||
1592 | memcpy(&defn->args.argnames[i], temp->name, temp->length); | ||
1593 | i += temp->length; | ||
1594 | if (temp->next) | ||
1595 | { | ||
1596 | defn->args.argnames[i++] = ','; | ||
1597 | defn->args.argnames[i++] = ' '; | ||
1598 | } | ||
1599 | } | ||
1600 | defn->args.argnames[i] = 0; | ||
1601 | } | ||
1602 | } | ||
1603 | else | ||
1604 | { | ||
1605 | /* Simple expansion or empty definition. */ | ||
1606 | |||
1607 | if (bp < limit) | ||
1608 | { | ||
1609 | if (is_hor_space[*bp]) | ||
1610 | { | ||
1611 | bp++; | ||
1612 | SKIP_WHITE_SPACE(bp); | ||
1613 | } | ||
1614 | else | ||
1615 | { | ||
1616 | switch (*bp) | ||
1617 | { | ||
1618 | case '!': | ||
1619 | case '"': | ||
1620 | case '#': | ||
1621 | case '%': | ||
1622 | case '&': | ||
1623 | case '\'': | ||
1624 | case ')': | ||
1625 | case '*': | ||
1626 | case '+': | ||
1627 | case ',': | ||
1628 | case '-': | ||
1629 | case '.': | ||
1630 | case '/': | ||
1631 | case ':': | ||
1632 | case ';': | ||
1633 | case '<': | ||
1634 | case '=': | ||
1635 | case '>': | ||
1636 | case '?': | ||
1637 | case '[': | ||
1638 | case '\\': | ||
1639 | case ']': | ||
1640 | case '^': | ||
1641 | case '{': | ||
1642 | case '|': | ||
1643 | case '}': | ||
1644 | case '~': | ||
1645 | cpp_warning(pfile, | ||
1646 | "missing white space after `#define %.*s'", | ||
1647 | sym_length, symname); | ||
1648 | break; | ||
1649 | |||
1650 | default: | ||
1651 | cpp_pedwarn(pfile, | ||
1652 | "missing white space after `#define %.*s'", | ||
1653 | sym_length, symname); | ||
1654 | break; | ||
1655 | } | ||
1656 | } | ||
1657 | } | ||
1658 | /* now everything from bp before limit is the definition. */ | ||
1659 | defn = collect_expansion(pfile, bp, limit, -1, NULL); | ||
1660 | defn->args.argnames = (unsigned char *)""; | ||
1661 | } | ||
1662 | |||
1663 | defn->line = line; | ||
1664 | defn->file = file; | ||
1665 | |||
1666 | /* OP is null if this is a predefinition */ | ||
1667 | defn->predefined = predefinition; | ||
1668 | mdef->defn = defn; | ||
1669 | mdef->symnam = (char *)symname; | ||
1670 | mdef->symlen = sym_length; | ||
1671 | |||
1672 | return; | ||
1673 | |||
1674 | nope: | ||
1675 | mdef->defn = 0; | ||
1676 | } | ||
1677 | |||
1678 | /* Check a purported macro name SYMNAME, and yield its length. | ||
1679 | * USAGE is the kind of name this is intended for. */ | ||
1680 | |||
1681 | static int | ||
1682 | check_macro_name(cpp_reader * pfile, unsigned char *symname, const char *usage) | ||
1683 | { | ||
1684 | unsigned char *p; | ||
1685 | int sym_length; | ||
1686 | |||
1687 | for (p = symname; is_idchar[*p]; p++) | ||
1688 | ; | ||
1689 | sym_length = p - symname; | ||
1690 | if (sym_length == 0) | ||
1691 | { | ||
1692 | cpp_error(pfile, "invalid %s name", usage); | ||
1693 | } | ||
1694 | else if (!is_idstart[*symname]) | ||
1695 | { | ||
1696 | unsigned char *msg; /* what pain... */ | ||
1697 | |||
1698 | msg = (unsigned char *)alloca(sym_length + 1); | ||
1699 | memcpy(msg, symname, sym_length); | ||
1700 | msg[sym_length] = 0; | ||
1701 | cpp_error(pfile, "invalid %s name `%s'", usage, msg); | ||
1702 | } | ||
1703 | else | ||
1704 | { | ||
1705 | if (!strncmp((const char *)symname, "defined", 7) && sym_length == 7) | ||
1706 | cpp_error(pfile, "invalid %s name `defined'", usage); | ||
1707 | } | ||
1708 | return sym_length; | ||
1709 | } | ||
1710 | |||
1711 | /* | ||
1712 | * return zero if two DEFINITIONs are isomorphic | ||
1713 | */ | ||
1714 | static int | ||
1715 | compare_defs(DEFINITION * d1, DEFINITION * d2) | ||
1716 | { | ||
1717 | reflist *a1, *a2; | ||
1718 | unsigned char *p1 = d1->expansion; | ||
1719 | unsigned char *p2 = d2->expansion; | ||
1720 | int first = 1; | ||
1721 | |||
1722 | if (d1->nargs != d2->nargs) | ||
1723 | return 1; | ||
1724 | if (strcmp((char *)d1->args.argnames, (char *)d2->args.argnames)) | ||
1725 | return 1; | ||
1726 | for (a1 = d1->pattern, a2 = d2->pattern; a1 && a2; | ||
1727 | a1 = a1->next, a2 = a2->next) | ||
1728 | { | ||
1729 | if (! | ||
1730 | ((a1->nchars == a2->nchars | ||
1731 | && !strncmp((const char *)p1, (const char *)p2, a1->nchars)) | ||
1732 | || !comp_def_part(first, p1, a1->nchars, p2, a2->nchars, 0)) | ||
1733 | || a1->argno != a2->argno || a1->stringify != a2->stringify | ||
1734 | || a1->raw_before != a2->raw_before | ||
1735 | || a1->raw_after != a2->raw_after) | ||
1736 | return 1; | ||
1737 | first = 0; | ||
1738 | p1 += a1->nchars; | ||
1739 | p2 += a2->nchars; | ||
1740 | } | ||
1741 | if (a1 != a2) | ||
1742 | return 1; | ||
1743 | if (comp_def_part(first, p1, d1->length - (p1 - d1->expansion), | ||
1744 | p2, d2->length - (p2 - d2->expansion), 1)) | ||
1745 | return 1; | ||
1746 | return 0; | ||
1747 | } | ||
1748 | |||
1749 | /* Return 1 if two parts of two macro definitions are effectively different. | ||
1750 | * One of the parts starts at BEG1 and has LEN1 chars; | ||
1751 | * the other has LEN2 chars at BEG2. | ||
1752 | * Any sequence of whitespace matches any other sequence of whitespace. | ||
1753 | * FIRST means these parts are the first of a macro definition; | ||
1754 | * so ignore leading whitespace entirely. | ||
1755 | * LAST means these parts are the last of a macro definition; | ||
1756 | * so ignore trailing whitespace entirely. */ | ||
1757 | |||
1758 | static int | ||
1759 | comp_def_part(int first, unsigned char *beg1, int len1, | ||
1760 | unsigned char *beg2, int len2, int last) | ||
1761 | { | ||
1762 | unsigned char *end1 = beg1 + len1; | ||
1763 | unsigned char *end2 = beg2 + len2; | ||
1764 | |||
1765 | if (first) | ||
1766 | { | ||
1767 | while (beg1 != end1 && is_space[*beg1]) | ||
1768 | beg1++; | ||
1769 | while (beg2 != end2 && is_space[*beg2]) | ||
1770 | beg2++; | ||
1771 | } | ||
1772 | if (last) | ||
1773 | { | ||
1774 | while (beg1 != end1 && is_space[end1[-1]]) | ||
1775 | end1--; | ||
1776 | while (beg2 != end2 && is_space[end2[-1]]) | ||
1777 | end2--; | ||
1778 | } | ||
1779 | while (beg1 != end1 && beg2 != end2) | ||
1780 | { | ||
1781 | if (is_space[*beg1] && is_space[*beg2]) | ||
1782 | { | ||
1783 | while (beg1 != end1 && is_space[*beg1]) | ||
1784 | beg1++; | ||
1785 | while (beg2 != end2 && is_space[*beg2]) | ||
1786 | beg2++; | ||
1787 | } | ||
1788 | else if (*beg1 == *beg2) | ||
1789 | { | ||
1790 | beg1++; | ||
1791 | beg2++; | ||
1792 | } | ||
1793 | else | ||
1794 | break; | ||
1795 | } | ||
1796 | return (beg1 != end1) || (beg2 != end2); | ||
1797 | } | ||
1798 | |||
1799 | /* Process a #define command. | ||
1800 | * BUF points to the contents of the #define command, as a contiguous string. | ||
1801 | * LIMIT points to the first character past the end of the definition. | ||
1802 | * KEYWORD is the keyword-table entry for #define, | ||
1803 | * or NULL for a "predefined" macro. */ | ||
1804 | |||
1805 | static int | ||
1806 | do_define(cpp_reader * pfile, struct directive *keyword, | ||
1807 | unsigned char *buf, unsigned char *limit) | ||
1808 | { | ||
1809 | int hashcode; | ||
1810 | MACRODEF mdef; | ||
1811 | HASHNODE *hp; | ||
1812 | |||
1813 | create_definition(&mdef, buf, limit, pfile, !keyword); | ||
1814 | if (!mdef.defn) | ||
1815 | return 1; | ||
1816 | |||
1817 | hashcode = hashf(mdef.symnam, mdef.symlen, HASHSIZE); | ||
1818 | |||
1819 | if ((hp = cpp_lookup(mdef.symnam, mdef.symlen, hashcode))) | ||
1820 | { | ||
1821 | int ok = 0; | ||
1822 | |||
1823 | /* Redefining a precompiled key is ok. */ | ||
1824 | if (hp->type == T_PCSTRING) | ||
1825 | ok = 1; | ||
1826 | /* Redefining a macro is ok if the definitions are the same. */ | ||
1827 | else if (hp->type == T_MACRO) | ||
1828 | ok = !compare_defs(mdef.defn, hp->value.defn); | ||
1829 | /* Redefining a constant is ok with -D. */ | ||
1830 | else if (hp->type == T_CONST) | ||
1831 | ok = !CPP_OPTIONS(pfile)->done_initializing; | ||
1832 | /* Print the warning if it's not ok. */ | ||
1833 | if (!ok) | ||
1834 | { | ||
1835 | char *msg; /* what pain... */ | ||
1836 | |||
1837 | /* If we are passing through #define and #undef directives, do | ||
1838 | * that for this re-definition now. */ | ||
1839 | if (CPP_OPTIONS(pfile)->debug_output && keyword) | ||
1840 | pass_thru_directive((char *)buf, (char *)limit, pfile, keyword); | ||
1841 | |||
1842 | msg = (char *)alloca(mdef.symlen + 22); | ||
1843 | *msg = '`'; | ||
1844 | memcpy(msg + 1, mdef.symnam, mdef.symlen); | ||
1845 | strcpy((msg + mdef.symlen + 1), "' redefined"); | ||
1846 | cpp_pedwarn(pfile, msg); | ||
1847 | if (hp->type == T_MACRO) | ||
1848 | cpp_pedwarn_with_file_and_line(pfile, hp->value.defn->file, | ||
1849 | hp->value.defn->line, | ||
1850 | "this is the location of the previous definition", | ||
1851 | NULL, NULL, NULL); | ||
1852 | } | ||
1853 | /* Replace the old definition. */ | ||
1854 | hp->type = T_MACRO; | ||
1855 | hp->value.defn = mdef.defn; | ||
1856 | } | ||
1857 | else | ||
1858 | { | ||
1859 | /* If we are passing through #define and #undef directives, do | ||
1860 | * that for this new definition now. */ | ||
1861 | if (CPP_OPTIONS(pfile)->debug_output && keyword) | ||
1862 | pass_thru_directive((char *)buf, (char *)limit, pfile, keyword); | ||
1863 | install(mdef.symnam, mdef.symlen, T_MACRO, 0, | ||
1864 | (char *)mdef.defn, hashcode); | ||
1865 | } | ||
1866 | |||
1867 | return 0; | ||
1868 | } | ||
1869 | |||
1870 | /* This structure represents one parsed argument in a macro call. | ||
1871 | * `raw' points to the argument text as written (`raw_length' is its length). | ||
1872 | * `expanded' points to the argument's macro-expansion | ||
1873 | * (its length is `expand_length'). | ||
1874 | * `stringified_length' is the length the argument would have | ||
1875 | * if stringified. | ||
1876 | * `use_count' is the number of times this macro arg is substituted | ||
1877 | * into the macro. If the actual use count exceeds 10, | ||
1878 | * the value stored is 10. */ | ||
1879 | |||
1880 | /* raw and expanded are relative to ARG_BASE */ | ||
1881 | #define ARG_BASE ((pfile)->token_buffer) | ||
1882 | |||
1883 | struct argdata { | ||
1884 | /* Strings relative to pfile->token_buffer */ | ||
1885 | long raw, expanded, stringified; | ||
1886 | int raw_length, expand_length; | ||
1887 | int stringified_length; | ||
1888 | char newlines; | ||
1889 | char use_count; | ||
1890 | }; | ||
1891 | |||
1892 | cpp_buffer * | ||
1893 | cpp_push_buffer(cpp_reader * pfile, unsigned char *buffer, long length) | ||
1894 | { | ||
1895 | #ifdef STATIC_BUFFERS | ||
1896 | cpp_buffer *buf = CPP_BUFFER(pfile); | ||
1897 | |||
1898 | if (buf == pfile->buffer_stack) | ||
1899 | cpp_fatal("macro or `#include' recursion too deep"); | ||
1900 | buf--; | ||
1901 | memset((char *)buf, 0, sizeof(cpp_buffer)); | ||
1902 | CPP_BUFFER(pfile) = buf; | ||
1903 | #else | ||
1904 | cpp_buffer *buf = (cpp_buffer *) xmalloc(sizeof(cpp_buffer)); | ||
1905 | |||
1906 | memset((char *)buf, 0, sizeof(cpp_buffer)); | ||
1907 | CPP_PREV_BUFFER(buf) = CPP_BUFFER(pfile); | ||
1908 | CPP_BUFFER(pfile) = buf; | ||
1909 | #endif | ||
1910 | buf->if_stack = pfile->if_stack; | ||
1911 | buf->cleanup = null_cleanup; | ||
1912 | buf->underflow = null_underflow; | ||
1913 | buf->buf = buf->cur = buffer; | ||
1914 | buf->alimit = buf->rlimit = buffer + length; | ||
1915 | |||
1916 | return buf; | ||
1917 | } | ||
1918 | |||
1919 | static cpp_buffer * | ||
1920 | cpp_pop_buffer(cpp_reader * pfile) | ||
1921 | { | ||
1922 | cpp_buffer *buf = CPP_BUFFER(pfile); | ||
1923 | |||
1924 | #ifdef STATIC_BUFFERS | ||
1925 | (*buf->cleanup) (buf, pfile); | ||
1926 | return ++CPP_BUFFER(pfile); | ||
1927 | #else | ||
1928 | cpp_buffer *next_buf = CPP_PREV_BUFFER(buf); | ||
1929 | |||
1930 | (*buf->cleanup) (buf, pfile); | ||
1931 | CPP_BUFFER(pfile) = next_buf; | ||
1932 | free(buf); | ||
1933 | return next_buf; | ||
1934 | #endif | ||
1935 | } | ||
1936 | |||
1937 | /* Scan until CPP_BUFFER (PFILE) is exhausted into PFILE->token_buffer. | ||
1938 | * Pop the buffer when done. */ | ||
1939 | |||
1940 | static void | ||
1941 | cpp_scan_buffer(cpp_reader * pfile) | ||
1942 | { | ||
1943 | cpp_buffer *buffer = CPP_BUFFER(pfile); | ||
1944 | |||
1945 | for (;;) | ||
1946 | { | ||
1947 | enum cpp_token token = cpp_get_token(pfile); | ||
1948 | |||
1949 | if (token == CPP_EOF) /* Should not happen ... */ | ||
1950 | break; | ||
1951 | if (token == CPP_POP && CPP_BUFFER(pfile) == buffer) | ||
1952 | { | ||
1953 | cpp_pop_buffer(pfile); | ||
1954 | break; | ||
1955 | } | ||
1956 | } | ||
1957 | } | ||
1958 | |||
1959 | /* | ||
1960 | * Rescan a string (which may have escape marks) into pfile's buffer. | ||
1961 | * Place the result in pfile->token_buffer. | ||
1962 | * | ||
1963 | * The input is copied before it is scanned, so it is safe to pass | ||
1964 | * it something from the token_buffer that will get overwritten | ||
1965 | * (because it follows CPP_WRITTEN). This is used by do_include. | ||
1966 | */ | ||
1967 | |||
1968 | static void | ||
1969 | cpp_expand_to_buffer(cpp_reader * pfile, unsigned char *buf, int length) | ||
1970 | { | ||
1971 | cpp_buffer *ip; | ||
1972 | unsigned char *limit = buf + length; | ||
1973 | unsigned char *buf1; | ||
1974 | |||
1975 | if (length < 0) | ||
1976 | abort(); | ||
1977 | |||
1978 | /* Set up the input on the input stack. */ | ||
1979 | |||
1980 | buf1 = (unsigned char *)alloca(length + 1); | ||
1981 | { | ||
1982 | unsigned char *p1 = buf; | ||
1983 | unsigned char *p2 = buf1; | ||
1984 | int in_string = 0; | ||
1985 | |||
1986 | #if 0 /* old behavior */ | ||
1987 | while (p1 != limit) *p2++ = *p1++; | ||
1988 | #else /* new one - handle \ escapes if not in string */ | ||
1989 | while (p1 != limit) | ||
1990 | { | ||
1991 | if (!in_string) | ||
1992 | { | ||
1993 | if (*p1 == '"') in_string = 1; | ||
1994 | if (*p1 == '\\') | ||
1995 | { | ||
1996 | p1++; | ||
1997 | if (p1 != limit) *p2++ = *p1++; | ||
1998 | } | ||
1999 | else | ||
2000 | *p2++ = *p1++; | ||
2001 | } | ||
2002 | else | ||
2003 | { | ||
2004 | if ((*p1 == '"') && (p1 > buf) && (p1[-1] != '\\')) | ||
2005 | in_string = 0; | ||
2006 | *p2++ = *p1++; | ||
2007 | } | ||
2008 | } | ||
2009 | #endif | ||
2010 | *p2 = 0; | ||
2011 | length = p2 - buf1; | ||
2012 | } | ||
2013 | |||
2014 | ip = cpp_push_buffer(pfile, buf1, length); | ||
2015 | ip->has_escapes = 1; | ||
2016 | |||
2017 | /* Scan the input, create the output. */ | ||
2018 | cpp_scan_buffer(pfile); | ||
2019 | |||
2020 | CPP_NUL_TERMINATE(pfile); | ||
2021 | } | ||
2022 | |||
2023 | static void | ||
2024 | adjust_position(unsigned char *buf, unsigned char *limit, long *linep, | ||
2025 | long *colp) | ||
2026 | { | ||
2027 | while (buf < limit) | ||
2028 | { | ||
2029 | unsigned char ch = *buf++; | ||
2030 | |||
2031 | if (ch == '\n') | ||
2032 | (*linep)++, (*colp) = 1; | ||
2033 | else | ||
2034 | (*colp)++; | ||
2035 | } | ||
2036 | } | ||
2037 | |||
2038 | /* Move line_base forward, updating lineno and colno. */ | ||
2039 | |||
2040 | static void | ||
2041 | update_position(cpp_buffer * pbuf) | ||
2042 | { | ||
2043 | unsigned char *old_pos = pbuf->buf + pbuf->line_base; | ||
2044 | unsigned char *new_pos = pbuf->cur; | ||
2045 | struct parse_marker *mark; | ||
2046 | |||
2047 | for (mark = pbuf->marks; mark; mark = mark->next) | ||
2048 | { | ||
2049 | if (pbuf->buf + mark->position < new_pos) | ||
2050 | new_pos = pbuf->buf + mark->position; | ||
2051 | } | ||
2052 | pbuf->line_base += new_pos - old_pos; | ||
2053 | adjust_position(old_pos, new_pos, &pbuf->lineno, &pbuf->colno); | ||
2054 | } | ||
2055 | |||
2056 | void | ||
2057 | cpp_buf_line_and_col(cpp_buffer * pbuf, long *linep, long *colp) | ||
2058 | { | ||
2059 | long dummy; | ||
2060 | |||
2061 | if (!colp) | ||
2062 | colp = &dummy; | ||
2063 | if (pbuf) | ||
2064 | { | ||
2065 | *linep = pbuf->lineno; | ||
2066 | *colp = pbuf->colno; | ||
2067 | adjust_position(pbuf->buf + pbuf->line_base, pbuf->cur, linep, colp); | ||
2068 | } | ||
2069 | else | ||
2070 | { | ||
2071 | *linep = 0; | ||
2072 | *colp = 0; | ||
2073 | } | ||
2074 | } | ||
2075 | |||
2076 | /* Return the cpp_buffer that corresponds to a file (not a macro). */ | ||
2077 | |||
2078 | cpp_buffer * | ||
2079 | cpp_file_buffer(cpp_reader * pfile) | ||
2080 | { | ||
2081 | cpp_buffer *ip = CPP_BUFFER(pfile); | ||
2082 | |||
2083 | for (; ip != CPP_NULL_BUFFER(pfile); ip = CPP_PREV_BUFFER(ip)) | ||
2084 | if (ip->fname) | ||
2085 | return ip; | ||
2086 | return NULL; | ||
2087 | } | ||
2088 | |||
2089 | static long | ||
2090 | count_newlines(unsigned char *buf, unsigned char *limit) | ||
2091 | { | ||
2092 | long count = 0; | ||
2093 | |||
2094 | while (buf < limit) | ||
2095 | { | ||
2096 | unsigned char ch = *buf++; | ||
2097 | |||
2098 | if (ch == '\n') | ||
2099 | count++; | ||
2100 | } | ||
2101 | return count; | ||
2102 | } | ||
2103 | |||
2104 | /* | ||
2105 | * write out a #line command, for instance, after an #include file. | ||
2106 | * If CONDITIONAL is nonzero, we can omit the #line if it would | ||
2107 | * appear to be a no-op, and we can output a few newlines instead | ||
2108 | * if we want to increase the line number by a small amount. | ||
2109 | * FILE_CHANGE says whether we are entering a file, leaving, or neither. | ||
2110 | */ | ||
2111 | |||
2112 | static void | ||
2113 | output_line_command(cpp_reader * pfile, int conditional, | ||
2114 | enum file_change_code file_change) | ||
2115 | { | ||
2116 | long line, col; | ||
2117 | cpp_buffer *ip = CPP_BUFFER(pfile); | ||
2118 | |||
2119 | if (CPP_OPTIONS(pfile)->no_line_commands | ||
2120 | || !ip->fname || CPP_OPTIONS(pfile)->no_output) | ||
2121 | { | ||
2122 | return; | ||
2123 | } | ||
2124 | update_position(ip); | ||
2125 | line = CPP_BUFFER(pfile)->lineno; | ||
2126 | col = CPP_BUFFER(pfile)->colno; | ||
2127 | adjust_position(CPP_LINE_BASE(ip), ip->cur, &line, &col); | ||
2128 | |||
2129 | if (conditional) | ||
2130 | { | ||
2131 | if (line == pfile->lineno) | ||
2132 | return; | ||
2133 | |||
2134 | /* If the inherited line number is a little too small, | ||
2135 | * output some newlines instead of a #line command. */ | ||
2136 | if (line > pfile->lineno && line < pfile->lineno + 8) | ||
2137 | { | ||
2138 | CPP_RESERVE(pfile, 20); | ||
2139 | while (line > pfile->lineno) | ||
2140 | { | ||
2141 | CPP_PUTC_Q(pfile, '\n'); | ||
2142 | pfile->lineno++; | ||
2143 | } | ||
2144 | return; | ||
2145 | } | ||
2146 | } | ||
2147 | |||
2148 | CPP_RESERVE(pfile, 4 * strlen(ip->nominal_fname) + 50); | ||
2149 | { | ||
2150 | static char sharp_line[] = "#line "; | ||
2151 | |||
2152 | CPP_PUTS_Q(pfile, sharp_line, sizeof(sharp_line) - 1); | ||
2153 | } | ||
2154 | |||
2155 | sprintf((char *)CPP_PWRITTEN(pfile), "%d ", (int)line); | ||
2156 | CPP_ADJUST_WRITTEN(pfile, strlen((char *)CPP_PWRITTEN(pfile))); | ||
2157 | |||
2158 | quote_string(pfile, ip->nominal_fname); | ||
2159 | if (file_change != same_file) | ||
2160 | { | ||
2161 | CPP_PUTC_Q(pfile, ' '); | ||
2162 | CPP_PUTC_Q(pfile, file_change == enter_file ? '1' : '2'); | ||
2163 | } | ||
2164 | /* Tell cc1 if following text comes from a system header file. */ | ||
2165 | if (ip->system_header_p) | ||
2166 | { | ||
2167 | CPP_PUTC_Q(pfile, ' '); | ||
2168 | CPP_PUTC_Q(pfile, '3'); | ||
2169 | } | ||
2170 | #ifndef NO_IMPLICIT_EXTERN_C | ||
2171 | /* Tell cc1plus if following text should be treated as C. */ | ||
2172 | if (ip->system_header_p == 2 && CPP_OPTIONS(pfile)->cplusplus) | ||
2173 | { | ||
2174 | CPP_PUTC_Q(pfile, ' '); | ||
2175 | CPP_PUTC_Q(pfile, '4'); | ||
2176 | } | ||
2177 | #endif | ||
2178 | CPP_PUTC_Q(pfile, '\n'); | ||
2179 | pfile->lineno = line; | ||
2180 | } | ||
2181 | |||
2182 | /* | ||
2183 | * Parse a macro argument and append the info on PFILE's token_buffer. | ||
2184 | * REST_ARGS means to absorb the rest of the args. | ||
2185 | * Return nonzero to indicate a syntax error. | ||
2186 | */ | ||
2187 | |||
2188 | static enum cpp_token | ||
2189 | macarg(cpp_reader * pfile, int rest_args) | ||
2190 | { | ||
2191 | int paren = 0; | ||
2192 | enum cpp_token token; | ||
2193 | char save_put_out_comments = | ||
2194 | CPP_OPTIONS(pfile)->put_out_comments; | ||
2195 | |||
2196 | CPP_OPTIONS(pfile)->put_out_comments = 0; | ||
2197 | |||
2198 | token = CPP_OTHER; | ||
2199 | /* Try to parse as much of the argument as exists at this | ||
2200 | * input stack level. */ | ||
2201 | pfile->no_macro_expand++; | ||
2202 | for (;;) | ||
2203 | { | ||
2204 | token = cpp_get_token(pfile); | ||
2205 | switch (token) | ||
2206 | { | ||
2207 | case CPP_EOF: | ||
2208 | goto done; | ||
2209 | case CPP_POP: | ||
2210 | /* If we've hit end of file, it's an error (reported by caller). | ||
2211 | * Ditto if it's the end of cpp_expand_to_buffer text. | ||
2212 | * If we've hit end of macro, just continue. */ | ||
2213 | if (!CPP_IS_MACRO_BUFFER(CPP_BUFFER(pfile))) | ||
2214 | goto done; | ||
2215 | break; | ||
2216 | case CPP_LPAREN: | ||
2217 | paren++; | ||
2218 | break; | ||
2219 | case CPP_RPAREN: | ||
2220 | if (--paren < 0) | ||
2221 | goto found; | ||
2222 | break; | ||
2223 | case CPP_COMMA: | ||
2224 | /* if we've returned to lowest level and | ||
2225 | * we aren't absorbing all args */ | ||
2226 | if (paren == 0 && rest_args == 0) | ||
2227 | goto found; | ||
2228 | break; | ||
2229 | found: | ||
2230 | /* Remove ',' or ')' from argument buffer. */ | ||
2231 | CPP_ADJUST_WRITTEN(pfile, -1); | ||
2232 | goto done; | ||
2233 | default:; | ||
2234 | } | ||
2235 | } | ||
2236 | |||
2237 | done: | ||
2238 | CPP_OPTIONS(pfile)->put_out_comments = save_put_out_comments; | ||
2239 | pfile->no_macro_expand--; | ||
2240 | |||
2241 | return token; | ||
2242 | } | ||
2243 | |||
2244 | /* Turn newlines to spaces in the string of length LENGTH at START, | ||
2245 | * except inside of string constants. | ||
2246 | * The string is copied into itself with its beginning staying fixed. */ | ||
2247 | |||
2248 | static int | ||
2249 | change_newlines(unsigned char *start, int length) | ||
2250 | { | ||
2251 | unsigned char *ibp; | ||
2252 | unsigned char *obp; | ||
2253 | unsigned char *limit; | ||
2254 | int c; | ||
2255 | |||
2256 | ibp = start; | ||
2257 | limit = start + length; | ||
2258 | obp = start; | ||
2259 | |||
2260 | while (ibp < limit) | ||
2261 | { | ||
2262 | *obp++ = c = *ibp++; | ||
2263 | switch (c) | ||
2264 | { | ||
2265 | |||
2266 | case '\'': | ||
2267 | case '\"': | ||
2268 | /* Notice and skip strings, so that we don't delete newlines in them. */ | ||
2269 | { | ||
2270 | int quotec = c; | ||
2271 | |||
2272 | while (ibp < limit) | ||
2273 | { | ||
2274 | *obp++ = c = *ibp++; | ||
2275 | if (c == quotec) | ||
2276 | break; | ||
2277 | if (c == '\n' && quotec == '\'') | ||
2278 | break; | ||
2279 | } | ||
2280 | } | ||
2281 | break; | ||
2282 | } | ||
2283 | } | ||
2284 | |||
2285 | return obp - start; | ||
2286 | } | ||
2287 | |||
2288 | static struct tm * | ||
2289 | timestamp(cpp_reader * pfile) | ||
2290 | { | ||
2291 | if (!pfile->timebuf) | ||
2292 | { | ||
2293 | time_t t = time((time_t *) 0); | ||
2294 | |||
2295 | pfile->timebuf = localtime(&t); | ||
2296 | } | ||
2297 | return pfile->timebuf; | ||
2298 | } | ||
2299 | |||
2300 | static const char *monthnames[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", | ||
2301 | "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", | ||
2302 | }; | ||
2303 | |||
2304 | /* | ||
2305 | * expand things like __FILE__. Place the expansion into the output | ||
2306 | * buffer *without* rescanning. | ||
2307 | */ | ||
2308 | |||
2309 | static void | ||
2310 | special_symbol(HASHNODE * hp, cpp_reader * pfile) | ||
2311 | { | ||
2312 | const char *buf; | ||
2313 | char *bufx; | ||
2314 | int len; | ||
2315 | int true_indepth; | ||
2316 | cpp_buffer *ip = NULL; | ||
2317 | struct tm *timebuf; | ||
2318 | |||
2319 | int paren = 0; /* For special `defined' keyword */ | ||
2320 | |||
2321 | for (ip = CPP_BUFFER(pfile);; ip = CPP_PREV_BUFFER(ip)) | ||
2322 | { | ||
2323 | if (!ip) | ||
2324 | { | ||
2325 | cpp_error(pfile, "cccp error: not in any file?!"); | ||
2326 | return; /* the show must go on */ | ||
2327 | } | ||
2328 | if (ip->fname) | ||
2329 | break; | ||
2330 | } | ||
2331 | |||
2332 | switch (hp->type) | ||
2333 | { | ||
2334 | case T_FILE: | ||
2335 | case T_BASE_FILE: | ||
2336 | { | ||
2337 | const char *string; | ||
2338 | |||
2339 | if (hp->type == T_BASE_FILE) | ||
2340 | { | ||
2341 | while (CPP_PREV_BUFFER(ip)) | ||
2342 | ip = CPP_PREV_BUFFER(ip); | ||
2343 | } | ||
2344 | string = ip->nominal_fname; | ||
2345 | |||
2346 | if (!string) | ||
2347 | string = ""; | ||
2348 | CPP_RESERVE(pfile, 3 + 4 * strlen(string)); | ||
2349 | quote_string(pfile, string); | ||
2350 | return; | ||
2351 | } | ||
2352 | |||
2353 | case T_INCLUDE_LEVEL: | ||
2354 | true_indepth = 0; | ||
2355 | for (ip = CPP_BUFFER(pfile); ip; ip = CPP_PREV_BUFFER(ip)) | ||
2356 | if (ip->fname) | ||
2357 | true_indepth++; | ||
2358 | |||
2359 | bufx = (char *)alloca(8); /* Eight bytes ought to be more than enough */ | ||
2360 | sprintf(bufx, "%d", true_indepth - 1); | ||
2361 | buf = bufx; | ||
2362 | break; | ||
2363 | |||
2364 | case T_VERSION: | ||
2365 | bufx = (char *)alloca(3 + strlen(version_string)); | ||
2366 | sprintf(bufx, "\"%s\"", version_string); | ||
2367 | buf = bufx; | ||
2368 | break; | ||
2369 | |||
2370 | #ifndef NO_BUILTIN_SIZE_TYPE | ||
2371 | case T_SIZE_TYPE: | ||
2372 | buf = SIZE_TYPE; | ||
2373 | break; | ||
2374 | #endif | ||
2375 | |||
2376 | #ifndef NO_BUILTIN_PTRDIFF_TYPE | ||
2377 | case T_PTRDIFF_TYPE: | ||
2378 | buf = PTRDIFF_TYPE; | ||
2379 | break; | ||
2380 | #endif | ||
2381 | |||
2382 | case T_WCHAR_TYPE: | ||
2383 | buf = CPP_WCHAR_TYPE(pfile); | ||
2384 | break; | ||
2385 | |||
2386 | case T_USER_LABEL_PREFIX_TYPE: | ||
2387 | buf = USER_LABEL_PREFIX; | ||
2388 | break; | ||
2389 | |||
2390 | case T_REGISTER_PREFIX_TYPE: | ||
2391 | buf = REGISTER_PREFIX; | ||
2392 | break; | ||
2393 | |||
2394 | case T_CONST: | ||
2395 | bufx = (char *)alloca(4 * sizeof(int)); | ||
2396 | sprintf(bufx, "%d", hp->value.ival); | ||
2397 | buf = bufx; | ||
2398 | break; | ||
2399 | |||
2400 | case T_SPECLINE: | ||
2401 | { | ||
2402 | long line = ip->lineno; | ||
2403 | long col = ip->colno; | ||
2404 | |||
2405 | adjust_position(CPP_LINE_BASE(ip), ip->cur, &line, &col); | ||
2406 | |||
2407 | bufx = (char *)alloca(10); | ||
2408 | sprintf(bufx, "%d", (int)line); | ||
2409 | buf = bufx; | ||
2410 | } | ||
2411 | break; | ||
2412 | |||
2413 | case T_DATE: | ||
2414 | case T_TIME: | ||
2415 | bufx = (char *)alloca(20); | ||
2416 | timebuf = timestamp(pfile); | ||
2417 | if (hp->type == T_DATE) | ||
2418 | sprintf(bufx, "\"%s %2d %4d\"", monthnames[timebuf->tm_mon], | ||
2419 | timebuf->tm_mday, timebuf->tm_year + 1900); | ||
2420 | else | ||
2421 | sprintf(bufx, "\"%02d:%02d:%02d\"", timebuf->tm_hour, | ||
2422 | timebuf->tm_min, timebuf->tm_sec); | ||
2423 | buf = bufx; | ||
2424 | break; | ||
2425 | |||
2426 | case T_SPEC_DEFINED: | ||
2427 | buf = " 0 "; /* Assume symbol is not defined */ | ||
2428 | ip = CPP_BUFFER(pfile); | ||
2429 | SKIP_WHITE_SPACE(ip->cur); | ||
2430 | if (*ip->cur == '(') | ||
2431 | { | ||
2432 | paren++; | ||
2433 | ip->cur++; /* Skip over the paren */ | ||
2434 | SKIP_WHITE_SPACE(ip->cur); | ||
2435 | } | ||
2436 | if (!is_idstart[*ip->cur]) | ||
2437 | goto oops; | ||
2438 | if ((hp = cpp_lookup((const char *)ip->cur, -1, -1))) | ||
2439 | { | ||
2440 | buf = " 1 "; | ||
2441 | } | ||
2442 | while (is_idchar[*ip->cur]) | ||
2443 | ++ip->cur; | ||
2444 | SKIP_WHITE_SPACE(ip->cur); | ||
2445 | if (paren) | ||
2446 | { | ||
2447 | if (*ip->cur != ')') | ||
2448 | goto oops; | ||
2449 | ++ip->cur; | ||
2450 | } | ||
2451 | break; | ||
2452 | |||
2453 | oops: | ||
2454 | |||
2455 | cpp_error(pfile, "`defined' without an identifier"); | ||
2456 | break; | ||
2457 | |||
2458 | default: | ||
2459 | cpp_error(pfile, "cccp error: invalid special hash type"); /* time for gdb */ | ||
2460 | abort(); | ||
2461 | } | ||
2462 | len = strlen(buf); | ||
2463 | CPP_RESERVE(pfile, len + 1); | ||
2464 | CPP_PUTS_Q(pfile, buf, len); | ||
2465 | CPP_NUL_TERMINATE_Q(pfile); | ||
2466 | |||
2467 | return; | ||
2468 | } | ||
2469 | |||
2470 | /* Initialize the built-in macros. */ | ||
2471 | |||
2472 | static void | ||
2473 | initialize_builtins(cpp_reader * pfile) | ||
2474 | { | ||
2475 | install("__LINE__", -1, T_SPECLINE, 0, 0, -1); | ||
2476 | install("__DATE__", -1, T_DATE, 0, 0, -1); | ||
2477 | install("__FILE__", -1, T_FILE, 0, 0, -1); | ||
2478 | install("__BASE_FILE__", -1, T_BASE_FILE, 0, 0, -1); | ||
2479 | install("__INCLUDE_LEVEL__", -1, T_INCLUDE_LEVEL, 0, 0, -1); | ||
2480 | install("__VERSION__", -1, T_VERSION, 0, 0, -1); | ||
2481 | #ifndef NO_BUILTIN_SIZE_TYPE | ||
2482 | install("__SIZE_TYPE__", -1, T_SIZE_TYPE, 0, 0, -1); | ||
2483 | #endif | ||
2484 | #ifndef NO_BUILTIN_PTRDIFF_TYPE | ||
2485 | install("__PTRDIFF_TYPE__ ", -1, T_PTRDIFF_TYPE, 0, 0, -1); | ||
2486 | #endif | ||
2487 | install("__WCHAR_TYPE__", -1, T_WCHAR_TYPE, 0, 0, -1); | ||
2488 | install("__USER_LABEL_PREFIX__", -1, T_USER_LABEL_PREFIX_TYPE, 0, 0, -1); | ||
2489 | install("__REGISTER_PREFIX__", -1, T_REGISTER_PREFIX_TYPE, 0, 0, -1); | ||
2490 | install("__TIME__", -1, T_TIME, 0, 0, -1); | ||
2491 | install("__STDC__", -1, T_CONST, STDC_VALUE, 0, -1); | ||
2492 | if (CPP_OPTIONS(pfile)->objc) | ||
2493 | install("__OBJC__", -1, T_CONST, 1, 0, -1); | ||
2494 | /* This is supplied using a -D by the compiler driver | ||
2495 | * so that it is present only when truly compiling with GNU C. */ | ||
2496 | /* install ("__GNUC__", -1, T_CONST, 2, 0, -1); */ | ||
2497 | |||
2498 | if (CPP_OPTIONS(pfile)->debug_output) | ||
2499 | { | ||
2500 | char directive[2048]; | ||
2501 | struct directive *dp = &directive_table[0]; | ||
2502 | struct tm *timebuf = timestamp(pfile); | ||
2503 | cpp_buffer *pbuffer = CPP_BUFFER(pfile); | ||
2504 | |||
2505 | while (CPP_PREV_BUFFER(pbuffer)) | ||
2506 | pbuffer = CPP_PREV_BUFFER(pbuffer); | ||
2507 | sprintf(directive, " __BASE_FILE__ \"%s\"\n", pbuffer->nominal_fname); | ||
2508 | output_line_command(pfile, 0, same_file); | ||
2509 | pass_thru_directive(directive, &directive[strlen(directive)], pfile, | ||
2510 | dp); | ||
2511 | |||
2512 | sprintf(directive, " __VERSION__ \"%s\"\n", version_string); | ||
2513 | output_line_command(pfile, 0, same_file); | ||
2514 | pass_thru_directive(directive, &directive[strlen(directive)], pfile, | ||
2515 | dp); | ||
2516 | |||
2517 | #ifndef NO_BUILTIN_SIZE_TYPE | ||
2518 | sprintf(directive, " __SIZE_TYPE__ %s\n", SIZE_TYPE); | ||
2519 | output_line_command(pfile, 0, same_file); | ||
2520 | pass_thru_directive(directive, &directive[strlen(directive)], pfile, | ||
2521 | dp); | ||
2522 | #endif | ||
2523 | |||
2524 | #ifndef NO_BUILTIN_PTRDIFF_TYPE | ||
2525 | sprintf(directive, " __PTRDIFF_TYPE__ %s\n", PTRDIFF_TYPE); | ||
2526 | output_line_command(pfile, 0, same_file); | ||
2527 | pass_thru_directive(directive, &directive[strlen(directive)], pfile, | ||
2528 | dp); | ||
2529 | #endif | ||
2530 | |||
2531 | sprintf(directive, " __WCHAR_TYPE__ %s\n", CPP_WCHAR_TYPE(pfile)); | ||
2532 | output_line_command(pfile, 0, same_file); | ||
2533 | pass_thru_directive(directive, &directive[strlen(directive)], pfile, | ||
2534 | dp); | ||
2535 | |||
2536 | sprintf(directive, " __DATE__ \"%s %2d %4d\"\n", | ||
2537 | monthnames[timebuf->tm_mon], | ||
2538 | timebuf->tm_mday, timebuf->tm_year + 1900); | ||
2539 | output_line_command(pfile, 0, same_file); | ||
2540 | pass_thru_directive(directive, &directive[strlen(directive)], pfile, | ||
2541 | dp); | ||
2542 | |||
2543 | sprintf(directive, " __TIME__ \"%02d:%02d:%02d\"\n", | ||
2544 | timebuf->tm_hour, timebuf->tm_min, timebuf->tm_sec); | ||
2545 | output_line_command(pfile, 0, same_file); | ||
2546 | pass_thru_directive(directive, &directive[strlen(directive)], pfile, | ||
2547 | dp); | ||
2548 | |||
2549 | sprintf(directive, " __STDC__ 1"); | ||
2550 | output_line_command(pfile, 0, same_file); | ||
2551 | pass_thru_directive(directive, &directive[strlen(directive)], | ||
2552 | pfile, dp); | ||
2553 | } | ||
2554 | } | ||
2555 | |||
2556 | /* Return 1 iff a token ending in C1 followed directly by a token C2 | ||
2557 | * could cause mis-tokenization. */ | ||
2558 | |||
2559 | static int | ||
2560 | unsafe_chars(int c1, int c2) | ||
2561 | { | ||
2562 | // printf("unsafe %c %c ...", c1, c2); | ||
2563 | switch (c1) | ||
2564 | { | ||
2565 | case '+': | ||
2566 | case '-': | ||
2567 | case '.': | ||
2568 | // printf(" no0\n"); | ||
2569 | return 0; | ||
2570 | case '0': | ||
2571 | case '1': | ||
2572 | case '2': | ||
2573 | case '3': | ||
2574 | case '4': | ||
2575 | case '5': | ||
2576 | case '6': | ||
2577 | case '7': | ||
2578 | case '8': | ||
2579 | case '9': | ||
2580 | case 'e': | ||
2581 | case 'E': | ||
2582 | if (c2 == '-' || c2 == '+') | ||
2583 | { | ||
2584 | // printf(" yes2\n"); | ||
2585 | return 1; /* could extend a pre-processing number */ | ||
2586 | } | ||
2587 | goto letter; | ||
2588 | case 'L': | ||
2589 | if (c2 == '\'' || c2 == '\"') | ||
2590 | { | ||
2591 | // printf(" yes3\n"); | ||
2592 | return 1; /* Could turn into L"xxx" or L'xxx'. */ | ||
2593 | } | ||
2594 | goto letter; | ||
2595 | letter: | ||
2596 | case '_': | ||
2597 | case 'a': | ||
2598 | case 'b': | ||
2599 | case 'c': | ||
2600 | case 'd': | ||
2601 | case 'f': | ||
2602 | case 'g': | ||
2603 | case 'h': | ||
2604 | case 'i': | ||
2605 | case 'j': | ||
2606 | case 'k': | ||
2607 | case 'l': | ||
2608 | case 'm': | ||
2609 | case 'n': | ||
2610 | case 'o': | ||
2611 | case 'p': | ||
2612 | case 'q': | ||
2613 | case 'r': | ||
2614 | case 's': | ||
2615 | case 't': | ||
2616 | case 'u': | ||
2617 | case 'v': | ||
2618 | case 'w': | ||
2619 | case 'x': | ||
2620 | case 'y': | ||
2621 | case 'z': | ||
2622 | case 'A': | ||
2623 | case 'B': | ||
2624 | case 'C': | ||
2625 | case 'D': | ||
2626 | case 'F': | ||
2627 | case 'G': | ||
2628 | case 'H': | ||
2629 | case 'I': | ||
2630 | case 'J': | ||
2631 | case 'K': | ||
2632 | case 'M': | ||
2633 | case 'N': | ||
2634 | case 'O': | ||
2635 | case 'P': | ||
2636 | case 'Q': | ||
2637 | case 'R': | ||
2638 | case 'S': | ||
2639 | case 'T': | ||
2640 | case 'U': | ||
2641 | case 'V': | ||
2642 | case 'W': | ||
2643 | case 'X': | ||
2644 | case 'Y': | ||
2645 | case 'Z': | ||
2646 | /* We're in the middle of either a name or a pre-processing number. */ | ||
2647 | if (is_idchar[c2] || c2 == '.') | ||
2648 | { | ||
2649 | // printf(" yes4 %i %i\n", is_idchar[c2], c2 == '.'); | ||
2650 | return 1; | ||
2651 | } | ||
2652 | else | ||
2653 | { | ||
2654 | // printf(" no5\n"); | ||
2655 | return 0; | ||
2656 | } | ||
2657 | case '<': | ||
2658 | case '>': | ||
2659 | case '!': | ||
2660 | case '%': | ||
2661 | case '#': | ||
2662 | case ':': | ||
2663 | case '^': | ||
2664 | case '&': | ||
2665 | case '|': | ||
2666 | case '*': | ||
2667 | case '/': | ||
2668 | case '=': | ||
2669 | if (c2 == c1 || c2 == '=') | ||
2670 | { | ||
2671 | // printf(" yes6\n"); | ||
2672 | return 1; | ||
2673 | } | ||
2674 | else | ||
2675 | { | ||
2676 | // printf(" no7\n"); | ||
2677 | return 0; | ||
2678 | } | ||
2679 | } | ||
2680 | // printf(" no8\n"); | ||
2681 | return 0; | ||
2682 | } | ||
2683 | |||
2684 | /* Expand a macro call. | ||
2685 | * HP points to the symbol that is the macro being called. | ||
2686 | * Put the result of expansion onto the input stack | ||
2687 | * so that subsequent input by our caller will use it. | ||
2688 | * | ||
2689 | * If macro wants arguments, caller has already verified that | ||
2690 | * an argument list follows; arguments come from the input stack. */ | ||
2691 | |||
2692 | static void | ||
2693 | macroexpand(cpp_reader * pfile, HASHNODE * hp) | ||
2694 | { | ||
2695 | int nargs; | ||
2696 | DEFINITION *defn = hp->value.defn; | ||
2697 | unsigned char *xbuf; | ||
2698 | long start_line, start_column; | ||
2699 | int xbuf_len; | ||
2700 | struct argdata *args; | ||
2701 | long old_written = CPP_WRITTEN(pfile); | ||
2702 | |||
2703 | int rest_args, rest_zero; | ||
2704 | int i; | ||
2705 | |||
2706 | pfile->output_escapes++; | ||
2707 | cpp_buf_line_and_col(cpp_file_buffer(pfile), &start_line, &start_column); | ||
2708 | |||
2709 | rest_zero = 0; | ||
2710 | args = NULL; | ||
2711 | nargs = defn->nargs; | ||
2712 | |||
2713 | if (nargs >= 0) | ||
2714 | { | ||
2715 | enum cpp_token token; | ||
2716 | |||
2717 | token = CPP_OTHER; | ||
2718 | |||
2719 | args = (struct argdata *)alloca((nargs + 1) * sizeof(struct argdata)); | ||
2720 | |||
2721 | for (i = 0; i < nargs; i++) | ||
2722 | { | ||
2723 | args[i].raw = args[i].expanded = 0; | ||
2724 | args[i].raw_length = 0; | ||
2725 | args[i].expand_length = args[i].stringified_length = -1; | ||
2726 | args[i].use_count = 0; | ||
2727 | } | ||
2728 | |||
2729 | /* Parse all the macro args that are supplied. I counts them. | ||
2730 | * The first NARGS args are stored in ARGS. | ||
2731 | * The rest are discarded. If rest_args is set then we assume | ||
2732 | * macarg absorbed the rest of the args. */ | ||
2733 | i = 0; | ||
2734 | rest_args = 0; | ||
2735 | rest_args = 0; | ||
2736 | FORWARD(1); /* Discard the open-parenthesis before the first arg. */ | ||
2737 | do | ||
2738 | { | ||
2739 | if (rest_args) | ||
2740 | continue; | ||
2741 | if (i < nargs || (nargs == 0 && i == 0)) | ||
2742 | { | ||
2743 | unsigned char *bp; | ||
2744 | |||
2745 | /* if we are working on last arg which absorbs rest of args... */ | ||
2746 | if (i == nargs - 1 && defn->rest_args) | ||
2747 | rest_args = 1; | ||
2748 | args[i].raw = CPP_WRITTEN(pfile); | ||
2749 | token = macarg(pfile, rest_args); | ||
2750 | args[i].raw_length = CPP_WRITTEN(pfile) - args[i].raw; | ||
2751 | args[i].newlines = 0; /* FIXME */ | ||
2752 | bp = ARG_BASE + args[i].raw; | ||
2753 | while (is_space[(unsigned char)(*bp)]) { bp++; } | ||
2754 | args[i].raw_length -= bp - (ARG_BASE + args[i].raw); | ||
2755 | args[i].raw = bp - ARG_BASE; | ||
2756 | if (args[i].raw_length > 0) | ||
2757 | { | ||
2758 | bp = ARG_BASE + args[i].raw + args[i].raw_length - 1; | ||
2759 | while (is_space[(unsigned char)(*bp)]) | ||
2760 | { | ||
2761 | bp--; | ||
2762 | args[i].raw_length--; | ||
2763 | if (args[i].raw_length < 1) break; | ||
2764 | } | ||
2765 | } | ||
2766 | } | ||
2767 | else | ||
2768 | token = macarg(pfile, 0); | ||
2769 | if (token == CPP_EOF || token == CPP_POP) | ||
2770 | { | ||
2771 | cpp_error_with_line(pfile, start_line, start_column, | ||
2772 | "unterminated macro call"); | ||
2773 | return; | ||
2774 | } | ||
2775 | i++; | ||
2776 | } | ||
2777 | while (token == CPP_COMMA); | ||
2778 | |||
2779 | /* If we got one arg but it was just whitespace, call that 0 args. */ | ||
2780 | if (i == 1) | ||
2781 | { | ||
2782 | unsigned char *bp = ARG_BASE + args[0].raw; | ||
2783 | unsigned char *lim = bp + args[0].raw_length; | ||
2784 | |||
2785 | /* cpp.texi says for foo ( ) we provide one argument. | ||
2786 | * However, if foo wants just 0 arguments, treat this as 0. */ | ||
2787 | if (nargs == 0) | ||
2788 | while (bp != lim && is_space[*bp]) | ||
2789 | bp++; | ||
2790 | if (bp == lim) | ||
2791 | i = 0; | ||
2792 | } | ||
2793 | /* Don't output an error message if we have already output one for | ||
2794 | * a parse error above. */ | ||
2795 | if (nargs == 0 && i > 0) | ||
2796 | { | ||
2797 | cpp_error(pfile, "arguments given to macro `%s'", hp->name); | ||
2798 | } | ||
2799 | else if (i < nargs) | ||
2800 | { | ||
2801 | if (i == nargs - 1 && defn->rest_args) | ||
2802 | rest_zero = 1; | ||
2803 | else if (i == 0) | ||
2804 | cpp_error(pfile, "macro `%s' used without args", hp->name); | ||
2805 | else if (i == 1) | ||
2806 | cpp_error(pfile, "macro `%s' used with just one arg", hp->name); | ||
2807 | else | ||
2808 | cpp_error(pfile, "macro `%s' used with only %d args", | ||
2809 | hp->name, i); | ||
2810 | } | ||
2811 | else if (i > nargs) | ||
2812 | { | ||
2813 | cpp_error(pfile, | ||
2814 | "macro `%s' used with too many (%d) args", hp->name, i); | ||
2815 | } | ||
2816 | } | ||
2817 | /* If macro wants zero args, we parsed the arglist for checking only. | ||
2818 | * Read directly from the macro definition. */ | ||
2819 | if (nargs <= 0) | ||
2820 | { | ||
2821 | xbuf = defn->expansion; | ||
2822 | xbuf_len = defn->length; | ||
2823 | } | ||
2824 | else | ||
2825 | { | ||
2826 | unsigned char *exp = defn->expansion; | ||
2827 | int offset; /* offset in expansion, | ||
2828 | * copied a piece at a time */ | ||
2829 | int totlen; /* total amount of exp buffer filled so far */ | ||
2830 | reflist *ap, *last_ap; | ||
2831 | |||
2832 | /* Macro really takes args. Compute the expansion of this call. */ | ||
2833 | |||
2834 | /* Compute length in characters of the macro's expansion. | ||
2835 | * Also count number of times each arg is used. */ | ||
2836 | xbuf_len = defn->length; | ||
2837 | for (ap = defn->pattern; ap; ap = ap->next) | ||
2838 | { | ||
2839 | if (ap->stringify) | ||
2840 | { | ||
2841 | struct argdata *arg = &args[ap->argno]; | ||
2842 | |||
2843 | /* Stringify it it hasn't already been */ | ||
2844 | if (arg->stringified_length < 0) | ||
2845 | { | ||
2846 | int arglen = arg->raw_length; | ||
2847 | int escaped = 0; | ||
2848 | int in_string = 0; | ||
2849 | int c; | ||
2850 | |||
2851 | /* Initially need_space is -1. Otherwise, 1 means the | ||
2852 | * previous character was a space, but we suppressed it; | ||
2853 | * 0 means the previous character was a non-space. */ | ||
2854 | int need_space = -1; | ||
2855 | |||
2856 | i = 0; | ||
2857 | arg->stringified = CPP_WRITTEN(pfile); | ||
2858 | CPP_PUTC(pfile, '\"'); /* insert beginning quote */ | ||
2859 | for (; i < arglen; i++) | ||
2860 | { | ||
2861 | c = (ARG_BASE + arg->raw)[i]; | ||
2862 | |||
2863 | if (!in_string) | ||
2864 | { | ||
2865 | /* Internal sequences of whitespace are replaced by | ||
2866 | * one space except within an string or char token. */ | ||
2867 | if (is_space[c]) | ||
2868 | { | ||
2869 | if (CPP_WRITTEN(pfile) > arg->stringified | ||
2870 | && (CPP_PWRITTEN(pfile))[-1] == '@') | ||
2871 | { | ||
2872 | /* "@ " escape markers are removed */ | ||
2873 | CPP_ADJUST_WRITTEN(pfile, -1); | ||
2874 | continue; | ||
2875 | } | ||
2876 | if (need_space == 0) | ||
2877 | need_space = 1; | ||
2878 | continue; | ||
2879 | } | ||
2880 | else if (need_space > 0) | ||
2881 | CPP_PUTC(pfile, ' '); | ||
2882 | need_space = 0; | ||
2883 | } | ||
2884 | if (escaped) | ||
2885 | escaped = 0; | ||
2886 | else | ||
2887 | { | ||
2888 | if (c == '\\') | ||
2889 | escaped = 1; | ||
2890 | if (in_string) | ||
2891 | { | ||
2892 | if (c == in_string) | ||
2893 | in_string = 0; | ||
2894 | } | ||
2895 | else if (c == '\"' || c == '\'') | ||
2896 | in_string = c; | ||
2897 | } | ||
2898 | |||
2899 | /* Escape these chars */ | ||
2900 | if (c == '\"' || (in_string && c == '\\')) | ||
2901 | CPP_PUTC(pfile, '\\'); | ||
2902 | if (isprint(c)) | ||
2903 | CPP_PUTC(pfile, c); | ||
2904 | else | ||
2905 | { | ||
2906 | CPP_RESERVE(pfile, 4); | ||
2907 | sprintf((char *)CPP_PWRITTEN(pfile), "\\%03o", | ||
2908 | (unsigned int)c); | ||
2909 | CPP_ADJUST_WRITTEN(pfile, 4); | ||
2910 | } | ||
2911 | } | ||
2912 | CPP_PUTC(pfile, '\"'); /* insert ending quote */ | ||
2913 | arg->stringified_length | ||
2914 | = CPP_WRITTEN(pfile) - arg->stringified; | ||
2915 | } | ||
2916 | xbuf_len += args[ap->argno].stringified_length; | ||
2917 | } | ||
2918 | else if (ap->raw_before || ap->raw_after) | ||
2919 | { | ||
2920 | /* Add 4 for two newline-space markers to prevent | ||
2921 | * token concatenation. */ | ||
2922 | xbuf_len += args[ap->argno].raw_length + 4; | ||
2923 | } | ||
2924 | else | ||
2925 | { | ||
2926 | /* We have an ordinary (expanded) occurrence of the arg. | ||
2927 | * So compute its expansion, if we have not already. */ | ||
2928 | if (args[ap->argno].expand_length < 0) | ||
2929 | { | ||
2930 | args[ap->argno].expanded = CPP_WRITTEN(pfile); | ||
2931 | cpp_expand_to_buffer(pfile, | ||
2932 | ARG_BASE + args[ap->argno].raw, | ||
2933 | args[ap->argno].raw_length); | ||
2934 | |||
2935 | args[ap->argno].expand_length | ||
2936 | = CPP_WRITTEN(pfile) - args[ap->argno].expanded; | ||
2937 | } | ||
2938 | /* Add 4 for two newline-space markers to prevent | ||
2939 | * token concatenation. */ | ||
2940 | xbuf_len += args[ap->argno].expand_length + 4; | ||
2941 | } | ||
2942 | if (args[ap->argno].use_count < 10) | ||
2943 | args[ap->argno].use_count++; | ||
2944 | } | ||
2945 | |||
2946 | xbuf = (unsigned char *)xmalloc(xbuf_len + 1); | ||
2947 | |||
2948 | /* Generate in XBUF the complete expansion | ||
2949 | * with arguments substituted in. | ||
2950 | * TOTLEN is the total size generated so far. | ||
2951 | * OFFSET is the index in the definition | ||
2952 | * of where we are copying from. */ | ||
2953 | offset = totlen = 0; | ||
2954 | for (last_ap = NULL, ap = defn->pattern; ap; | ||
2955 | last_ap = ap, ap = ap->next) | ||
2956 | { | ||
2957 | struct argdata *arg = &args[ap->argno]; | ||
2958 | int count_before = totlen; | ||
2959 | |||
2960 | /* Add chars to XBUF. */ | ||
2961 | for (i = 0; i < ap->nchars; i++, offset++) | ||
2962 | xbuf[totlen++] = exp[offset]; | ||
2963 | |||
2964 | /* If followed by an empty rest arg with concatenation, | ||
2965 | * delete the last run of nonwhite chars. */ | ||
2966 | if (rest_zero && totlen > count_before | ||
2967 | && ((ap->rest_args && ap->raw_before) | ||
2968 | || (last_ap && last_ap->rest_args && last_ap->raw_after))) | ||
2969 | { | ||
2970 | /* Delete final whitespace. */ | ||
2971 | while (totlen > count_before && is_space[xbuf[totlen - 1]]) | ||
2972 | totlen--; | ||
2973 | |||
2974 | /* Delete the nonwhites before them. */ | ||
2975 | while (totlen > count_before && !is_space[xbuf[totlen - 1]]) | ||
2976 | totlen--; | ||
2977 | } | ||
2978 | if (ap->stringify != 0) | ||
2979 | { | ||
2980 | memcpy(xbuf + totlen, ARG_BASE + arg->stringified, | ||
2981 | arg->stringified_length); | ||
2982 | totlen += arg->stringified_length; | ||
2983 | } | ||
2984 | else if (ap->raw_before || ap->raw_after) | ||
2985 | { | ||
2986 | unsigned char *p1 = ARG_BASE + arg->raw; | ||
2987 | unsigned char *l1 = p1 + arg->raw_length; | ||
2988 | |||
2989 | if (ap->raw_before) | ||
2990 | { | ||
2991 | while (p1 != l1 && is_space[*p1]) | ||
2992 | p1++; | ||
2993 | while (p1 != l1 && is_idchar[*p1]) | ||
2994 | xbuf[totlen++] = *p1++; | ||
2995 | } | ||
2996 | if (ap->raw_after) | ||
2997 | { | ||
2998 | /* Arg is concatenated after: delete trailing whitespace, | ||
2999 | * whitespace markers, and no-reexpansion markers. */ | ||
3000 | while (p1 != l1) | ||
3001 | { | ||
3002 | if (is_space[l1[-1]]) | ||
3003 | l1--; | ||
3004 | else if (l1[-1] == '-') | ||
3005 | { | ||
3006 | unsigned char *p2 = l1 - 1; | ||
3007 | |||
3008 | /* If a `-' is preceded by an odd number of newlines then it | ||
3009 | * and the last newline are a no-reexpansion marker. */ | ||
3010 | while (p2 != p1 && p2[-1] == '\n') | ||
3011 | p2--; | ||
3012 | if ((l1 - 1 - p2) & 1) | ||
3013 | { | ||
3014 | l1 -= 2; | ||
3015 | } | ||
3016 | else | ||
3017 | break; | ||
3018 | } | ||
3019 | else | ||
3020 | break; | ||
3021 | } | ||
3022 | } | ||
3023 | memcpy(xbuf + totlen, p1, l1 - p1); | ||
3024 | totlen += l1 - p1; | ||
3025 | } | ||
3026 | else | ||
3027 | { | ||
3028 | unsigned char *expanded = ARG_BASE + arg->expanded; | ||
3029 | |||
3030 | if (!ap->raw_before && totlen > 0 && arg->expand_length | ||
3031 | && unsafe_chars(xbuf[totlen - 1], expanded[0])) | ||
3032 | { | ||
3033 | xbuf[totlen++] = '@'; | ||
3034 | xbuf[totlen++] = ' '; | ||
3035 | } | ||
3036 | memcpy(xbuf + totlen, expanded, arg->expand_length); | ||
3037 | totlen += arg->expand_length; | ||
3038 | |||
3039 | if (!ap->raw_after && totlen > 0 && offset < defn->length | ||
3040 | && unsafe_chars(xbuf[totlen - 1], exp[offset])) | ||
3041 | { | ||
3042 | xbuf[totlen++] = '@'; | ||
3043 | xbuf[totlen++] = ' '; | ||
3044 | } | ||
3045 | /* If a macro argument with newlines is used multiple times, | ||
3046 | * then only expand the newlines once. This avoids creating | ||
3047 | * output lines which don't correspond to any input line, | ||
3048 | * which confuses gdb and gcov. */ | ||
3049 | if (arg->use_count > 1 && arg->newlines > 0) | ||
3050 | { | ||
3051 | /* Don't bother doing change_newlines for subsequent | ||
3052 | * uses of arg. */ | ||
3053 | arg->use_count = 1; | ||
3054 | arg->expand_length | ||
3055 | = change_newlines(expanded, arg->expand_length); | ||
3056 | } | ||
3057 | } | ||
3058 | |||
3059 | if (totlen > xbuf_len) | ||
3060 | abort(); | ||
3061 | } | ||
3062 | /* if there is anything left of the definition | ||
3063 | * after handling the arg list, copy that in too. */ | ||
3064 | |||
3065 | for (i = offset; i < defn->length; i++) | ||
3066 | { | ||
3067 | /* if we've reached the end of the macro */ | ||
3068 | if (exp[i] == ')') | ||
3069 | rest_zero = 0; | ||
3070 | if (!(rest_zero && last_ap && last_ap->rest_args | ||
3071 | && last_ap->raw_after)) | ||
3072 | xbuf[totlen++] = exp[i]; | ||
3073 | } | ||
3074 | |||
3075 | xbuf[totlen] = 0; | ||
3076 | xbuf_len = totlen; | ||
3077 | } | ||
3078 | |||
3079 | pfile->output_escapes--; | ||
3080 | |||
3081 | /* Now put the expansion on the input stack | ||
3082 | * so our caller will commence reading from it. */ | ||
3083 | push_macro_expansion(pfile, xbuf, xbuf_len, hp); | ||
3084 | CPP_BUFFER(pfile)->has_escapes = 1; | ||
3085 | |||
3086 | /* Pop the space we've used in the token_buffer for argument expansion. */ | ||
3087 | CPP_SET_WRITTEN(pfile, old_written); | ||
3088 | |||
3089 | /* Recursive macro use sometimes works traditionally. | ||
3090 | * #define foo(x,y) bar (x (y,0), y) | ||
3091 | * foo (foo, baz) */ | ||
3092 | |||
3093 | hp->type = T_DISABLED; | ||
3094 | } | ||
3095 | |||
3096 | static void | ||
3097 | push_macro_expansion(cpp_reader * pfile, unsigned char *xbuf, int xbuf_len, | ||
3098 | HASHNODE * hp) | ||
3099 | { | ||
3100 | cpp_buffer *mbuf = cpp_push_buffer(pfile, xbuf, xbuf_len); | ||
3101 | |||
3102 | mbuf->cleanup = macro_cleanup; | ||
3103 | mbuf->data = hp; | ||
3104 | |||
3105 | /* The first chars of the expansion should be a "@ " added by | ||
3106 | * collect_expansion. This is to prevent accidental token-pasting | ||
3107 | * between the text preceding the macro invocation, and the macro | ||
3108 | * expansion text. | ||
3109 | * | ||
3110 | * We would like to avoid adding unneeded spaces (for the sake of | ||
3111 | * tools that use cpp, such as imake). In some common cases we can | ||
3112 | * tell that it is safe to omit the space. | ||
3113 | * | ||
3114 | * The character before the macro invocation cannot have been an | ||
3115 | * idchar (or else it would have been pasted with the idchars of | ||
3116 | * the macro name). Therefore, if the first non-space character | ||
3117 | * of the expansion is an idchar, we do not need the extra space | ||
3118 | * to prevent token pasting. | ||
3119 | * | ||
3120 | * Also, we don't need the extra space if the first char is '(', | ||
3121 | * or some other (less common) characters. */ | ||
3122 | |||
3123 | if (xbuf[0] == '@' && xbuf[1] == ' ' | ||
3124 | && (is_idchar[xbuf[2]] || xbuf[2] == '(' || xbuf[2] == '\'' | ||
3125 | || xbuf[2] == '\"')) | ||
3126 | mbuf->cur += 2; | ||
3127 | } | ||
3128 | |||
3129 | /* Like cpp_get_token, except that it does not read past end-of-line. | ||
3130 | * Also, horizontal space is skipped, and macros are popped. */ | ||
3131 | |||
3132 | static enum cpp_token | ||
3133 | get_directive_token(cpp_reader * pfile) | ||
3134 | { | ||
3135 | for (;;) | ||
3136 | { | ||
3137 | long old_written = CPP_WRITTEN(pfile); | ||
3138 | enum cpp_token token; | ||
3139 | |||
3140 | cpp_skip_hspace(pfile); | ||
3141 | if (PEEKC() == '\n') | ||
3142 | return CPP_VSPACE; | ||
3143 | token = cpp_get_token(pfile); | ||
3144 | switch (token) | ||
3145 | { | ||
3146 | case CPP_POP: | ||
3147 | if (!CPP_IS_MACRO_BUFFER(CPP_BUFFER(pfile))) | ||
3148 | return token; | ||
3149 | /* ... else fall though ... */ | ||
3150 | case CPP_HSPACE: | ||
3151 | case CPP_COMMENT: | ||
3152 | CPP_SET_WRITTEN(pfile, old_written); | ||
3153 | break; | ||
3154 | default: | ||
3155 | return token; | ||
3156 | } | ||
3157 | } | ||
3158 | } | ||
3159 | |||
3160 | /* Handle #include and #import. | ||
3161 | * This function expects to see "fname" or <fname> on the input. | ||
3162 | * | ||
3163 | * The input is normally in part of the output_buffer following | ||
3164 | * CPP_WRITTEN, and will get overwritten by output_line_command. | ||
3165 | * I.e. in input file specification has been popped by handle_directive. | ||
3166 | * This is safe. */ | ||
3167 | |||
3168 | static int | ||
3169 | do_include(cpp_reader * pfile, struct directive *keyword, | ||
3170 | unsigned char *unused1 __UNUSED__, unsigned char *unused2 __UNUSED__) | ||
3171 | { | ||
3172 | int importing = (keyword->type == T_IMPORT); | ||
3173 | int skip_dirs = (keyword->type == T_INCLUDE_NEXT); | ||
3174 | char *fname; /* Dynamically allocated fname buffer */ | ||
3175 | unsigned char *fbeg, *fend; /* Beginning and end of fname */ | ||
3176 | enum cpp_token token; | ||
3177 | |||
3178 | /* Chain of dirs to search */ | ||
3179 | file_name_list *search_start = CPP_OPTIONS(pfile)->include; | ||
3180 | file_name_list dsp[1]; /* First in chain, if #include "..." */ | ||
3181 | file_name_list *searchptr = 0; | ||
3182 | long old_written = CPP_WRITTEN(pfile); | ||
3183 | int flen; | ||
3184 | int f; /* file number */ | ||
3185 | int angle_brackets = 0; /* 0 for "...", 1 for <...> */ | ||
3186 | |||
3187 | f = -1; /* JF we iz paranoid! */ | ||
3188 | |||
3189 | if (importing && CPP_OPTIONS(pfile)->warn_import | ||
3190 | && !CPP_OPTIONS(pfile)->inhibit_warnings | ||
3191 | && !CPP_BUFFER(pfile)->system_header_p && !pfile->import_warning) | ||
3192 | { | ||
3193 | pfile->import_warning = 1; | ||
3194 | cpp_warning(pfile, "using `#import' is not recommended"); | ||
3195 | fprintf(stderr, | ||
3196 | "The fact that a certain header file need not be processed more than once\n"); | ||
3197 | fprintf(stderr, | ||
3198 | "should be indicated in the header file, not where it is used.\n"); | ||
3199 | fprintf(stderr, | ||
3200 | "The best way to do this is with a conditional of this form:\n\n"); | ||
3201 | fprintf(stderr, " #ifndef _FOO_H_INCLUDED\n"); | ||
3202 | fprintf(stderr, " #define _FOO_H_INCLUDED\n"); | ||
3203 | fprintf(stderr, " ... <real contents of file> ...\n"); | ||
3204 | fprintf(stderr, " #endif /* Not _FOO_H_INCLUDED */\n\n"); | ||
3205 | fprintf(stderr, "Then users can use `#include' any number of times.\n"); | ||
3206 | fprintf(stderr, | ||
3207 | "GNU C automatically avoids processing the file more than once\n"); | ||
3208 | fprintf(stderr, "when it is equipped with such a conditional.\n"); | ||
3209 | } | ||
3210 | pfile->parsing_include_directive++; | ||
3211 | token = get_directive_token(pfile); | ||
3212 | pfile->parsing_include_directive--; | ||
3213 | |||
3214 | if (token == CPP_STRING) | ||
3215 | { | ||
3216 | /* FIXME - check no trailing garbage */ | ||
3217 | fbeg = pfile->token_buffer + old_written + 1; | ||
3218 | fend = CPP_PWRITTEN(pfile) - 1; | ||
3219 | if (fbeg[-1] == '<') | ||
3220 | { | ||
3221 | angle_brackets = 1; | ||
3222 | /* If -I-, start with the first -I dir after the -I-. */ | ||
3223 | if (CPP_OPTIONS(pfile)->first_bracket_include) | ||
3224 | search_start = CPP_OPTIONS(pfile)->first_bracket_include; | ||
3225 | } | ||
3226 | /* If -I- was specified, don't search current dir, only spec'd ones. */ | ||
3227 | else if (!CPP_OPTIONS(pfile)->ignore_srcdir) | ||
3228 | { | ||
3229 | cpp_buffer *fp; | ||
3230 | |||
3231 | /* We have "filename". Figure out directory this source | ||
3232 | * file is coming from and put it on the front of the list. */ | ||
3233 | |||
3234 | for (fp = CPP_BUFFER(pfile); fp; fp = CPP_PREV_BUFFER(fp)) | ||
3235 | { | ||
3236 | int n; | ||
3237 | const char *ep, *nam; | ||
3238 | |||
3239 | if ((nam = fp->nominal_fname)) | ||
3240 | { | ||
3241 | /* Found a named file. Figure out dir of the file, | ||
3242 | * and put it in front of the search list. */ | ||
3243 | dsp[0].next = search_start; | ||
3244 | search_start = dsp; | ||
3245 | #ifndef VMS | ||
3246 | ep = strrchr(nam, '/'); | ||
3247 | #else /* VMS */ | ||
3248 | ep = strrchr(nam, ']'); | ||
3249 | if (!ep) | ||
3250 | ep = strrchr(nam, '>'); | ||
3251 | if (!ep) | ||
3252 | ep = strrchr(nam, ':'); | ||
3253 | if (ep) | ||
3254 | ep++; | ||
3255 | #endif /* VMS */ | ||
3256 | if (ep) | ||
3257 | { | ||
3258 | n = ep - nam; | ||
3259 | dsp[0].fname = (char *)alloca(n + 1); | ||
3260 | strncpy(dsp[0].fname, nam, n); | ||
3261 | dsp[0].fname[n] = '\0'; | ||
3262 | if (n + INCLUDE_LEN_FUDGE > pfile->max_include_len) | ||
3263 | pfile->max_include_len = n + INCLUDE_LEN_FUDGE; | ||
3264 | } | ||
3265 | else | ||
3266 | { | ||
3267 | dsp[0].fname = 0; /* Current directory */ | ||
3268 | } | ||
3269 | dsp[0].got_name_map = 0; | ||
3270 | break; | ||
3271 | } | ||
3272 | } | ||
3273 | } | ||
3274 | } | ||
3275 | else | ||
3276 | { | ||
3277 | cpp_error(pfile, | ||
3278 | "`#%s' expects \"FILENAME\" or <FILENAME>", keyword->name); | ||
3279 | CPP_SET_WRITTEN(pfile, old_written); | ||
3280 | skip_rest_of_line(pfile); | ||
3281 | return 0; | ||
3282 | } | ||
3283 | |||
3284 | *fend = 0; | ||
3285 | |||
3286 | token = get_directive_token(pfile); | ||
3287 | if (token != CPP_VSPACE) | ||
3288 | { | ||
3289 | cpp_error(pfile, "junk at end of `#include'"); | ||
3290 | while (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP) | ||
3291 | token = get_directive_token(pfile); | ||
3292 | } | ||
3293 | /* For #include_next, skip in the search path | ||
3294 | * past the dir in which the containing file was found. */ | ||
3295 | if (skip_dirs) | ||
3296 | { | ||
3297 | cpp_buffer *fp; | ||
3298 | |||
3299 | for (fp = CPP_BUFFER(pfile); fp; fp = CPP_PREV_BUFFER(fp)) | ||
3300 | if (fp->fname) | ||
3301 | { | ||
3302 | /* fp->dir is null if the containing file was specified with | ||
3303 | * an absolute file name. In that case, don't skip anything. */ | ||
3304 | if (fp->dir == SELF_DIR_DUMMY) | ||
3305 | search_start = CPP_OPTIONS(pfile)->include; | ||
3306 | else if (fp->dir) | ||
3307 | search_start = fp->dir->next; | ||
3308 | break; | ||
3309 | } | ||
3310 | } | ||
3311 | CPP_SET_WRITTEN(pfile, old_written); | ||
3312 | |||
3313 | flen = fend - fbeg; | ||
3314 | |||
3315 | if (flen == 0) | ||
3316 | { | ||
3317 | cpp_error(pfile, "empty file name in `#%s'", keyword->name); | ||
3318 | return 0; | ||
3319 | } | ||
3320 | /* Allocate this permanently, because it gets stored in the definitions | ||
3321 | * of macros. */ | ||
3322 | fname = (char *)xmalloc(pfile->max_include_len + flen + 4); | ||
3323 | /* + 2 above for slash and terminating null. */ | ||
3324 | /* + 2 added for '.h' on VMS (to support '#include filename') */ | ||
3325 | |||
3326 | /* If specified file name is absolute, just open it. */ | ||
3327 | |||
3328 | #ifndef __EMX__ | ||
3329 | if (*fbeg == '/') | ||
3330 | #else | ||
3331 | if (_fnisabs(fbeg)) | ||
3332 | #endif | ||
3333 | { | ||
3334 | strncpy(fname, (const char *)fbeg, flen); | ||
3335 | fname[flen] = 0; | ||
3336 | if (redundant_include_p(pfile, fname)) | ||
3337 | return 0; | ||
3338 | if (importing) | ||
3339 | f = lookup_import(pfile, fname, NULL); | ||
3340 | else | ||
3341 | f = open_include_file(pfile, fname, NULL); | ||
3342 | if (f == -2) | ||
3343 | return 0; /* Already included this file */ | ||
3344 | } | ||
3345 | else | ||
3346 | { | ||
3347 | /* Search directory path, trying to open the file. | ||
3348 | * Copy each filename tried into FNAME. */ | ||
3349 | |||
3350 | for (searchptr = search_start; searchptr; searchptr = searchptr->next) | ||
3351 | { | ||
3352 | if (searchptr->fname) | ||
3353 | { | ||
3354 | /* The empty string in a search path is ignored. | ||
3355 | * This makes it possible to turn off entirely | ||
3356 | * a standard piece of the list. */ | ||
3357 | if (searchptr->fname[0] == 0) | ||
3358 | continue; | ||
3359 | strcpy(fname, searchptr->fname); | ||
3360 | strcat(fname, "/"); | ||
3361 | fname[strlen(fname) + flen] = 0; | ||
3362 | } | ||
3363 | else | ||
3364 | { | ||
3365 | fname[0] = 0; | ||
3366 | } | ||
3367 | strncat(fname, (const char *)fbeg, flen); | ||
3368 | #ifdef VMS | ||
3369 | /* Change this 1/2 Unix 1/2 VMS file specification into a | ||
3370 | * full VMS file specification */ | ||
3371 | if (searchptr->fname && (searchptr->fname[0] != 0)) | ||
3372 | { | ||
3373 | /* Fix up the filename */ | ||
3374 | hack_vms_include_specification(fname); | ||
3375 | } | ||
3376 | else | ||
3377 | { | ||
3378 | /* This is a normal VMS filespec, so use it unchanged. */ | ||
3379 | strncpy(fname, fbeg, flen); | ||
3380 | fname[flen] = 0; | ||
3381 | /* if it's '#include filename', add the missing .h */ | ||
3382 | if (!strchr(fname, '.')) | ||
3383 | { | ||
3384 | strcat(fname, ".h"); | ||
3385 | } | ||
3386 | } | ||
3387 | #endif /* VMS */ | ||
3388 | /* ??? There are currently 3 separate mechanisms for avoiding processing | ||
3389 | * of redundant include files: #import, #pragma once, and | ||
3390 | * redundant_include_p. It would be nice if they were unified. */ | ||
3391 | if (redundant_include_p(pfile, fname)) | ||
3392 | return 0; | ||
3393 | if (importing) | ||
3394 | f = lookup_import(pfile, fname, searchptr); | ||
3395 | else | ||
3396 | f = open_include_file(pfile, fname, searchptr); | ||
3397 | if (f == -2) | ||
3398 | return 0; /* Already included this file */ | ||
3399 | #ifdef EACCES | ||
3400 | else if (f == -1 && errno == EACCES) | ||
3401 | cpp_warning(pfile, "Header file %s exists, but is not readable", | ||
3402 | fname); | ||
3403 | #endif | ||
3404 | if (f >= 0) | ||
3405 | break; | ||
3406 | } | ||
3407 | } | ||
3408 | |||
3409 | if (f < 0) | ||
3410 | { | ||
3411 | /* A file that was not found. */ | ||
3412 | strncpy(fname, (const char *)fbeg, flen); | ||
3413 | fname[flen] = 0; | ||
3414 | /* If generating dependencies and -MG was specified, we assume missing | ||
3415 | * files are leaf files, living in the same directory as the source file | ||
3416 | * or other similar place; these missing files may be generated from | ||
3417 | * other files and may not exist yet (eg: y.tab.h). */ | ||
3418 | |||
3419 | if (CPP_OPTIONS(pfile)->print_deps_missing_files | ||
3420 | && CPP_PRINT_DEPS(pfile) | ||
3421 | > (angle_brackets || (pfile->system_include_depth > 0))) | ||
3422 | { | ||
3423 | /* If it was requested as a system header file, | ||
3424 | * then assume it belongs in the first place to look for such. */ | ||
3425 | if (angle_brackets) | ||
3426 | { | ||
3427 | for (searchptr = search_start; searchptr; | ||
3428 | searchptr = searchptr->next) | ||
3429 | { | ||
3430 | if (searchptr->fname) | ||
3431 | { | ||
3432 | char *p; | ||
3433 | |||
3434 | if (searchptr->fname[0] == 0) | ||
3435 | continue; | ||
3436 | p = (char *)alloca(strlen(searchptr->fname) | ||
3437 | + strlen(fname) + 2); | ||
3438 | strcpy(p, searchptr->fname); | ||
3439 | strcat(p, "/"); | ||
3440 | strcat(p, fname); | ||
3441 | deps_output(pfile, p, ' '); | ||
3442 | break; | ||
3443 | } | ||
3444 | } | ||
3445 | } | ||
3446 | else | ||
3447 | { | ||
3448 | /* Otherwise, omit the directory, as if the file existed | ||
3449 | * in the directory with the source. */ | ||
3450 | deps_output(pfile, fname, ' '); | ||
3451 | } | ||
3452 | } | ||
3453 | /* If -M was specified, and this header file won't be added to the | ||
3454 | * dependency list, then don't count this as an error, because we can | ||
3455 | * still produce correct output. Otherwise, we can't produce correct | ||
3456 | * output, because there may be dependencies we need inside the missing | ||
3457 | * file, and we don't know what directory this missing file exists in. */ | ||
3458 | else if (CPP_PRINT_DEPS(pfile) | ||
3459 | && (CPP_PRINT_DEPS(pfile) | ||
3460 | <= (angle_brackets || (pfile->system_include_depth > 0)))) | ||
3461 | cpp_warning(pfile, "No include path in which to find %s", fname); | ||
3462 | else if (search_start) | ||
3463 | cpp_error_from_errno(pfile, fname); | ||
3464 | else | ||
3465 | cpp_error(pfile, "No include path in which to find %s", fname); | ||
3466 | } | ||
3467 | else | ||
3468 | { | ||
3469 | /* Check to see if this include file is a once-only include file. | ||
3470 | * If so, give up. */ | ||
3471 | |||
3472 | file_name_list *ptr; | ||
3473 | |||
3474 | for (ptr = pfile->dont_repeat_files; ptr; ptr = ptr->next) | ||
3475 | { | ||
3476 | if (!strcmp(ptr->fname, fname)) | ||
3477 | { | ||
3478 | close(f); | ||
3479 | return 0; /* This file was once'd. */ | ||
3480 | } | ||
3481 | } | ||
3482 | |||
3483 | for (ptr = pfile->all_include_files; ptr; ptr = ptr->next) | ||
3484 | { | ||
3485 | if (!strcmp(ptr->fname, fname)) | ||
3486 | break; /* This file was included before. */ | ||
3487 | } | ||
3488 | |||
3489 | if (!ptr) | ||
3490 | { | ||
3491 | /* This is the first time for this file. */ | ||
3492 | /* Add it to list of files included. */ | ||
3493 | |||
3494 | ptr = (file_name_list *) xmalloc(sizeof(file_name_list)); | ||
3495 | |||
3496 | ptr->control_macro = 0; | ||
3497 | ptr->c_system_include_path = 0; | ||
3498 | ptr->next = pfile->all_include_files; | ||
3499 | pfile->all_include_files = ptr; | ||
3500 | ptr->fname = savestring(fname); | ||
3501 | ptr->got_name_map = 0; | ||
3502 | |||
3503 | /* For -M, add this file to the dependencies. */ | ||
3504 | if (CPP_PRINT_DEPS(pfile) | ||
3505 | > (angle_brackets || (pfile->system_include_depth > 0))) | ||
3506 | deps_output(pfile, fname, ' '); | ||
3507 | } | ||
3508 | /* Handle -H option. */ | ||
3509 | if (CPP_OPTIONS(pfile)->print_include_names) | ||
3510 | { | ||
3511 | cpp_buffer *buf = CPP_BUFFER(pfile); | ||
3512 | |||
3513 | while ((buf = CPP_PREV_BUFFER(buf))) | ||
3514 | putc('.', stderr); | ||
3515 | fprintf(stderr, "%s\n", fname); | ||
3516 | } | ||
3517 | if (angle_brackets) | ||
3518 | pfile->system_include_depth++; | ||
3519 | |||
3520 | /* Actually process the file. */ | ||
3521 | |||
3522 | /* Record file on "seen" list for #import. */ | ||
3523 | add_import(pfile, f, fname); | ||
3524 | |||
3525 | /* Actually process the file */ | ||
3526 | cpp_push_buffer(pfile, NULL, 0); | ||
3527 | if (finclude(pfile, f, fname, is_system_include(pfile, fname), | ||
3528 | searchptr != dsp ? searchptr : SELF_DIR_DUMMY)) | ||
3529 | { | ||
3530 | output_line_command(pfile, 0, enter_file); | ||
3531 | pfile->only_seen_white = 2; | ||
3532 | } | ||
3533 | if (angle_brackets) | ||
3534 | pfile->system_include_depth--; | ||
3535 | } | ||
3536 | return 0; | ||
3537 | } | ||
3538 | |||
3539 | /* Return nonzero if there is no need to include file NAME | ||
3540 | * because it has already been included and it contains a conditional | ||
3541 | * to make a repeated include do nothing. */ | ||
3542 | |||
3543 | static int | ||
3544 | redundant_include_p(cpp_reader * pfile, char *name) | ||
3545 | { | ||
3546 | file_name_list *l = pfile->all_include_files; | ||
3547 | |||
3548 | for (; l; l = l->next) | ||
3549 | if (!strcmp(name, l->fname) | ||
3550 | && l->control_macro | ||
3551 | && cpp_lookup((const char *)l->control_macro, -1, -1)) | ||
3552 | return 1; | ||
3553 | return 0; | ||
3554 | } | ||
3555 | |||
3556 | /* Return nonzero if the given FILENAME is an absolute pathname which | ||
3557 | * designates a file within one of the known "system" include file | ||
3558 | * directories. We assume here that if the given FILENAME looks like | ||
3559 | * it is the name of a file which resides either directly in a "system" | ||
3560 | * include file directory, or within any subdirectory thereof, then the | ||
3561 | * given file must be a "system" include file. This function tells us | ||
3562 | * if we should suppress pedantic errors/warnings for the given FILENAME. | ||
3563 | * | ||
3564 | * The value is 2 if the file is a C-language system header file | ||
3565 | * for which C++ should (on most systems) assume `extern "C"'. */ | ||
3566 | |||
3567 | static int | ||
3568 | is_system_include(cpp_reader * pfile, char *filename) | ||
3569 | { | ||
3570 | file_name_list *searchptr; | ||
3571 | |||
3572 | for (searchptr = CPP_OPTIONS(pfile)->first_system_include; searchptr; | ||
3573 | searchptr = searchptr->next) | ||
3574 | if (searchptr->fname) | ||
3575 | { | ||
3576 | char *sys_dir = searchptr->fname; | ||
3577 | unsigned length = strlen(sys_dir); | ||
3578 | |||
3579 | if (!strncmp(sys_dir, filename, length) && filename[length] == '/') | ||
3580 | { | ||
3581 | if (searchptr->c_system_include_path) | ||
3582 | return 2; | ||
3583 | else | ||
3584 | return 1; | ||
3585 | } | ||
3586 | } | ||
3587 | return 0; | ||
3588 | } | ||
3589 | |||
3590 | /* | ||
3591 | * Install a name in the assertion hash table. | ||
3592 | * | ||
3593 | * If LEN is >= 0, it is the length of the name. | ||
3594 | * Otherwise, compute the length by scanning the entire name. | ||
3595 | * | ||
3596 | * If HASH is >= 0, it is the precomputed hash code. | ||
3597 | * Otherwise, compute the hash code. | ||
3598 | */ | ||
3599 | static ASSERTION_HASHNODE * | ||
3600 | assertion_install(cpp_reader * pfile, const char *name, int len, int hash) | ||
3601 | { | ||
3602 | ASSERTION_HASHNODE *hp; | ||
3603 | int i, bucket; | ||
3604 | |||
3605 | i = sizeof(ASSERTION_HASHNODE) + len + 1; | ||
3606 | hp = (ASSERTION_HASHNODE *) xmalloc(i); | ||
3607 | bucket = hash; | ||
3608 | hp->bucket_hdr = &pfile->assertion_hashtab[bucket]; | ||
3609 | hp->next = pfile->assertion_hashtab[bucket]; | ||
3610 | pfile->assertion_hashtab[bucket] = hp; | ||
3611 | hp->prev = NULL; | ||
3612 | if (hp->next) | ||
3613 | hp->next->prev = hp; | ||
3614 | hp->length = len; | ||
3615 | hp->value = 0; | ||
3616 | hp->name = ((char *)hp) + sizeof(ASSERTION_HASHNODE); | ||
3617 | memcpy(hp->name, name, len); | ||
3618 | hp->name[len] = 0; | ||
3619 | return hp; | ||
3620 | } | ||
3621 | /* | ||
3622 | * find the most recent hash node for name name (ending with first | ||
3623 | * non-identifier char) installed by install | ||
3624 | * | ||
3625 | * If LEN is >= 0, it is the length of the name. | ||
3626 | * Otherwise, compute the length by scanning the entire name. | ||
3627 | * | ||
3628 | * If HASH is >= 0, it is the precomputed hash code. | ||
3629 | * Otherwise, compute the hash code. | ||
3630 | */ | ||
3631 | |||
3632 | static ASSERTION_HASHNODE * | ||
3633 | assertion_lookup(cpp_reader * pfile, const char *name, int len, int hash) | ||
3634 | { | ||
3635 | ASSERTION_HASHNODE *bucket; | ||
3636 | |||
3637 | bucket = pfile->assertion_hashtab[hash]; | ||
3638 | while (bucket) | ||
3639 | { | ||
3640 | if (bucket->length == len && strncmp(bucket->name, name, len) == 0) | ||
3641 | return bucket; | ||
3642 | bucket = bucket->next; | ||
3643 | } | ||
3644 | return NULL; | ||
3645 | } | ||
3646 | |||
3647 | static void | ||
3648 | delete_assertion(ASSERTION_HASHNODE * hp) | ||
3649 | { | ||
3650 | struct tokenlist_list *tail; | ||
3651 | |||
3652 | if (hp->prev) | ||
3653 | hp->prev->next = hp->next; | ||
3654 | if (hp->next) | ||
3655 | hp->next->prev = hp->prev; | ||
3656 | |||
3657 | for (tail = hp->value; tail;) | ||
3658 | { | ||
3659 | struct tokenlist_list *next = tail->next; | ||
3660 | |||
3661 | free_token_list(tail->tokens); | ||
3662 | free(tail); | ||
3663 | tail = next; | ||
3664 | } | ||
3665 | |||
3666 | /* make sure that the bucket chain header that | ||
3667 | * the deleted guy was on points to the right thing afterwards. */ | ||
3668 | if (hp == *hp->bucket_hdr) | ||
3669 | *hp->bucket_hdr = hp->next; | ||
3670 | |||
3671 | free(hp); | ||
3672 | } | ||
3673 | |||
3674 | /* Convert a character string literal into a nul-terminated string. | ||
3675 | * The input string is [IN ... LIMIT). | ||
3676 | * The result is placed in RESULT. RESULT can be the same as IN. | ||
3677 | * The value returned in the end of the string written to RESULT, | ||
3678 | * or NULL on error. */ | ||
3679 | |||
3680 | static char * | ||
3681 | convert_string(cpp_reader * pfile, char *result, char *in, char *limit, | ||
3682 | int handle_escapes) | ||
3683 | { | ||
3684 | unsigned char c; | ||
3685 | |||
3686 | c = *in++; | ||
3687 | if (c != '\"') | ||
3688 | return NULL; | ||
3689 | while (in < limit) | ||
3690 | { | ||
3691 | c = *in++; | ||
3692 | |||
3693 | switch (c) | ||
3694 | { | ||
3695 | case '\0': | ||
3696 | return NULL; | ||
3697 | case '\"': | ||
3698 | limit = in; | ||
3699 | break; | ||
3700 | case '\\': | ||
3701 | if (handle_escapes) | ||
3702 | { | ||
3703 | char *bpc = in; | ||
3704 | int i = | ||
3705 | (unsigned char)cpp_parse_escape(pfile, &bpc); | ||
3706 | |||
3707 | in = bpc; | ||
3708 | if (i >= 0) | ||
3709 | *result++ = (unsigned char)c; | ||
3710 | break; | ||
3711 | } | ||
3712 | /* else fall through */ | ||
3713 | default: | ||
3714 | *result++ = c; | ||
3715 | } | ||
3716 | } | ||
3717 | *result = 0; | ||
3718 | return result; | ||
3719 | } | ||
3720 | |||
3721 | /* | ||
3722 | * interpret #line command. Remembers previously seen fnames | ||
3723 | * in its very own hash table. | ||
3724 | */ | ||
3725 | #define FNAME_HASHSIZE 37 | ||
3726 | |||
3727 | static int | ||
3728 | do_line(cpp_reader * pfile, struct directive *keyword __UNUSED__, | ||
3729 | unsigned char *unused1 __UNUSED__, unsigned char *unused2 __UNUSED__) | ||
3730 | { | ||
3731 | cpp_buffer *ip = CPP_BUFFER(pfile); | ||
3732 | int new_lineno; | ||
3733 | long old_written = CPP_WRITTEN(pfile); | ||
3734 | enum file_change_code file_change = same_file; | ||
3735 | enum cpp_token token; | ||
3736 | |||
3737 | token = get_directive_token(pfile); | ||
3738 | |||
3739 | if (token != CPP_NUMBER || !isdigit(pfile->token_buffer[old_written])) | ||
3740 | { | ||
3741 | cpp_error(pfile, "invalid format `#line' command"); | ||
3742 | goto bad_line_directive; | ||
3743 | } | ||
3744 | /* The Newline at the end of this line remains to be processed. | ||
3745 | * To put the next line at the specified line number, | ||
3746 | * we must store a line number now that is one less. */ | ||
3747 | new_lineno = atoi((char *)(pfile->token_buffer + old_written)) - 1; | ||
3748 | CPP_SET_WRITTEN(pfile, old_written); | ||
3749 | |||
3750 | /* NEW_LINENO is one less than the actual line number here. */ | ||
3751 | if (CPP_PEDANTIC(pfile) && new_lineno < 0) | ||
3752 | cpp_pedwarn(pfile, "line number out of range in `#line' command"); | ||
3753 | |||
3754 | token = get_directive_token(pfile); | ||
3755 | |||
3756 | if (token == CPP_STRING) | ||
3757 | { | ||
3758 | char *fname = (char *)pfile->token_buffer + old_written; | ||
3759 | char *end_name; | ||
3760 | static HASHNODE *fname_table[FNAME_HASHSIZE]; | ||
3761 | HASHNODE *hp, **hash_bucket; | ||
3762 | unsigned char *p; | ||
3763 | long num_start; | ||
3764 | int fname_length; | ||
3765 | |||
3766 | /* Turn the file name, which is a character string literal, | ||
3767 | * into a null-terminated string. Do this in place. */ | ||
3768 | end_name = | ||
3769 | convert_string(pfile, fname, fname, (char *)CPP_PWRITTEN(pfile), 1); | ||
3770 | if (!end_name) | ||
3771 | { | ||
3772 | cpp_error(pfile, "invalid format `#line' command"); | ||
3773 | goto bad_line_directive; | ||
3774 | } | ||
3775 | fname_length = end_name - fname; | ||
3776 | |||
3777 | num_start = CPP_WRITTEN(pfile); | ||
3778 | token = get_directive_token(pfile); | ||
3779 | if (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP) | ||
3780 | { | ||
3781 | p = pfile->token_buffer + num_start; | ||
3782 | if (CPP_PEDANTIC(pfile)) | ||
3783 | cpp_pedwarn(pfile, "garbage at end of `#line' command"); | ||
3784 | |||
3785 | if (token != CPP_NUMBER || *p < '0' || *p > '4' || p[1] != '\0') | ||
3786 | { | ||
3787 | cpp_error(pfile, "invalid format `#line' command"); | ||
3788 | goto bad_line_directive; | ||
3789 | } | ||
3790 | if (*p == '1') | ||
3791 | file_change = enter_file; | ||
3792 | else if (*p == 2) | ||
3793 | file_change = leave_file; | ||
3794 | else if (*p == 3) | ||
3795 | ip->system_header_p = 1; | ||
3796 | else /* if (*p == 4) */ | ||
3797 | ip->system_header_p = 2; | ||
3798 | |||
3799 | CPP_SET_WRITTEN(pfile, num_start); | ||
3800 | token = get_directive_token(pfile); | ||
3801 | p = pfile->token_buffer + num_start; | ||
3802 | if (token == CPP_NUMBER && p[1] == '\0' | ||
3803 | && (*p == '3' || *p == '4')) | ||
3804 | { | ||
3805 | ip->system_header_p = *p == 3 ? 1 : 2; | ||
3806 | token = get_directive_token(pfile); | ||
3807 | } | ||
3808 | if (token != CPP_VSPACE) | ||
3809 | { | ||
3810 | cpp_error(pfile, "invalid format `#line' command"); | ||
3811 | goto bad_line_directive; | ||
3812 | } | ||
3813 | } | ||
3814 | hash_bucket = &fname_table[hashf(fname, fname_length, FNAME_HASHSIZE)]; | ||
3815 | for (hp = *hash_bucket; hp; hp = hp->next) | ||
3816 | if (hp->length == fname_length && | ||
3817 | strncmp(hp->value.cpval, fname, fname_length) == 0) | ||
3818 | { | ||
3819 | ip->nominal_fname = hp->value.cpval; | ||
3820 | break; | ||
3821 | } | ||
3822 | if (!hp) | ||
3823 | { | ||
3824 | /* Didn't find it; cons up a new one. */ | ||
3825 | hp = (HASHNODE *) xcalloc(1, sizeof(HASHNODE) + fname_length + 1); | ||
3826 | hp->next = *hash_bucket; | ||
3827 | *hash_bucket = hp; | ||
3828 | |||
3829 | hp->length = fname_length; | ||
3830 | ip->nominal_fname = hp->value.cpval = | ||
3831 | ((char *)hp) + sizeof(HASHNODE); | ||
3832 | memcpy(hp->value.cpval, fname, fname_length); | ||
3833 | } | ||
3834 | } | ||
3835 | else if (token != CPP_VSPACE && token != CPP_EOF) | ||
3836 | { | ||
3837 | cpp_error(pfile, "invalid format `#line' command"); | ||
3838 | goto bad_line_directive; | ||
3839 | } | ||
3840 | ip->lineno = new_lineno; | ||
3841 | bad_line_directive: | ||
3842 | skip_rest_of_line(pfile); | ||
3843 | CPP_SET_WRITTEN(pfile, old_written); | ||
3844 | output_line_command(pfile, 0, file_change); | ||
3845 | return 0; | ||
3846 | } | ||
3847 | |||
3848 | /* | ||
3849 | * remove the definition of a symbol from the symbol table. | ||
3850 | * according to un*x /lib/cpp, it is not an error to undef | ||
3851 | * something that has no definitions, so it isn't one here either. | ||
3852 | */ | ||
3853 | |||
3854 | static int | ||
3855 | do_undef(cpp_reader * pfile, struct directive *keyword, unsigned char *buf, | ||
3856 | unsigned char *limit) | ||
3857 | { | ||
3858 | int sym_length; | ||
3859 | HASHNODE *hp; | ||
3860 | unsigned char *orig_buf = buf; | ||
3861 | |||
3862 | SKIP_WHITE_SPACE(buf); | ||
3863 | sym_length = check_macro_name(pfile, buf, "macro"); | ||
3864 | |||
3865 | while ((hp = cpp_lookup((const char *)buf, sym_length, -1))) | ||
3866 | { | ||
3867 | /* If we are generating additional info for debugging (with -g) we | ||
3868 | * need to pass through all effective #undef commands. */ | ||
3869 | if (CPP_OPTIONS(pfile)->debug_output && keyword) | ||
3870 | pass_thru_directive((char *)orig_buf, (char *)limit, pfile, keyword); | ||
3871 | if (hp->type != T_MACRO) | ||
3872 | cpp_warning(pfile, "undefining `%s'", hp->name); | ||
3873 | delete_macro(hp); | ||
3874 | } | ||
3875 | |||
3876 | if (CPP_PEDANTIC(pfile)) | ||
3877 | { | ||
3878 | buf += sym_length; | ||
3879 | SKIP_WHITE_SPACE(buf); | ||
3880 | if (buf != limit) | ||
3881 | cpp_pedwarn(pfile, "garbage after `#undef' directive"); | ||
3882 | } | ||
3883 | return 0; | ||
3884 | } | ||
3885 | |||
3886 | /* | ||
3887 | * Report an error detected by the program we are processing. | ||
3888 | * Use the text of the line in the error message. | ||
3889 | * (We use error because it prints the filename & line#.) | ||
3890 | */ | ||
3891 | |||
3892 | static int | ||
3893 | do_error(cpp_reader * pfile, struct directive *keyword __UNUSED__, | ||
3894 | unsigned char *buf, unsigned char *limit) | ||
3895 | { | ||
3896 | int length = limit - buf; | ||
3897 | unsigned char *copy = (unsigned char *)xmalloc(length + 1); | ||
3898 | |||
3899 | memcpy(copy, buf, length); | ||
3900 | copy[length] = 0; | ||
3901 | SKIP_WHITE_SPACE(copy); | ||
3902 | cpp_error(pfile, "#error %s", copy); | ||
3903 | return 0; | ||
3904 | } | ||
3905 | |||
3906 | /* | ||
3907 | * Report a warning detected by the program we are processing. | ||
3908 | * Use the text of the line in the warning message, then continue. | ||
3909 | * (We use error because it prints the filename & line#.) | ||
3910 | */ | ||
3911 | |||
3912 | static int | ||
3913 | do_warning(cpp_reader * pfile, struct directive *keyword __UNUSED__, | ||
3914 | unsigned char *buf, unsigned char *limit) | ||
3915 | { | ||
3916 | int length = limit - buf; | ||
3917 | unsigned char *copy = (unsigned char *)xmalloc(length + 1); | ||
3918 | |||
3919 | memcpy(copy, buf, length); | ||
3920 | copy[length] = 0; | ||
3921 | SKIP_WHITE_SPACE(copy); | ||
3922 | cpp_warning(pfile, "#warning %s", copy); | ||
3923 | return 0; | ||
3924 | } | ||
3925 | |||
3926 | /* Remember the name of the current file being read from so that we can | ||
3927 | * avoid ever including it again. */ | ||
3928 | |||
3929 | static int | ||
3930 | do_once(cpp_reader * pfile) | ||
3931 | { | ||
3932 | cpp_buffer *ip = NULL; | ||
3933 | file_name_list *new_; | ||
3934 | |||
3935 | for (ip = CPP_BUFFER(pfile);; ip = CPP_PREV_BUFFER(ip)) | ||
3936 | { | ||
3937 | if (!ip) | ||
3938 | return 0; | ||
3939 | if (ip->fname) | ||
3940 | break; | ||
3941 | } | ||
3942 | |||
3943 | new_ = (file_name_list *) xmalloc(sizeof(file_name_list)); | ||
3944 | |||
3945 | new_->next = pfile->dont_repeat_files; | ||
3946 | pfile->dont_repeat_files = new_; | ||
3947 | new_->fname = savestring(ip->fname); | ||
3948 | new_->control_macro = 0; | ||
3949 | new_->got_name_map = 0; | ||
3950 | new_->c_system_include_path = 0; | ||
3951 | |||
3952 | return 0; | ||
3953 | } | ||
3954 | |||
3955 | /* #ident has already been copied to the output file, so just ignore it. */ | ||
3956 | |||
3957 | static int | ||
3958 | do_ident(cpp_reader * pfile, struct directive *keyword __UNUSED__, | ||
3959 | unsigned char *buf __UNUSED__, unsigned char *limit __UNUSED__) | ||
3960 | { | ||
3961 | /* long old_written = CPP_WRITTEN (pfile); */ | ||
3962 | |||
3963 | /* Allow #ident in system headers, since that's not user's fault. */ | ||
3964 | if (CPP_PEDANTIC(pfile) && !CPP_BUFFER(pfile)->system_header_p) | ||
3965 | cpp_pedwarn(pfile, "ANSI C does not allow `#ident'"); | ||
3966 | |||
3967 | /* Leave rest of line to be read by later calls to cpp_get_token. */ | ||
3968 | |||
3969 | return 0; | ||
3970 | } | ||
3971 | |||
3972 | /* #pragma and its argument line have already been copied to the output file. | ||
3973 | * Just check for some recognized pragmas that need validation here. */ | ||
3974 | |||
3975 | static int | ||
3976 | do_pragma(cpp_reader * pfile, struct directive *keyword __UNUSED__, | ||
3977 | unsigned char *buf, unsigned char *limit __UNUSED__) | ||
3978 | { | ||
3979 | while (*buf == ' ' || *buf == '\t') | ||
3980 | buf++; | ||
3981 | |||
3982 | if (!strncmp((const char *)buf, "once", 4)) | ||
3983 | { | ||
3984 | /* Allow #pragma once in system headers, since that's not the user's | ||
3985 | * fault. */ | ||
3986 | if (!CPP_BUFFER(pfile)->system_header_p) | ||
3987 | cpp_warning(pfile, "`#pragma once' is obsolete"); | ||
3988 | do_once(pfile); | ||
3989 | } | ||
3990 | if (!strncmp((const char *)buf, "implementation", 14)) | ||
3991 | { | ||
3992 | /* Be quiet about `#pragma implementation' for a file only if it hasn't | ||
3993 | * been included yet. */ | ||
3994 | file_name_list *ptr; | ||
3995 | char *p = (char *)buf + 14, *fname, *inc_fname; | ||
3996 | int fname_len; | ||
3997 | |||
3998 | SKIP_WHITE_SPACE(p); | ||
3999 | if (*p == '\n' || *p != '\"') | ||
4000 | return 0; | ||
4001 | |||
4002 | fname = p + 1; | ||
4003 | p = strchr(fname, '\"'); | ||
4004 | fname_len = (p) ? (int)(p - fname) : (int)strlen(fname); | ||
4005 | |||
4006 | for (ptr = pfile->all_include_files; ptr; ptr = ptr->next) | ||
4007 | { | ||
4008 | inc_fname = strrchr(ptr->fname, '/'); | ||
4009 | inc_fname = inc_fname ? inc_fname + 1 : (char *)ptr->fname; | ||
4010 | if (inc_fname && !strncmp(inc_fname, fname, fname_len)) | ||
4011 | cpp_warning(pfile, | ||
4012 | "`#pragma implementation' for `%s' appears after file is included", | ||
4013 | fname); | ||
4014 | } | ||
4015 | } | ||
4016 | return 0; | ||
4017 | } | ||
4018 | |||
4019 | /* Just ignore #sccs, on systems where we define it at all. */ | ||
4020 | |||
4021 | /* | ||
4022 | * handle #if command by | ||
4023 | * 1) inserting special `defined' keyword into the hash table | ||
4024 | * that gets turned into 0 or 1 by special_symbol (thus, | ||
4025 | * if the luser has a symbol called `defined' already, it won't | ||
4026 | * work inside the #if command) | ||
4027 | * 2) rescan the input into a temporary output buffer | ||
4028 | * 3) pass the output buffer to the yacc parser and collect a value | ||
4029 | * 4) clean up the mess left from steps 1 and 2. | ||
4030 | * 5) call conditional_skip to skip til the next #endif (etc.), | ||
4031 | * or not, depending on the value from step 3. | ||
4032 | */ | ||
4033 | |||
4034 | static int | ||
4035 | do_if(cpp_reader * pfile, struct directive *keyword __UNUSED__, | ||
4036 | unsigned char *buf, unsigned char *limit) | ||
4037 | { | ||
4038 | HOST_WIDE_INT value = eval_if_expression(pfile, buf, limit - buf); | ||
4039 | |||
4040 | conditional_skip(pfile, value == 0, T_IF, NULL); | ||
4041 | return 0; | ||
4042 | } | ||
4043 | |||
4044 | /* | ||
4045 | * handle a #elif directive by not changing if_stack either. | ||
4046 | * see the comment above do_else. | ||
4047 | */ | ||
4048 | |||
4049 | static int | ||
4050 | do_elif(cpp_reader * pfile, struct directive *keyword __UNUSED__, | ||
4051 | unsigned char *buf, unsigned char *limit) | ||
4052 | { | ||
4053 | if (pfile->if_stack == CPP_BUFFER(pfile)->if_stack) | ||
4054 | { | ||
4055 | cpp_error(pfile, "`#elif' not within a conditional"); | ||
4056 | return 0; | ||
4057 | } | ||
4058 | else | ||
4059 | { | ||
4060 | if (pfile->if_stack->type != T_IF && pfile->if_stack->type != T_ELIF) | ||
4061 | { | ||
4062 | cpp_error(pfile, "`#elif' after `#else'"); | ||
4063 | if (pfile->if_stack->fname | ||
4064 | && CPP_BUFFER(pfile)->fname | ||
4065 | && strcmp(pfile->if_stack->fname, | ||
4066 | CPP_BUFFER(pfile)->nominal_fname) != 0) | ||
4067 | fprintf(stderr, ", file %s", pfile->if_stack->fname); | ||
4068 | fprintf(stderr, ")\n"); | ||
4069 | } | ||
4070 | pfile->if_stack->type = T_ELIF; | ||
4071 | } | ||
4072 | |||
4073 | if (pfile->if_stack->if_succeeded) | ||
4074 | skip_if_group(pfile, 0); | ||
4075 | else | ||
4076 | { | ||
4077 | HOST_WIDE_INT value = eval_if_expression(pfile, buf, limit - buf); | ||
4078 | |||
4079 | if (value == 0) | ||
4080 | skip_if_group(pfile, 0); | ||
4081 | else | ||
4082 | { | ||
4083 | ++pfile->if_stack->if_succeeded; /* continue processing input */ | ||
4084 | output_line_command(pfile, 1, same_file); | ||
4085 | } | ||
4086 | } | ||
4087 | return 0; | ||
4088 | } | ||
4089 | |||
4090 | /* | ||
4091 | * evaluate a #if expression in BUF, of length LENGTH, | ||
4092 | * then parse the result as a C expression and return the value as an int. | ||
4093 | */ | ||
4094 | static HOST_WIDE_INT | ||
4095 | eval_if_expression(cpp_reader * pfile, unsigned char *buf __UNUSED__, | ||
4096 | int length __UNUSED__) | ||
4097 | { | ||
4098 | HASHNODE *save_defined; | ||
4099 | HOST_WIDE_INT value; | ||
4100 | long old_written = CPP_WRITTEN(pfile); | ||
4101 | |||
4102 | save_defined = install("defined", -1, T_SPEC_DEFINED, 0, 0, -1); | ||
4103 | pfile->pcp_inside_if = 1; | ||
4104 | |||
4105 | value = cpp_parse_expr(pfile); | ||
4106 | pfile->pcp_inside_if = 0; | ||
4107 | delete_macro(save_defined); /* clean up special symbol */ | ||
4108 | |||
4109 | CPP_SET_WRITTEN(pfile, old_written); /* Pop */ | ||
4110 | |||
4111 | return value; | ||
4112 | } | ||
4113 | |||
4114 | /* | ||
4115 | * routine to handle ifdef/ifndef. Try to look up the symbol, | ||
4116 | * then do or don't skip to the #endif/#else/#elif depending | ||
4117 | * on what directive is actually being processed. | ||
4118 | */ | ||
4119 | |||
4120 | static int | ||
4121 | do_xifdef(cpp_reader * pfile, struct directive *keyword, | ||
4122 | unsigned char *unused1 __UNUSED__, unsigned char *unused2 __UNUSED__) | ||
4123 | { | ||
4124 | int skip; | ||
4125 | cpp_buffer *ip = CPP_BUFFER(pfile); | ||
4126 | char *ident; | ||
4127 | int ident_length; | ||
4128 | enum cpp_token token; | ||
4129 | int start_of_file = 0; | ||
4130 | unsigned char *control_macro = 0; | ||
4131 | int old_written = CPP_WRITTEN(pfile); | ||
4132 | int c; | ||
4133 | |||
4134 | /* Detect a #ifndef at start of file (not counting comments). */ | ||
4135 | if (ip->fname != 0 && keyword->type == T_IFNDEF) | ||
4136 | start_of_file = pfile->only_seen_white == 2; | ||
4137 | |||
4138 | pfile->no_macro_expand++; | ||
4139 | token = get_directive_token(pfile); | ||
4140 | pfile->no_macro_expand--; | ||
4141 | |||
4142 | ident = (char *)pfile->token_buffer + old_written; | ||
4143 | ident_length = CPP_WRITTEN(pfile) - old_written; | ||
4144 | CPP_SET_WRITTEN(pfile, old_written); /* Pop */ | ||
4145 | |||
4146 | if (token == CPP_VSPACE || token == CPP_POP || token == CPP_EOF) | ||
4147 | { | ||
4148 | skip = (keyword->type == T_IFDEF); | ||
4149 | cpp_pedwarn(pfile, "`#%s' with no argument", keyword->name); | ||
4150 | } | ||
4151 | else if (token == CPP_NAME) | ||
4152 | { | ||
4153 | HASHNODE *hp = cpp_lookup(ident, ident_length, -1); | ||
4154 | |||
4155 | skip = (!hp) ^ (keyword->type == T_IFNDEF); | ||
4156 | if (start_of_file && !skip) | ||
4157 | { | ||
4158 | control_macro = (unsigned char *)xmalloc(ident_length + 1); | ||
4159 | memcpy(control_macro, ident, ident_length + 1); | ||
4160 | } | ||
4161 | } | ||
4162 | else | ||
4163 | { | ||
4164 | skip = (keyword->type == T_IFDEF); | ||
4165 | cpp_error(pfile, "`#%s' with invalid argument", keyword->name); | ||
4166 | } | ||
4167 | |||
4168 | cpp_skip_hspace(pfile); | ||
4169 | c = PEEKC(); | ||
4170 | if (c != EOF && c != '\n') | ||
4171 | cpp_pedwarn(pfile, "garbage at end of `#%s' argument", | ||
4172 | keyword->name); | ||
4173 | skip_rest_of_line(pfile); | ||
4174 | |||
4175 | conditional_skip(pfile, skip, T_IF, control_macro); | ||
4176 | return 0; | ||
4177 | } | ||
4178 | |||
4179 | /* Push TYPE on stack; then, if SKIP is nonzero, skip ahead. | ||
4180 | * If this is a #ifndef starting at the beginning of a file, | ||
4181 | * CONTROL_MACRO is the macro name tested by the #ifndef. | ||
4182 | * Otherwise, CONTROL_MACRO is 0. */ | ||
4183 | |||
4184 | static void | ||
4185 | conditional_skip(cpp_reader * pfile, int skip, enum node_type type, | ||
4186 | unsigned char *control_macro) | ||
4187 | { | ||
4188 | IF_STACK_FRAME *temp; | ||
4189 | |||
4190 | temp = (IF_STACK_FRAME *) xcalloc(1, sizeof(IF_STACK_FRAME)); | ||
4191 | temp->fname = CPP_BUFFER(pfile)->nominal_fname; | ||
4192 | temp->next = pfile->if_stack; | ||
4193 | temp->control_macro = control_macro; | ||
4194 | pfile->if_stack = temp; | ||
4195 | |||
4196 | pfile->if_stack->type = type; | ||
4197 | |||
4198 | if (skip != 0) | ||
4199 | { | ||
4200 | skip_if_group(pfile, 0); | ||
4201 | return; | ||
4202 | } | ||
4203 | else | ||
4204 | { | ||
4205 | ++pfile->if_stack->if_succeeded; | ||
4206 | output_line_command(pfile, 1, same_file); | ||
4207 | } | ||
4208 | } | ||
4209 | |||
4210 | /* | ||
4211 | * skip to #endif, #else, or #elif. adjust line numbers, etc. | ||
4212 | * leaves input ptr at the sharp sign found. | ||
4213 | * If ANY is nonzero, return at next directive of any sort. | ||
4214 | */ | ||
4215 | |||
4216 | static void | ||
4217 | skip_if_group(cpp_reader * pfile, int any) | ||
4218 | { | ||
4219 | int c; | ||
4220 | struct directive *kt; | ||
4221 | IF_STACK_FRAME *save_if_stack = pfile->if_stack; /* don't pop past here */ | ||
4222 | |||
4223 | int ident_length; | ||
4224 | char *ident; | ||
4225 | struct parse_marker line_start_mark; | ||
4226 | |||
4227 | parse_set_mark(&line_start_mark, pfile); | ||
4228 | |||
4229 | if (CPP_OPTIONS(pfile)->output_conditionals) | ||
4230 | { | ||
4231 | static char failed[] = "#failed\n"; | ||
4232 | |||
4233 | CPP_PUTS(pfile, failed, sizeof(failed) - 1); | ||
4234 | pfile->lineno++; | ||
4235 | output_line_command(pfile, 1, same_file); | ||
4236 | } | ||
4237 | beg_of_line: | ||
4238 | if (CPP_OPTIONS(pfile)->output_conditionals) | ||
4239 | { | ||
4240 | cpp_buffer *pbuf = CPP_BUFFER(pfile); | ||
4241 | unsigned char *start_line = pbuf->buf + line_start_mark.position; | ||
4242 | |||
4243 | CPP_PUTS(pfile, start_line, pbuf->cur - start_line); | ||
4244 | } | ||
4245 | parse_move_mark(&line_start_mark, pfile); | ||
4246 | cpp_skip_hspace(pfile); | ||
4247 | c = GETC(); | ||
4248 | if (c == '#') | ||
4249 | { | ||
4250 | int old_written = CPP_WRITTEN(pfile); | ||
4251 | |||
4252 | cpp_skip_hspace(pfile); | ||
4253 | |||
4254 | parse_name(pfile, GETC()); | ||
4255 | ident_length = CPP_WRITTEN(pfile) - old_written; | ||
4256 | ident = (char *)pfile->token_buffer + old_written; | ||
4257 | pfile->limit = (unsigned char *)ident; | ||
4258 | |||
4259 | for (kt = directive_table; kt->length >= 0; kt++) | ||
4260 | { | ||
4261 | IF_STACK_FRAME *temp; | ||
4262 | |||
4263 | if (ident_length == kt->length | ||
4264 | && strncmp(ident, kt->name, kt->length) == 0) | ||
4265 | { | ||
4266 | /* If we are asked to return on next directive, do so now. */ | ||
4267 | if (any) | ||
4268 | goto done; | ||
4269 | |||
4270 | switch (kt->type) | ||
4271 | { | ||
4272 | case T_IF: | ||
4273 | case T_IFDEF: | ||
4274 | case T_IFNDEF: | ||
4275 | temp | ||
4276 | = | ||
4277 | (IF_STACK_FRAME *) xcalloc(1, sizeof(IF_STACK_FRAME)); | ||
4278 | temp->next = pfile->if_stack; | ||
4279 | pfile->if_stack = temp; | ||
4280 | temp->fname = CPP_BUFFER(pfile)->nominal_fname; | ||
4281 | temp->type = kt->type; | ||
4282 | break; | ||
4283 | case T_ELSE: | ||
4284 | case T_ENDIF: | ||
4285 | if (CPP_PEDANTIC(pfile) | ||
4286 | && pfile->if_stack != save_if_stack) | ||
4287 | validate_else(pfile, | ||
4288 | kt->type == | ||
4289 | T_ELSE ? "#else" : "#endif"); | ||
4290 | case T_ELIF: | ||
4291 | if (pfile->if_stack == CPP_BUFFER(pfile)->if_stack) | ||
4292 | { | ||
4293 | cpp_error(pfile, | ||
4294 | "`#%s' not within a conditional", | ||
4295 | kt->name); | ||
4296 | break; | ||
4297 | } | ||
4298 | else if (pfile->if_stack == save_if_stack) | ||
4299 | goto done; /* found what we came for */ | ||
4300 | |||
4301 | if (kt->type != T_ENDIF) | ||
4302 | { | ||
4303 | if (pfile->if_stack->type == T_ELSE) | ||
4304 | cpp_error(pfile, | ||
4305 | "`#else' or `#elif' after `#else'"); | ||
4306 | pfile->if_stack->type = kt->type; | ||
4307 | break; | ||
4308 | } | ||
4309 | temp = pfile->if_stack; | ||
4310 | pfile->if_stack = temp->next; | ||
4311 | free(temp); | ||
4312 | break; | ||
4313 | default:; | ||
4314 | } | ||
4315 | break; | ||
4316 | } | ||
4317 | /* Don't let erroneous code go by. */ | ||
4318 | if (kt->length < 0 && !CPP_OPTIONS(pfile)->lang_asm | ||
4319 | && CPP_PEDANTIC(pfile)) | ||
4320 | cpp_pedwarn(pfile, "invalid preprocessor directive name"); | ||
4321 | } | ||
4322 | c = GETC(); | ||
4323 | } | ||
4324 | /* We're in the middle of a line. Skip the rest of it. */ | ||
4325 | for (;;) | ||
4326 | { | ||
4327 | switch (c) | ||
4328 | { | ||
4329 | long old; | ||
4330 | |||
4331 | case EOF: | ||
4332 | goto done; | ||
4333 | case '/': /* possible comment */ | ||
4334 | c = skip_comment(pfile, NULL); | ||
4335 | if (c == EOF) | ||
4336 | goto done; | ||
4337 | break; | ||
4338 | case '\"': | ||
4339 | case '\'': | ||
4340 | FORWARD(-1); | ||
4341 | old = CPP_WRITTEN(pfile); | ||
4342 | cpp_get_token(pfile); | ||
4343 | CPP_SET_WRITTEN(pfile, old); | ||
4344 | break; | ||
4345 | case '\\': | ||
4346 | /* Char after backslash loses its special meaning. */ | ||
4347 | if (PEEKC() == '\n') | ||
4348 | FORWARD(1); | ||
4349 | break; | ||
4350 | case '\n': | ||
4351 | goto beg_of_line; | ||
4352 | break; | ||
4353 | } | ||
4354 | c = GETC(); | ||
4355 | } | ||
4356 | done: | ||
4357 | if (CPP_OPTIONS(pfile)->output_conditionals) | ||
4358 | { | ||
4359 | static char end_failed[] = "#endfailed\n"; | ||
4360 | |||
4361 | CPP_PUTS(pfile, end_failed, sizeof(end_failed) - 1); | ||
4362 | pfile->lineno++; | ||
4363 | } | ||
4364 | pfile->only_seen_white = 1; | ||
4365 | parse_goto_mark(&line_start_mark, pfile); | ||
4366 | parse_clear_mark(&line_start_mark); | ||
4367 | } | ||
4368 | |||
4369 | /* | ||
4370 | * handle a #else directive. Do this by just continuing processing | ||
4371 | * without changing if_stack ; this is so that the error message | ||
4372 | * for missing #endif's etc. will point to the original #if. It | ||
4373 | * is possible that something different would be better. | ||
4374 | */ | ||
4375 | |||
4376 | static int | ||
4377 | do_else(cpp_reader * pfile, struct directive *keyword __UNUSED__, | ||
4378 | unsigned char *buf __UNUSED__, unsigned char *limit __UNUSED__) | ||
4379 | { | ||
4380 | cpp_buffer *ip = CPP_BUFFER(pfile); | ||
4381 | |||
4382 | if (CPP_PEDANTIC(pfile)) | ||
4383 | validate_else(pfile, "#else"); | ||
4384 | skip_rest_of_line(pfile); | ||
4385 | |||
4386 | if (pfile->if_stack == CPP_BUFFER(pfile)->if_stack) | ||
4387 | { | ||
4388 | cpp_error(pfile, "`#else' not within a conditional"); | ||
4389 | return 0; | ||
4390 | } | ||
4391 | else | ||
4392 | { | ||
4393 | /* #ifndef can't have its special treatment for containing the whole file | ||
4394 | * if it has a #else clause. */ | ||
4395 | pfile->if_stack->control_macro = 0; | ||
4396 | |||
4397 | if (pfile->if_stack->type != T_IF && pfile->if_stack->type != T_ELIF) | ||
4398 | { | ||
4399 | cpp_error(pfile, "`#else' after `#else'"); | ||
4400 | fprintf(stderr, " (matches line %d", pfile->if_stack->lineno); | ||
4401 | if (strcmp(pfile->if_stack->fname, ip->nominal_fname) != 0) | ||
4402 | fprintf(stderr, ", file %s", pfile->if_stack->fname); | ||
4403 | fprintf(stderr, ")\n"); | ||
4404 | } | ||
4405 | pfile->if_stack->type = T_ELSE; | ||
4406 | } | ||
4407 | |||
4408 | if (pfile->if_stack->if_succeeded) | ||
4409 | skip_if_group(pfile, 0); | ||
4410 | else | ||
4411 | { | ||
4412 | ++pfile->if_stack->if_succeeded; /* continue processing input */ | ||
4413 | output_line_command(pfile, 1, same_file); | ||
4414 | } | ||
4415 | return 0; | ||
4416 | } | ||
4417 | |||
4418 | /* | ||
4419 | * unstack after #endif command | ||
4420 | */ | ||
4421 | |||
4422 | static int | ||
4423 | do_endif(cpp_reader * pfile, struct directive *keyword __UNUSED__, | ||
4424 | unsigned char *buf __UNUSED__, unsigned char *limit __UNUSED__) | ||
4425 | { | ||
4426 | if (CPP_PEDANTIC(pfile)) | ||
4427 | validate_else(pfile, "#endif"); | ||
4428 | skip_rest_of_line(pfile); | ||
4429 | |||
4430 | if (pfile->if_stack == CPP_BUFFER(pfile)->if_stack) | ||
4431 | { | ||
4432 | cpp_error(pfile, "unbalanced `#endif'"); | ||
4433 | } | ||
4434 | else | ||
4435 | { | ||
4436 | IF_STACK_FRAME *temp = pfile->if_stack; | ||
4437 | |||
4438 | pfile->if_stack = temp->next; | ||
4439 | if (temp->control_macro) | ||
4440 | { | ||
4441 | /* This #endif matched a #ifndef at the start of the file. | ||
4442 | * See if it is at the end of the file. */ | ||
4443 | struct parse_marker start_mark; | ||
4444 | int c; | ||
4445 | |||
4446 | parse_set_mark(&start_mark, pfile); | ||
4447 | |||
4448 | for (;;) | ||
4449 | { | ||
4450 | cpp_skip_hspace(pfile); | ||
4451 | c = GETC(); | ||
4452 | if (c != '\n') | ||
4453 | break; | ||
4454 | } | ||
4455 | parse_goto_mark(&start_mark, pfile); | ||
4456 | parse_clear_mark(&start_mark); | ||
4457 | |||
4458 | if (c == EOF) | ||
4459 | { | ||
4460 | /* If we get here, this #endif ends a #ifndef | ||
4461 | * that contains all of the file (aside from whitespace). | ||
4462 | * Arrange not to include the file again | ||
4463 | * if the macro that was tested is defined. | ||
4464 | * | ||
4465 | * Do not do this for the top-level file in a -include or any | ||
4466 | * file in a -imacros. */ | ||
4467 | { | ||
4468 | file_name_list *ifile = pfile->all_include_files; | ||
4469 | |||
4470 | for (; ifile; ifile = ifile->next) | ||
4471 | { | ||
4472 | if (!strcmp(ifile->fname, CPP_BUFFER(pfile)->fname)) | ||
4473 | { | ||
4474 | ifile->control_macro = temp->control_macro; | ||
4475 | break; | ||
4476 | } | ||
4477 | } | ||
4478 | } | ||
4479 | } | ||
4480 | } | ||
4481 | free(temp); | ||
4482 | output_line_command(pfile, 1, same_file); | ||
4483 | } | ||
4484 | return 0; | ||
4485 | } | ||
4486 | |||
4487 | /* When an #else or #endif is found while skipping failed conditional, | ||
4488 | * if -pedantic was specified, this is called to warn about text after | ||
4489 | * the command name. P points to the first char after the command name. */ | ||
4490 | |||
4491 | static void | ||
4492 | validate_else(cpp_reader * pfile, const char *directive) | ||
4493 | { | ||
4494 | int c; | ||
4495 | |||
4496 | cpp_skip_hspace(pfile); | ||
4497 | c = PEEKC(); | ||
4498 | if (c != EOF && c != '\n') | ||
4499 | cpp_pedwarn(pfile, | ||
4500 | "text following `%s' violates ANSI standard", directive); | ||
4501 | } | ||
4502 | |||
4503 | /* Get the next token, and add it to the text in pfile->token_buffer. | ||
4504 | * Return the kind of token we got. */ | ||
4505 | |||
4506 | enum cpp_token | ||
4507 | cpp_get_token(cpp_reader * pfile) | ||
4508 | { | ||
4509 | int c, c2, c3; | ||
4510 | long old_written = 0; | ||
4511 | long start_line = 0, start_column = 0; | ||
4512 | enum cpp_token token; | ||
4513 | struct cpp_options *opts = CPP_OPTIONS(pfile); | ||
4514 | |||
4515 | CPP_BUFFER(pfile)->prev = CPP_BUFFER(pfile)->cur; | ||
4516 | get_next: | ||
4517 | c = GETC(); | ||
4518 | if (c == EOF) | ||
4519 | { | ||
4520 | handle_eof: | ||
4521 | if (CPP_BUFFER(pfile)->seen_eof) | ||
4522 | { | ||
4523 | if (cpp_pop_buffer(pfile) != CPP_NULL_BUFFER(pfile)) | ||
4524 | goto get_next; | ||
4525 | else | ||
4526 | return CPP_EOF; | ||
4527 | } | ||
4528 | else | ||
4529 | { | ||
4530 | cpp_buffer *next_buf = CPP_PREV_BUFFER(CPP_BUFFER(pfile)); | ||
4531 | |||
4532 | CPP_BUFFER(pfile)->seen_eof = 1; | ||
4533 | if (CPP_BUFFER(pfile)->nominal_fname && next_buf) | ||
4534 | { | ||
4535 | /* We're about to return from an #include file. | ||
4536 | * Emit #line information now (as part of the CPP_POP) result. | ||
4537 | * But the #line refers to the file we will pop to. */ | ||
4538 | cpp_buffer *cur_buffer = CPP_BUFFER(pfile); | ||
4539 | |||
4540 | CPP_BUFFER(pfile) = next_buf; | ||
4541 | pfile->input_stack_listing_current = 0; | ||
4542 | output_line_command(pfile, 0, leave_file); | ||
4543 | CPP_BUFFER(pfile) = cur_buffer; | ||
4544 | } | ||
4545 | return CPP_POP; | ||
4546 | } | ||
4547 | } | ||
4548 | else | ||
4549 | { | ||
4550 | switch (c) | ||
4551 | { | ||
4552 | long newlines; | ||
4553 | struct parse_marker start_mark; | ||
4554 | |||
4555 | case '/': | ||
4556 | if (PEEKC() == '=') | ||
4557 | goto op2; | ||
4558 | if (opts->put_out_comments) | ||
4559 | parse_set_mark(&start_mark, pfile); | ||
4560 | newlines = 0; | ||
4561 | cpp_buf_line_and_col(cpp_file_buffer(pfile), | ||
4562 | &start_line, &start_column); | ||
4563 | c = skip_comment(pfile, &newlines); | ||
4564 | if (opts->put_out_comments && (c == '/' || c == EOF)) | ||
4565 | parse_clear_mark(&start_mark); | ||
4566 | if (c == '/') | ||
4567 | goto randomchar; | ||
4568 | if (c == EOF) | ||
4569 | { | ||
4570 | cpp_error_with_line(pfile, start_line, start_column, | ||
4571 | "unterminated comment"); | ||
4572 | goto handle_eof; | ||
4573 | } | ||
4574 | c = '/'; /* Initial letter of comment. */ | ||
4575 | return_comment: | ||
4576 | /* Comments are equivalent to spaces. | ||
4577 | * For -traditional, a comment is equivalent to nothing. */ | ||
4578 | if (opts->put_out_comments) | ||
4579 | { | ||
4580 | cpp_buffer *pbuf = CPP_BUFFER(pfile); | ||
4581 | unsigned char *start = pbuf->buf + start_mark.position; | ||
4582 | int len = pbuf->cur - start; | ||
4583 | |||
4584 | CPP_RESERVE(pfile, 1 + len); | ||
4585 | CPP_PUTC_Q(pfile, c); | ||
4586 | CPP_PUTS_Q(pfile, start, len); | ||
4587 | pfile->lineno += newlines; | ||
4588 | parse_clear_mark(&start_mark); | ||
4589 | return CPP_COMMENT; | ||
4590 | } | ||
4591 | else if (newlines > 0) | ||
4592 | { | ||
4593 | output_line_command(pfile, 0, same_file); | ||
4594 | CPP_RESERVE(pfile, 1); | ||
4595 | CPP_PUTC_Q(pfile, ' '); | ||
4596 | return CPP_VSPACE; | ||
4597 | } | ||
4598 | else | ||
4599 | { | ||
4600 | CPP_RESERVE(pfile, 1); | ||
4601 | CPP_PUTC_Q(pfile, ' '); | ||
4602 | return CPP_HSPACE; | ||
4603 | } | ||
4604 | |||
4605 | case '#': | ||
4606 | if (!pfile->only_seen_white) | ||
4607 | goto randomchar; | ||
4608 | if (handle_directive(pfile)) | ||
4609 | return CPP_DIRECTIVE; | ||
4610 | pfile->only_seen_white = 0; | ||
4611 | return CPP_OTHER; | ||
4612 | |||
4613 | case '\"': | ||
4614 | case '\'': | ||
4615 | /* A single quoted string is treated like a double -- some | ||
4616 | * programs (e.g., troff) are perverse this way */ | ||
4617 | cpp_buf_line_and_col(cpp_file_buffer(pfile), | ||
4618 | &start_line, &start_column); | ||
4619 | old_written = CPP_WRITTEN(pfile); | ||
4620 | string: | ||
4621 | CPP_PUTC(pfile, c); | ||
4622 | while (1) | ||
4623 | { | ||
4624 | int cc = GETC(); | ||
4625 | |||
4626 | if (cc == EOF) | ||
4627 | { | ||
4628 | if (CPP_IS_MACRO_BUFFER(CPP_BUFFER(pfile))) | ||
4629 | { | ||
4630 | /* try harder: this string crosses a macro expansion | ||
4631 | * boundary. This can happen naturally if -traditional. | ||
4632 | * Otherwise, only -D can make a macro with an unmatched | ||
4633 | * quote. */ | ||
4634 | cpp_buffer *next_buf | ||
4635 | = CPP_PREV_BUFFER(CPP_BUFFER(pfile)); | ||
4636 | |||
4637 | (*CPP_BUFFER(pfile)->cleanup) | ||
4638 | (CPP_BUFFER(pfile), pfile); | ||
4639 | CPP_BUFFER(pfile) = next_buf; | ||
4640 | continue; | ||
4641 | } | ||
4642 | cpp_error_with_line(pfile, start_line, start_column, | ||
4643 | "unterminated string or character constant"); | ||
4644 | if (pfile->multiline_string_line != start_line | ||
4645 | && pfile->multiline_string_line != 0) | ||
4646 | cpp_error_with_line(pfile, | ||
4647 | pfile->multiline_string_line, | ||
4648 | -1, | ||
4649 | "possible real start of unterminated constant"); | ||
4650 | pfile->multiline_string_line = 0; | ||
4651 | break; | ||
4652 | } | ||
4653 | CPP_PUTC(pfile, cc); | ||
4654 | switch (cc) | ||
4655 | { | ||
4656 | case '\n': | ||
4657 | /* Traditionally, end of line ends a string constant with | ||
4658 | * no error. So exit the loop and record the new line. */ | ||
4659 | if (c == '\'') | ||
4660 | { | ||
4661 | cpp_error_with_line(pfile, start_line, start_column, | ||
4662 | "unterminated character constant"); | ||
4663 | goto while2end; | ||
4664 | } | ||
4665 | if (CPP_PEDANTIC(pfile) | ||
4666 | && pfile->multiline_string_line == 0) | ||
4667 | { | ||
4668 | cpp_pedwarn_with_line(pfile, start_line, | ||
4669 | start_column, | ||
4670 | "string constant runs past end of line"); | ||
4671 | } | ||
4672 | if (pfile->multiline_string_line == 0) | ||
4673 | pfile->multiline_string_line = start_line; | ||
4674 | break; | ||
4675 | |||
4676 | case '\\': | ||
4677 | cc = GETC(); | ||
4678 | if (cc == '\n') | ||
4679 | { | ||
4680 | /* Backslash newline is replaced by nothing at all. */ | ||
4681 | CPP_ADJUST_WRITTEN(pfile, -1); | ||
4682 | pfile->lineno++; | ||
4683 | } | ||
4684 | else | ||
4685 | { | ||
4686 | /* ANSI stupidly requires that in \\ the second \ | ||
4687 | * is *not* prevented from combining with a newline. */ | ||
4688 | NEWLINE_FIX1(cc); | ||
4689 | if (cc != EOF) | ||
4690 | CPP_PUTC(pfile, cc); | ||
4691 | } | ||
4692 | break; | ||
4693 | |||
4694 | case '\"': | ||
4695 | case '\'': | ||
4696 | if (cc == c) | ||
4697 | goto while2end; | ||
4698 | break; | ||
4699 | } | ||
4700 | } | ||
4701 | while2end: | ||
4702 | pfile->lineno += count_newlines(pfile->token_buffer + old_written, | ||
4703 | CPP_PWRITTEN(pfile)); | ||
4704 | pfile->only_seen_white = 0; | ||
4705 | return c == '\'' ? CPP_CHAR : CPP_STRING; | ||
4706 | |||
4707 | case '$': | ||
4708 | if (!opts->dollars_in_ident) | ||
4709 | goto randomchar; | ||
4710 | goto letter; | ||
4711 | |||
4712 | case ':': | ||
4713 | if (opts->cplusplus && PEEKC() == ':') | ||
4714 | goto op2; | ||
4715 | goto randomchar; | ||
4716 | |||
4717 | case '&': | ||
4718 | case '+': | ||
4719 | case '|': | ||
4720 | NEWLINE_FIX; | ||
4721 | c2 = PEEKC(); | ||
4722 | if (c2 == c || c2 == '=') | ||
4723 | goto op2; | ||
4724 | goto randomchar; | ||
4725 | |||
4726 | case '*': | ||
4727 | case '!': | ||
4728 | case '%': | ||
4729 | case '=': | ||
4730 | case '^': | ||
4731 | NEWLINE_FIX; | ||
4732 | if (PEEKC() == '=') | ||
4733 | goto op2; | ||
4734 | goto randomchar; | ||
4735 | |||
4736 | case '-': | ||
4737 | NEWLINE_FIX; | ||
4738 | c2 = PEEKC(); | ||
4739 | if (c2 == '-' && opts->chill) | ||
4740 | { | ||
4741 | /* Chill style comment */ | ||
4742 | if (opts->put_out_comments) | ||
4743 | parse_set_mark(&start_mark, pfile); | ||
4744 | FORWARD(1); /* Skip second '-'. */ | ||
4745 | for (;;) | ||
4746 | { | ||
4747 | c = GETC(); | ||
4748 | if (c == EOF) | ||
4749 | break; | ||
4750 | if (c == '\n') | ||
4751 | { | ||
4752 | /* Don't consider final '\n' to be part of comment. */ | ||
4753 | FORWARD(-1); | ||
4754 | break; | ||
4755 | } | ||
4756 | } | ||
4757 | c = '-'; | ||
4758 | goto return_comment; | ||
4759 | } | ||
4760 | if (c2 == '-' || c2 == '=' || c2 == '>') | ||
4761 | goto op2; | ||
4762 | goto randomchar; | ||
4763 | |||
4764 | case '<': | ||
4765 | if (pfile->parsing_include_directive) | ||
4766 | { | ||
4767 | for (;;) | ||
4768 | { | ||
4769 | CPP_PUTC(pfile, c); | ||
4770 | if (c == '>') | ||
4771 | break; | ||
4772 | c = GETC(); | ||
4773 | NEWLINE_FIX1(c); | ||
4774 | if (c == '\n' || c == EOF) | ||
4775 | { | ||
4776 | cpp_error(pfile, | ||
4777 | "missing '>' in `#include <FILENAME>'"); | ||
4778 | break; | ||
4779 | } | ||
4780 | } | ||
4781 | return CPP_STRING; | ||
4782 | } | ||
4783 | /* else fall through */ | ||
4784 | case '>': | ||
4785 | NEWLINE_FIX; | ||
4786 | c2 = PEEKC(); | ||
4787 | if (c2 == '=') | ||
4788 | goto op2; | ||
4789 | if (c2 != c) | ||
4790 | goto randomchar; | ||
4791 | FORWARD(1); | ||
4792 | CPP_RESERVE(pfile, 4); | ||
4793 | CPP_PUTC(pfile, c); | ||
4794 | CPP_PUTC(pfile, c2); | ||
4795 | NEWLINE_FIX; | ||
4796 | c3 = PEEKC(); | ||
4797 | if (c3 == '=') | ||
4798 | CPP_PUTC_Q(pfile, GETC()); | ||
4799 | CPP_NUL_TERMINATE_Q(pfile); | ||
4800 | pfile->only_seen_white = 0; | ||
4801 | return CPP_OTHER; | ||
4802 | |||
4803 | case '@': | ||
4804 | if (CPP_BUFFER(pfile)->has_escapes) | ||
4805 | { | ||
4806 | c = GETC(); | ||
4807 | // fix macro expansions starting with - losing the - | ||
4808 | if (c == '-') | ||
4809 | { | ||
4810 | CPP_PUTS(pfile, "-", 1); | ||
4811 | return CPP_OTHER; | ||
4812 | } | ||
4813 | // fix macro expansions starting with - losing the + | ||
4814 | else if (c == '+') | ||
4815 | { | ||
4816 | CPP_PUTS(pfile, "+", 1); | ||
4817 | return CPP_OTHER; | ||
4818 | } | ||
4819 | // fix macro expansions starting with - losing the . | ||
4820 | else if (c == '.') | ||
4821 | { | ||
4822 | CPP_PUTS(pfile, ".", 1); | ||
4823 | return CPP_OTHER; | ||
4824 | } | ||
4825 | else if (is_space[c]) | ||
4826 | { | ||
4827 | CPP_RESERVE(pfile, 1); | ||
4828 | if (pfile->output_escapes) | ||
4829 | CPP_PUTC_Q(pfile, '@'); | ||
4830 | return CPP_HSPACE; | ||
4831 | } | ||
4832 | } | ||
4833 | if (pfile->output_escapes) | ||
4834 | { | ||
4835 | CPP_PUTS(pfile, "@@", 2); | ||
4836 | return CPP_OTHER; | ||
4837 | } | ||
4838 | goto randomchar; | ||
4839 | |||
4840 | case '.': | ||
4841 | NEWLINE_FIX; | ||
4842 | c2 = PEEKC(); | ||
4843 | if (isdigit(c2)) | ||
4844 | { | ||
4845 | CPP_RESERVE(pfile, 2); | ||
4846 | CPP_PUTC_Q(pfile, '.'); | ||
4847 | c = GETC(); | ||
4848 | goto number; | ||
4849 | } | ||
4850 | /* FIXME - misses the case "..\\\n." */ | ||
4851 | if (c2 == '.' && PEEKN(1) == '.') | ||
4852 | { | ||
4853 | CPP_RESERVE(pfile, 4); | ||
4854 | CPP_PUTC_Q(pfile, '.'); | ||
4855 | CPP_PUTC_Q(pfile, '.'); | ||
4856 | CPP_PUTC_Q(pfile, '.'); | ||
4857 | FORWARD(2); | ||
4858 | CPP_NUL_TERMINATE_Q(pfile); | ||
4859 | pfile->only_seen_white = 0; | ||
4860 | return CPP_3DOTS; | ||
4861 | } | ||
4862 | goto randomchar; | ||
4863 | |||
4864 | op2: | ||
4865 | token = CPP_OTHER; | ||
4866 | pfile->only_seen_white = 0; | ||
4867 | op2any: | ||
4868 | CPP_RESERVE(pfile, 3); | ||
4869 | CPP_PUTC_Q(pfile, c); | ||
4870 | CPP_PUTC_Q(pfile, GETC()); | ||
4871 | CPP_NUL_TERMINATE_Q(pfile); | ||
4872 | return token; | ||
4873 | |||
4874 | case 'L': | ||
4875 | NEWLINE_FIX; | ||
4876 | c2 = PEEKC(); | ||
4877 | if ((c2 == '\'' || c2 == '\"')) | ||
4878 | { | ||
4879 | CPP_PUTC(pfile, c); | ||
4880 | c = GETC(); | ||
4881 | goto string; | ||
4882 | } | ||
4883 | goto letter; | ||
4884 | |||
4885 | case '0': | ||
4886 | case '1': | ||
4887 | case '2': | ||
4888 | case '3': | ||
4889 | case '4': | ||
4890 | case '5': | ||
4891 | case '6': | ||
4892 | case '7': | ||
4893 | case '8': | ||
4894 | case '9': | ||
4895 | number: | ||
4896 | c2 = '.'; | ||
4897 | for (;;) | ||
4898 | { | ||
4899 | CPP_RESERVE(pfile, 2); | ||
4900 | CPP_PUTC_Q(pfile, c); | ||
4901 | NEWLINE_FIX; | ||
4902 | c = PEEKC(); | ||
4903 | if (c == EOF) | ||
4904 | break; | ||
4905 | if (!is_idchar[c] && c != '.' | ||
4906 | && ((c2 != 'e' && c2 != 'E') || (c != '+' && c != '-'))) | ||
4907 | break; | ||
4908 | FORWARD(1); | ||
4909 | c2 = c; | ||
4910 | } | ||
4911 | CPP_NUL_TERMINATE_Q(pfile); | ||
4912 | pfile->only_seen_white = 0; | ||
4913 | return CPP_NUMBER; | ||
4914 | case 'b': | ||
4915 | case 'c': | ||
4916 | case 'd': | ||
4917 | case 'h': | ||
4918 | case 'o': | ||
4919 | case 'B': | ||
4920 | case 'C': | ||
4921 | case 'D': | ||
4922 | case 'H': | ||
4923 | case 'O': | ||
4924 | if (opts->chill && PEEKC() == '\'') | ||
4925 | { | ||
4926 | pfile->only_seen_white = 0; | ||
4927 | CPP_RESERVE(pfile, 2); | ||
4928 | CPP_PUTC_Q(pfile, c); | ||
4929 | CPP_PUTC_Q(pfile, '\''); | ||
4930 | FORWARD(1); | ||
4931 | for (;;) | ||
4932 | { | ||
4933 | c = GETC(); | ||
4934 | if (c == EOF) | ||
4935 | goto chill_number_eof; | ||
4936 | if (!is_idchar[c]) | ||
4937 | { | ||
4938 | if (c == '\\' && PEEKC() == '\n') | ||
4939 | { | ||
4940 | FORWARD(2); | ||
4941 | continue; | ||
4942 | } | ||
4943 | break; | ||
4944 | } | ||
4945 | CPP_PUTC(pfile, c); | ||
4946 | } | ||
4947 | if (c == '\'') | ||
4948 | { | ||
4949 | CPP_RESERVE(pfile, 2); | ||
4950 | CPP_PUTC_Q(pfile, c); | ||
4951 | CPP_NUL_TERMINATE_Q(pfile); | ||
4952 | return CPP_STRING; | ||
4953 | } | ||
4954 | else | ||
4955 | { | ||
4956 | FORWARD(-1); | ||
4957 | chill_number_eof: | ||
4958 | CPP_NUL_TERMINATE(pfile); | ||
4959 | return CPP_NUMBER; | ||
4960 | } | ||
4961 | } | ||
4962 | else | ||
4963 | goto letter; | ||
4964 | case '_': | ||
4965 | case 'a': | ||
4966 | case 'e': | ||
4967 | case 'f': | ||
4968 | case 'g': | ||
4969 | case 'i': | ||
4970 | case 'j': | ||
4971 | case 'k': | ||
4972 | case 'l': | ||
4973 | case 'm': | ||
4974 | case 'n': | ||
4975 | case 'p': | ||
4976 | case 'q': | ||
4977 | case 'r': | ||
4978 | case 's': | ||
4979 | case 't': | ||
4980 | case 'u': | ||
4981 | case 'v': | ||
4982 | case 'w': | ||
4983 | case 'x': | ||
4984 | case 'y': | ||
4985 | case 'z': | ||
4986 | case 'A': | ||
4987 | case 'E': | ||
4988 | case 'F': | ||
4989 | case 'G': | ||
4990 | case 'I': | ||
4991 | case 'J': | ||
4992 | case 'K': | ||
4993 | case 'M': | ||
4994 | case 'N': | ||
4995 | case 'P': | ||
4996 | case 'Q': | ||
4997 | case 'R': | ||
4998 | case 'S': | ||
4999 | case 'T': | ||
5000 | case 'U': | ||
5001 | case 'V': | ||
5002 | case 'W': | ||
5003 | case 'X': | ||
5004 | case 'Y': | ||
5005 | case 'Z': | ||
5006 | letter: | ||
5007 | { | ||
5008 | HASHNODE *hp; | ||
5009 | char *ident; | ||
5010 | int before_name_written = CPP_WRITTEN(pfile); | ||
5011 | int ident_len; | ||
5012 | |||
5013 | parse_name(pfile, c); | ||
5014 | pfile->only_seen_white = 0; | ||
5015 | if (pfile->no_macro_expand) | ||
5016 | return CPP_NAME; | ||
5017 | ident = (char *)pfile->token_buffer + before_name_written; | ||
5018 | ident_len = CPP_PWRITTEN(pfile) - (unsigned char *)ident; | ||
5019 | hp = cpp_lookup(ident, ident_len, -1); | ||
5020 | if (!hp) | ||
5021 | return CPP_NAME; | ||
5022 | if (hp->type == T_DISABLED) | ||
5023 | { | ||
5024 | if (pfile->output_escapes) | ||
5025 | { /* Return "@-IDENT", followed by '\0'. */ | ||
5026 | int i; | ||
5027 | |||
5028 | CPP_RESERVE(pfile, 3); | ||
5029 | ident = | ||
5030 | (char *)pfile->token_buffer + before_name_written; | ||
5031 | CPP_ADJUST_WRITTEN(pfile, 2); | ||
5032 | for (i = ident_len; i >= 0; i--) | ||
5033 | ident[i + 2] = ident[i]; | ||
5034 | ident[0] = '@'; | ||
5035 | ident[1] = '-'; | ||
5036 | } | ||
5037 | return CPP_NAME; | ||
5038 | } | ||
5039 | /* If macro wants an arglist, verify that a '(' follows. | ||
5040 | * first skip all whitespace, copying it to the output | ||
5041 | * after the macro name. Then, if there is no '(', | ||
5042 | * decide this is not a macro call and leave things that way. */ | ||
5043 | if (hp->type == T_MACRO && hp->value.defn->nargs >= 0) | ||
5044 | { | ||
5045 | struct parse_marker macro_mark; | ||
5046 | int is_macro_call; | ||
5047 | |||
5048 | while (CPP_IS_MACRO_BUFFER(CPP_BUFFER(pfile))) | ||
5049 | { | ||
5050 | cpp_buffer *next_buf; | ||
5051 | |||
5052 | cpp_skip_hspace(pfile); | ||
5053 | if (PEEKC() != EOF) | ||
5054 | break; | ||
5055 | next_buf = CPP_PREV_BUFFER(CPP_BUFFER(pfile)); | ||
5056 | (*CPP_BUFFER(pfile)->cleanup) (CPP_BUFFER(pfile), | ||
5057 | pfile); | ||
5058 | CPP_BUFFER(pfile) = next_buf; | ||
5059 | } | ||
5060 | parse_set_mark(¯o_mark, pfile); | ||
5061 | for (;;) | ||
5062 | { | ||
5063 | cpp_skip_hspace(pfile); | ||
5064 | c = PEEKC(); | ||
5065 | is_macro_call = c == '('; | ||
5066 | if (c != '\n') | ||
5067 | break; | ||
5068 | FORWARD(1); | ||
5069 | } | ||
5070 | if (!is_macro_call) | ||
5071 | parse_goto_mark(¯o_mark, pfile); | ||
5072 | parse_clear_mark(¯o_mark); | ||
5073 | if (!is_macro_call) | ||
5074 | return CPP_NAME; | ||
5075 | } | ||
5076 | /* This is now known to be a macro call. */ | ||
5077 | |||
5078 | /* it might not actually be a macro. */ | ||
5079 | if (hp->type != T_MACRO) | ||
5080 | { | ||
5081 | int xbuf_len; | ||
5082 | unsigned char *xbuf; | ||
5083 | |||
5084 | CPP_SET_WRITTEN(pfile, before_name_written); | ||
5085 | special_symbol(hp, pfile); | ||
5086 | xbuf_len = CPP_WRITTEN(pfile) - before_name_written; | ||
5087 | xbuf = (unsigned char *)xmalloc(xbuf_len + 1); | ||
5088 | CPP_SET_WRITTEN(pfile, before_name_written); | ||
5089 | memcpy(xbuf, CPP_PWRITTEN(pfile), xbuf_len + 1); | ||
5090 | push_macro_expansion(pfile, xbuf, xbuf_len, hp); | ||
5091 | } | ||
5092 | else | ||
5093 | { | ||
5094 | /* Expand the macro, reading arguments as needed, | ||
5095 | * and push the expansion on the input stack. */ | ||
5096 | macroexpand(pfile, hp); | ||
5097 | CPP_SET_WRITTEN(pfile, before_name_written); | ||
5098 | } | ||
5099 | |||
5100 | /* An extra "@ " is added to the end of a macro expansion | ||
5101 | * to prevent accidental token pasting. We prefer to avoid | ||
5102 | * unneeded extra spaces (for the sake of cpp-using tools like | ||
5103 | * imake). Here we remove the space if it is safe to do so. */ | ||
5104 | if (pfile->buffer->rlimit - pfile->buffer->cur >= 3 | ||
5105 | && pfile->buffer->rlimit[-2] == '@' | ||
5106 | && pfile->buffer->rlimit[-1] == ' ') | ||
5107 | { | ||
5108 | int c1 = pfile->buffer->rlimit[-3]; | ||
5109 | |||
5110 | c2 = CPP_BUF_PEEK(CPP_PREV_BUFFER(CPP_BUFFER(pfile))); | ||
5111 | |||
5112 | if (c2 == EOF || !unsafe_chars(c1, c2)) | ||
5113 | pfile->buffer->rlimit -= 2; | ||
5114 | } | ||
5115 | } | ||
5116 | goto get_next; | ||
5117 | |||
5118 | case ' ': | ||
5119 | case '\t': | ||
5120 | case '\v': | ||
5121 | case '\r': | ||
5122 | for (;;) | ||
5123 | { | ||
5124 | CPP_PUTC(pfile, c); | ||
5125 | c = PEEKC(); | ||
5126 | if (c == EOF || !is_hor_space[c]) | ||
5127 | break; | ||
5128 | FORWARD(1); | ||
5129 | } | ||
5130 | return CPP_HSPACE; | ||
5131 | |||
5132 | case '\\': | ||
5133 | c2 = PEEKC(); | ||
5134 | if (c2 != '\n') | ||
5135 | goto randomchar; | ||
5136 | token = CPP_HSPACE; | ||
5137 | goto op2any; | ||
5138 | |||
5139 | case '\n': | ||
5140 | CPP_PUTC(pfile, c); | ||
5141 | if (pfile->only_seen_white == 0) | ||
5142 | pfile->only_seen_white = 1; | ||
5143 | pfile->lineno++; | ||
5144 | output_line_command(pfile, 1, same_file); | ||
5145 | return CPP_VSPACE; | ||
5146 | |||
5147 | case '(': | ||
5148 | token = CPP_LPAREN; | ||
5149 | goto char1; | ||
5150 | case ')': | ||
5151 | token = CPP_RPAREN; | ||
5152 | goto char1; | ||
5153 | case '{': | ||
5154 | token = CPP_LBRACE; | ||
5155 | goto char1; | ||
5156 | case '}': | ||
5157 | token = CPP_RBRACE; | ||
5158 | goto char1; | ||
5159 | case ',': | ||
5160 | token = CPP_COMMA; | ||
5161 | goto char1; | ||
5162 | case ';': | ||
5163 | token = CPP_SEMICOLON; | ||
5164 | goto char1; | ||
5165 | |||
5166 | randomchar: | ||
5167 | default: | ||
5168 | token = CPP_OTHER; | ||
5169 | char1: | ||
5170 | pfile->only_seen_white = 0; | ||
5171 | CPP_PUTC(pfile, c); | ||
5172 | return token; | ||
5173 | } | ||
5174 | } | ||
5175 | } | ||
5176 | |||
5177 | #if 0 /* Unused */ | ||
5178 | /* Like cpp_get_token, but skip spaces and comments. */ | ||
5179 | enum cpp_token | ||
5180 | cpp_get_non_space_token(cpp_reader * pfile) | ||
5181 | { | ||
5182 | int old_written = CPP_WRITTEN(pfile); | ||
5183 | |||
5184 | for (;;) | ||
5185 | { | ||
5186 | enum cpp_token token = cpp_get_token(pfile); | ||
5187 | |||
5188 | if (token != CPP_COMMENT && token != CPP_POP | ||
5189 | && token != CPP_HSPACE && token != CPP_VSPACE) | ||
5190 | return token; | ||
5191 | CPP_SET_WRITTEN(pfile, old_written); | ||
5192 | } | ||
5193 | } | ||
5194 | #endif | ||
5195 | |||
5196 | /* Parse an identifier starting with C. */ | ||
5197 | |||
5198 | int | ||
5199 | parse_name(cpp_reader * pfile, int c) | ||
5200 | { | ||
5201 | for (;;) | ||
5202 | { | ||
5203 | if (!is_idchar[c]) | ||
5204 | { | ||
5205 | if (c == '\\' && PEEKC() == '\n') | ||
5206 | { | ||
5207 | FORWARD(2); | ||
5208 | continue; | ||
5209 | } | ||
5210 | FORWARD(-1); | ||
5211 | break; | ||
5212 | } | ||
5213 | CPP_RESERVE(pfile, 2); /* One more for final NUL. */ | ||
5214 | CPP_PUTC_Q(pfile, c); | ||
5215 | c = GETC(); | ||
5216 | if (c == EOF) | ||
5217 | break; | ||
5218 | } | ||
5219 | CPP_NUL_TERMINATE_Q(pfile); | ||
5220 | return 1; | ||
5221 | } | ||
5222 | |||
5223 | /* Maintain and search list of included files, for #import. */ | ||
5224 | |||
5225 | /* Hash a file name for import_hash_table. */ | ||
5226 | |||
5227 | static int | ||
5228 | import_hash(char *f) | ||
5229 | { | ||
5230 | int val = 0; | ||
5231 | |||
5232 | while (*f) | ||
5233 | val += *f++; | ||
5234 | return (val % IMPORT_HASH_SIZE); | ||
5235 | } | ||
5236 | |||
5237 | /* Search for file FILENAME in import_hash_table. | ||
5238 | * Return -2 if found, either a matching name or a matching inode. | ||
5239 | * Otherwise, open the file and return a file descriptor if successful | ||
5240 | * or -1 if unsuccessful. */ | ||
5241 | |||
5242 | static int | ||
5243 | lookup_import(cpp_reader * pfile, char *filename, file_name_list * searchptr) | ||
5244 | { | ||
5245 | struct import_file *i; | ||
5246 | int h; | ||
5247 | int hashval; | ||
5248 | struct stat sb; | ||
5249 | int fd; | ||
5250 | |||
5251 | hashval = import_hash(filename); | ||
5252 | |||
5253 | /* Attempt to find file in list of already included files */ | ||
5254 | i = pfile->import_hash_table[hashval]; | ||
5255 | |||
5256 | while (i) | ||
5257 | { | ||
5258 | if (!strcmp(filename, i->name)) | ||
5259 | return -2; /* return found */ | ||
5260 | i = i->next; | ||
5261 | } | ||
5262 | /* Open it and try a match on inode/dev */ | ||
5263 | fd = open_include_file(pfile, filename, searchptr); | ||
5264 | if (fd < 0) | ||
5265 | return fd; | ||
5266 | fstat(fd, &sb); | ||
5267 | for (h = 0; h < IMPORT_HASH_SIZE; h++) | ||
5268 | { | ||
5269 | i = pfile->import_hash_table[h]; | ||
5270 | while (i) | ||
5271 | { | ||
5272 | /* Compare the inode and the device. | ||
5273 | * Supposedly on some systems the inode is not a scalar. */ | ||
5274 | if (!memcmp | ||
5275 | ((char *)&i->inode, (char *)&sb.st_ino, sizeof(sb.st_ino)) | ||
5276 | && i->dev == sb.st_dev) | ||
5277 | { | ||
5278 | close(fd); | ||
5279 | return -2; /* return found */ | ||
5280 | } | ||
5281 | i = i->next; | ||
5282 | } | ||
5283 | } | ||
5284 | return fd; /* Not found, return open file */ | ||
5285 | } | ||
5286 | |||
5287 | /* Add the file FNAME, open on descriptor FD, to import_hash_table. */ | ||
5288 | |||
5289 | static void | ||
5290 | add_import(cpp_reader * pfile, int fd, char *fname) | ||
5291 | { | ||
5292 | struct import_file *i; | ||
5293 | int hashval; | ||
5294 | struct stat sb; | ||
5295 | |||
5296 | hashval = import_hash(fname); | ||
5297 | fstat(fd, &sb); | ||
5298 | i = (struct import_file *)xmalloc(sizeof(struct import_file)); | ||
5299 | |||
5300 | i->name = (char *)xmalloc(strlen(fname) + 1); | ||
5301 | strcpy(i->name, fname); | ||
5302 | memcpy((char *)&i->inode, (char *)&sb.st_ino, sizeof(sb.st_ino)); | ||
5303 | i->dev = sb.st_dev; | ||
5304 | i->next = pfile->import_hash_table[hashval]; | ||
5305 | pfile->import_hash_table[hashval] = i; | ||
5306 | } | ||
5307 | |||
5308 | /* The file_name_map structure holds a mapping of file names for a | ||
5309 | * particular directory. This mapping is read from the file named | ||
5310 | * FILE_NAME_MAP_FILE in that directory. Such a file can be used to | ||
5311 | * map filenames on a file system with severe filename restrictions, | ||
5312 | * such as DOS. The format of the file name map file is just a series | ||
5313 | * of lines with two tokens on each line. The first token is the name | ||
5314 | * to map, and the second token is the actual name to use. */ | ||
5315 | |||
5316 | struct file_name_map { | ||
5317 | struct file_name_map *map_next; | ||
5318 | char *map_from; | ||
5319 | char *map_to; | ||
5320 | }; | ||
5321 | |||
5322 | #if USE_FILE_NAME_MAPS | ||
5323 | |||
5324 | #define FILE_NAME_MAP_FILE "header.gcc" | ||
5325 | |||
5326 | /* Read a space delimited string of unlimited length from a stdio | ||
5327 | * file. */ | ||
5328 | |||
5329 | static char * | ||
5330 | read_filename_string(int ch, FILE * f) | ||
5331 | { | ||
5332 | char *alloc, *set; | ||
5333 | int len; | ||
5334 | |||
5335 | len = 20; | ||
5336 | set = alloc = (char *)xmalloc(len + 1); | ||
5337 | if (!is_space[ch]) | ||
5338 | { | ||
5339 | *set++ = ch; | ||
5340 | while ((ch = getc(f)) != EOF && !is_space[ch]) | ||
5341 | { | ||
5342 | if (set - alloc == len) | ||
5343 | { | ||
5344 | len *= 2; | ||
5345 | alloc = (char *)xrealloc(alloc, len + 1); | ||
5346 | set = alloc + len / 2; | ||
5347 | } | ||
5348 | *set++ = ch; | ||
5349 | } | ||
5350 | } | ||
5351 | *set = '\0'; | ||
5352 | ungetc(ch, f); | ||
5353 | return alloc; | ||
5354 | } | ||
5355 | |||
5356 | /* This structure holds a linked list of file name maps, one per directory. */ | ||
5357 | struct file_name_map_list { | ||
5358 | struct file_name_map_list *map_list_next; | ||
5359 | char *map_list_name; | ||
5360 | struct file_name_map *map_list_map; | ||
5361 | }; | ||
5362 | |||
5363 | /* Read the file name map file for DIRNAME. */ | ||
5364 | |||
5365 | static struct file_name_map * | ||
5366 | read_name_map(cpp_reader * pfile, const char *dirname) | ||
5367 | { | ||
5368 | struct file_name_map_list *map_list_ptr; | ||
5369 | char *name; | ||
5370 | FILE *f; | ||
5371 | |||
5372 | for (map_list_ptr = CPP_OPTIONS(pfile)->map_list; map_list_ptr; | ||
5373 | map_list_ptr = map_list_ptr->map_list_next) | ||
5374 | if (!strcmp(map_list_ptr->map_list_name, dirname)) | ||
5375 | return map_list_ptr->map_list_map; | ||
5376 | |||
5377 | map_list_ptr = | ||
5378 | ((struct file_name_map_list *)xmalloc(sizeof(struct file_name_map_list))); | ||
5379 | |||
5380 | map_list_ptr->map_list_name = savestring(dirname); | ||
5381 | map_list_ptr->map_list_map = NULL; | ||
5382 | |||
5383 | name = (char *)alloca(strlen(dirname) + strlen(FILE_NAME_MAP_FILE) + 2); | ||
5384 | strcpy(name, dirname); | ||
5385 | if (*dirname) | ||
5386 | strcat(name, "/"); | ||
5387 | strcat(name, FILE_NAME_MAP_FILE); | ||
5388 | #ifndef __EMX__ | ||
5389 | f = fopen(name, "rb"); | ||
5390 | #else | ||
5391 | f = fopen(name, "rtb"); | ||
5392 | #endif | ||
5393 | if (!f) | ||
5394 | map_list_ptr->map_list_map = NULL; | ||
5395 | else | ||
5396 | { | ||
5397 | int ch; | ||
5398 | int dirlen = strlen(dirname); | ||
5399 | |||
5400 | while ((ch = getc(f)) != EOF) | ||
5401 | { | ||
5402 | char *from, *to; | ||
5403 | struct file_name_map *ptr; | ||
5404 | |||
5405 | if (is_space[ch]) | ||
5406 | continue; | ||
5407 | from = read_filename_string(ch, f); | ||
5408 | while ((ch = getc(f)) != EOF && is_hor_space[ch]); | ||
5409 | to = read_filename_string(ch, f); | ||
5410 | |||
5411 | ptr = | ||
5412 | ((struct file_name_map *)xmalloc(sizeof(struct file_name_map))); | ||
5413 | |||
5414 | ptr->map_from = from; | ||
5415 | |||
5416 | /* Make the real filename absolute. */ | ||
5417 | if (*to == '/') | ||
5418 | ptr->map_to = to; | ||
5419 | else | ||
5420 | { | ||
5421 | ptr->map_to = (char *)xmalloc(dirlen + strlen(to) + 2); | ||
5422 | strcpy(ptr->map_to, dirname); | ||
5423 | ptr->map_to[dirlen] = '/'; | ||
5424 | strcpy(ptr->map_to + dirlen + 1, to); | ||
5425 | free(to); | ||
5426 | } | ||
5427 | |||
5428 | ptr->map_next = map_list_ptr->map_list_map; | ||
5429 | map_list_ptr->map_list_map = ptr; | ||
5430 | |||
5431 | while ((ch = getc(f)) != '\n') | ||
5432 | if (ch == EOF) | ||
5433 | break; | ||
5434 | } | ||
5435 | fclose(f); | ||
5436 | } | ||
5437 | |||
5438 | map_list_ptr->map_list_next = CPP_OPTIONS(pfile)->map_list; | ||
5439 | CPP_OPTIONS(pfile)->map_list = map_list_ptr; | ||
5440 | |||
5441 | return map_list_ptr->map_list_map; | ||
5442 | } | ||
5443 | |||
5444 | /* Try to open include file FILENAME. SEARCHPTR is the directory | ||
5445 | * being tried from the include file search path. This function maps | ||
5446 | * filenames on file systems based on information read by | ||
5447 | * read_name_map. */ | ||
5448 | |||
5449 | static int | ||
5450 | open_include_file(cpp_reader * pfile, char *filename, | ||
5451 | file_name_list * searchptr) | ||
5452 | { | ||
5453 | struct file_name_map *map; | ||
5454 | const char *from; | ||
5455 | const char *p, *dir; | ||
5456 | |||
5457 | if (searchptr && !searchptr->got_name_map) | ||
5458 | { | ||
5459 | searchptr->name_map = read_name_map(pfile, | ||
5460 | searchptr->fname | ||
5461 | ? searchptr->fname : "."); | ||
5462 | searchptr->got_name_map = 1; | ||
5463 | } | ||
5464 | /* First check the mapping for the directory we are using. */ | ||
5465 | if (searchptr && searchptr->name_map) | ||
5466 | { | ||
5467 | from = filename; | ||
5468 | if (searchptr->fname) | ||
5469 | from += strlen(searchptr->fname) + 1; | ||
5470 | for (map = searchptr->name_map; map; map = map->map_next) | ||
5471 | { | ||
5472 | if (!strcmp(map->map_from, from)) | ||
5473 | { | ||
5474 | /* Found a match. */ | ||
5475 | return open(map->map_to, O_RDONLY | O_BINARY, 0666); | ||
5476 | } | ||
5477 | } | ||
5478 | } | ||
5479 | /* Try to find a mapping file for the particular directory we are | ||
5480 | * looking in. Thus #include <sys/types.h> will look up sys/types.h | ||
5481 | * in /usr/include/header.gcc and look up types.h in | ||
5482 | * /usr/include/sys/header.gcc. */ | ||
5483 | p = strrchr(filename, '/'); | ||
5484 | if (!p) | ||
5485 | p = filename; | ||
5486 | if (searchptr | ||
5487 | && searchptr->fname | ||
5488 | && strlen(searchptr->fname) == (unsigned)(p - filename) | ||
5489 | && !strncmp(searchptr->fname, filename, p - filename)) | ||
5490 | { | ||
5491 | /* FILENAME is in SEARCHPTR, which we've already checked. */ | ||
5492 | return open(filename, O_RDONLY | O_BINARY, 0666); | ||
5493 | } | ||
5494 | if (p == filename) | ||
5495 | { | ||
5496 | dir = "."; | ||
5497 | from = filename; | ||
5498 | } | ||
5499 | else | ||
5500 | { | ||
5501 | char *s; | ||
5502 | |||
5503 | s = (char *)alloca(p - filename + 1); | ||
5504 | memcpy(s, filename, p - filename); | ||
5505 | s[p - filename] = '\0'; | ||
5506 | from = p + 1; | ||
5507 | dir = s; | ||
5508 | } | ||
5509 | for (map = read_name_map(pfile, dir); map; map = map->map_next) | ||
5510 | if (!strcmp(map->map_from, from)) | ||
5511 | return open(map->map_to, O_RDONLY | O_BINARY, 0666); | ||
5512 | |||
5513 | return open(filename, O_RDONLY | O_BINARY, 0666); | ||
5514 | } | ||
5515 | |||
5516 | #else | ||
5517 | |||
5518 | static int | ||
5519 | open_include_file(cpp_reader * pfile __UNUSED__, char *filename, | ||
5520 | file_name_list * searchptr __UNUSED__) | ||
5521 | { | ||
5522 | return open(filename, O_RDONLY | O_BINARY, 0666); | ||
5523 | } | ||
5524 | |||
5525 | #endif /* USE_FILE_NAME_MAPS */ | ||
5526 | |||
5527 | static int | ||
5528 | dos2unix(cpp_buffer *fp, int length) | ||
5529 | { | ||
5530 | unsigned char *tbuf; | ||
5531 | int nlen = 0, i; | ||
5532 | |||
5533 | tbuf = xmalloc(length + 4); | ||
5534 | if (!tbuf) return length; | ||
5535 | for (i = 0; i < length; i++) | ||
5536 | { | ||
5537 | if ((fp->buf[i] == '\r') && | ||
5538 | (fp->buf[i + 1] == '\n')) | ||
5539 | { | ||
5540 | // skip \r in \r\n | ||
5541 | continue; | ||
5542 | } | ||
5543 | tbuf[nlen] = fp->buf[i]; | ||
5544 | nlen++; | ||
5545 | } | ||
5546 | tbuf[nlen] = 0; | ||
5547 | |||
5548 | free(fp->buf); | ||
5549 | fp->buf = tbuf; | ||
5550 | return nlen; | ||
5551 | } | ||
5552 | |||
5553 | /* Process the contents of include file FNAME, already open on descriptor F, | ||
5554 | * with output to OP. | ||
5555 | * SYSTEM_HEADER_P is 1 if this file resides in any one of the known | ||
5556 | * "system" include directories (as decided by the `is_system_include' | ||
5557 | * function above). | ||
5558 | * DIRPTR is the link in the dir path through which this file was found, | ||
5559 | * or 0 if the file name was absolute or via the current directory. | ||
5560 | * Return 1 on success, 0 on failure. | ||
5561 | * | ||
5562 | * The caller is responsible for the cpp_push_buffer. */ | ||
5563 | |||
5564 | static int | ||
5565 | finclude(cpp_reader * pfile, int f, const char *fname, int system_header_p, | ||
5566 | file_name_list * dirptr) | ||
5567 | { | ||
5568 | int st_mode; | ||
5569 | long st_size; | ||
5570 | long i; | ||
5571 | int length; | ||
5572 | cpp_buffer *fp; /* For input stack frame */ | ||
5573 | |||
5574 | if (file_size_and_mode(f, &st_mode, &st_size) < 0) | ||
5575 | { | ||
5576 | cpp_perror_with_name(pfile, fname); | ||
5577 | close(f); | ||
5578 | cpp_pop_buffer(pfile); | ||
5579 | return 0; | ||
5580 | } | ||
5581 | fp = CPP_BUFFER(pfile); | ||
5582 | fp->nominal_fname = fp->fname = fname; | ||
5583 | fp->dir = dirptr; | ||
5584 | fp->system_header_p = system_header_p; | ||
5585 | fp->lineno = 1; | ||
5586 | fp->colno = 1; | ||
5587 | fp->cleanup = file_cleanup; | ||
5588 | |||
5589 | if (S_ISREG(st_mode)) | ||
5590 | { | ||
5591 | fp->buf = (unsigned char *)xmalloc(st_size + 2); | ||
5592 | /* Read the file contents, knowing that st_size is an upper bound | ||
5593 | * on the number of bytes we can read. */ | ||
5594 | length = safe_read(f, (char *)fp->buf, st_size); | ||
5595 | length = dos2unix(fp, length); | ||
5596 | |||
5597 | fp->alimit = fp->buf + st_size + 2; | ||
5598 | fp->cur = fp->buf; | ||
5599 | fp->rlimit = fp->buf + length; | ||
5600 | if (length < 0) | ||
5601 | goto nope; | ||
5602 | } | ||
5603 | else if (S_ISDIR(st_mode)) | ||
5604 | { | ||
5605 | cpp_error(pfile, "directory `%s' specified in #include", fname); | ||
5606 | close(f); | ||
5607 | return 0; | ||
5608 | } | ||
5609 | else | ||
5610 | { | ||
5611 | /* Cannot count its file size before reading. | ||
5612 | * First read the entire file into heap and | ||
5613 | * copy them into buffer on stack. */ | ||
5614 | |||
5615 | int bsize = 2000; | ||
5616 | |||
5617 | st_size = 0; | ||
5618 | fp->buf = (unsigned char *)xmalloc(bsize + 2); | ||
5619 | |||
5620 | for (;;) | ||
5621 | { | ||
5622 | i = safe_read(f, (char *)(fp->buf + st_size), bsize - st_size); | ||
5623 | if (i < 0) | ||
5624 | goto nope; /* error! */ | ||
5625 | st_size += i; | ||
5626 | if (st_size != bsize) | ||
5627 | break; /* End of file */ | ||
5628 | bsize *= 2; | ||
5629 | fp->buf = (unsigned char *)xrealloc(fp->buf, bsize + 2); | ||
5630 | } | ||
5631 | length = st_size; | ||
5632 | length = dos2unix(fp, length); | ||
5633 | } | ||
5634 | |||
5635 | if ((length > 0 && fp->buf[length - 1] != '\n') | ||
5636 | /* Backslash-newline at end is not good enough. */ | ||
5637 | || (length > 1 && fp->buf[length - 2] == '\\')) | ||
5638 | { | ||
5639 | fp->buf[length++] = '\n'; | ||
5640 | } | ||
5641 | fp->buf[length] = '\0'; | ||
5642 | |||
5643 | fp->rlimit = fp->buf + length; | ||
5644 | |||
5645 | /* Close descriptor now, so nesting does not use lots of descriptors. */ | ||
5646 | close(f); | ||
5647 | |||
5648 | /* Must do this before calling trigraph_pcp, so that the correct file name | ||
5649 | * will be printed in warning messages. */ | ||
5650 | |||
5651 | pfile->input_stack_listing_current = 0; | ||
5652 | |||
5653 | return 1; | ||
5654 | |||
5655 | nope: | ||
5656 | |||
5657 | cpp_perror_with_name(pfile, fname); | ||
5658 | close(f); | ||
5659 | free(fp->buf); | ||
5660 | return 1; | ||
5661 | } | ||
5662 | |||
5663 | int | ||
5664 | push_parse_file(cpp_reader * pfile, const char *fname) | ||
5665 | { | ||
5666 | struct cpp_options *opts = CPP_OPTIONS(pfile); | ||
5667 | struct cpp_pending *pend; | ||
5668 | char *p; | ||
5669 | int f; | ||
5670 | cpp_buffer *fp; | ||
5671 | |||
5672 | /* The code looks at the defaults through this pointer, rather than through | ||
5673 | * the constant structure above. This pointer gets changed if an environment | ||
5674 | * variable specifies other defaults. */ | ||
5675 | struct default_include *include_defaults = include_defaults_array; | ||
5676 | |||
5677 | /* Add dirs from CPATH after dirs from -I. */ | ||
5678 | /* There seems to be confusion about what CPATH should do, | ||
5679 | * so for the moment it is not documented. */ | ||
5680 | /* Some people say that CPATH should replace the standard include dirs, | ||
5681 | * but that seems pointless: it comes before them, so it overrides them | ||
5682 | * anyway. */ | ||
5683 | p = (char *)getenv("CPATH"); | ||
5684 | if (p && !opts->no_standard_includes) | ||
5685 | path_include(pfile, p); | ||
5686 | |||
5687 | /* Now that dollars_in_ident is known, initialize is_idchar. */ | ||
5688 | initialize_char_syntax(opts); | ||
5689 | |||
5690 | /* Do partial setup of input buffer for the sake of generating | ||
5691 | * early #line directives (when -g is in effect). */ | ||
5692 | fp = cpp_push_buffer(pfile, NULL, 0); | ||
5693 | if (!opts->in_fname) | ||
5694 | opts->in_fname = ""; | ||
5695 | fp->nominal_fname = fp->fname = opts->in_fname; | ||
5696 | fp->lineno = 0; | ||
5697 | |||
5698 | /* Install __LINE__, etc. Must follow initialize_char_syntax | ||
5699 | * and option processing. */ | ||
5700 | initialize_builtins(pfile); | ||
5701 | |||
5702 | /* Do standard #defines and assertions | ||
5703 | * that identify system and machine type. */ | ||
5704 | |||
5705 | if (!opts->inhibit_predefs) | ||
5706 | { | ||
5707 | p = (char *)alloca(strlen(predefs) + 1); | ||
5708 | |||
5709 | strcpy(p, predefs); | ||
5710 | while (*p) | ||
5711 | { | ||
5712 | char *q; | ||
5713 | |||
5714 | while (*p == ' ' || *p == '\t') | ||
5715 | p++; | ||
5716 | /* Handle -D options. */ | ||
5717 | if (p[0] == '-' && p[1] == 'D') | ||
5718 | { | ||
5719 | q = &p[2]; | ||
5720 | while (*p && *p != ' ' && *p != '\t') | ||
5721 | p++; | ||
5722 | if (*p != 0) | ||
5723 | *p++ = 0; | ||
5724 | if (opts->debug_output) | ||
5725 | output_line_command(pfile, 0, same_file); | ||
5726 | cpp_define(pfile, (unsigned char *)q); | ||
5727 | while (*p == ' ' || *p == '\t') | ||
5728 | p++; | ||
5729 | } | ||
5730 | else if (p[0] == '-' && p[1] == 'A') | ||
5731 | { | ||
5732 | /* Handle -A options (assertions). */ | ||
5733 | char *assertion; | ||
5734 | char *past_name; | ||
5735 | char *value; | ||
5736 | char *past_value; | ||
5737 | char *termination; | ||
5738 | int save_char; | ||
5739 | |||
5740 | assertion = &p[2]; | ||
5741 | past_name = assertion; | ||
5742 | /* Locate end of name. */ | ||
5743 | while (*past_name && *past_name != ' ' | ||
5744 | && *past_name != '\t' && *past_name != '(') | ||
5745 | past_name++; | ||
5746 | /* Locate `(' at start of value. */ | ||
5747 | value = past_name; | ||
5748 | while (*value && (*value == ' ' || *value == '\t')) | ||
5749 | value++; | ||
5750 | if (*value++ != '(') | ||
5751 | abort(); | ||
5752 | while (*value && (*value == ' ' || *value == '\t')) | ||
5753 | value++; | ||
5754 | past_value = value; | ||
5755 | /* Locate end of value. */ | ||
5756 | while (*past_value && *past_value != ' ' | ||
5757 | && *past_value != '\t' && *past_value != ')') | ||
5758 | past_value++; | ||
5759 | termination = past_value; | ||
5760 | while (*termination | ||
5761 | && (*termination == ' ' || *termination == '\t')) | ||
5762 | termination++; | ||
5763 | if (*termination++ != ')') | ||
5764 | abort(); | ||
5765 | if (*termination && *termination != ' ' | ||
5766 | && *termination != '\t') | ||
5767 | abort(); | ||
5768 | /* Temporarily null-terminate the value. */ | ||
5769 | save_char = *termination; | ||
5770 | *termination = '\0'; | ||
5771 | /* Install the assertion. */ | ||
5772 | make_assertion(pfile, "-A", assertion); | ||
5773 | *termination = (char)save_char; | ||
5774 | p = termination; | ||
5775 | while (*p == ' ' || *p == '\t') | ||
5776 | p++; | ||
5777 | } | ||
5778 | else | ||
5779 | { | ||
5780 | abort(); | ||
5781 | } | ||
5782 | } | ||
5783 | } | ||
5784 | /* Now handle the command line options. */ | ||
5785 | |||
5786 | /* Do -U's, -D's and -A's in the order they were seen. */ | ||
5787 | /* First reverse the list. */ | ||
5788 | opts->pending = nreverse_pending(opts->pending); | ||
5789 | |||
5790 | for (pend = opts->pending; pend; pend = pend->next) | ||
5791 | { | ||
5792 | if (pend->cmd && pend->cmd[0] == '-') | ||
5793 | { | ||
5794 | switch (pend->cmd[1]) | ||
5795 | { | ||
5796 | case 'U': | ||
5797 | if (opts->debug_output) | ||
5798 | output_line_command(pfile, 0, same_file); | ||
5799 | do_undef(pfile, NULL, (unsigned char *)pend->arg, | ||
5800 | (unsigned char *)pend->arg + strlen(pend->arg)); | ||
5801 | break; | ||
5802 | case 'D': | ||
5803 | if (opts->debug_output) | ||
5804 | output_line_command(pfile, 0, same_file); | ||
5805 | cpp_define(pfile, (unsigned char *)pend->arg); | ||
5806 | break; | ||
5807 | case 'A': | ||
5808 | make_assertion(pfile, "-A", pend->arg); | ||
5809 | break; | ||
5810 | } | ||
5811 | } | ||
5812 | } | ||
5813 | |||
5814 | opts->done_initializing = 1; | ||
5815 | |||
5816 | { /* read the appropriate environment variable and if it exists | ||
5817 | * replace include_defaults with the listed path. */ | ||
5818 | char *epath = 0; | ||
5819 | |||
5820 | switch ((opts->objc << 1) + opts->cplusplus) | ||
5821 | { | ||
5822 | case 0: | ||
5823 | epath = getenv("C_INCLUDE_PATH"); | ||
5824 | break; | ||
5825 | case 1: | ||
5826 | epath = getenv("CPLUS_INCLUDE_PATH"); | ||
5827 | break; | ||
5828 | case 2: | ||
5829 | epath = getenv("OBJC_INCLUDE_PATH"); | ||
5830 | break; | ||
5831 | case 3: | ||
5832 | epath = getenv("OBJCPLUS_INCLUDE_PATH"); | ||
5833 | break; | ||
5834 | } | ||
5835 | /* If the environment var for this language is set, | ||
5836 | * add to the default list of include directories. */ | ||
5837 | if (epath) | ||
5838 | { | ||
5839 | char *nstore = (char *)alloca(strlen(epath) + 2); | ||
5840 | int num_dirs; | ||
5841 | char *startp, *endp; | ||
5842 | |||
5843 | for (num_dirs = 1, startp = epath; *startp; startp++) | ||
5844 | if (*startp == PATH_SEPARATOR) | ||
5845 | num_dirs++; | ||
5846 | include_defaults | ||
5847 | = (struct default_include *)xmalloc((num_dirs | ||
5848 | * | ||
5849 | sizeof(struct | ||
5850 | default_include)) + | ||
5851 | sizeof | ||
5852 | (include_defaults_array)); | ||
5853 | |||
5854 | startp = endp = epath; | ||
5855 | num_dirs = 0; | ||
5856 | while (1) | ||
5857 | { | ||
5858 | /* Handle cases like c:/usr/lib:d:/gcc/lib */ | ||
5859 | if ((*endp == PATH_SEPARATOR) || *endp == 0) | ||
5860 | { | ||
5861 | strncpy(nstore, startp, endp - startp); | ||
5862 | if (endp == startp) | ||
5863 | strcpy(nstore, "."); | ||
5864 | else | ||
5865 | nstore[endp - startp] = '\0'; | ||
5866 | |||
5867 | include_defaults[num_dirs].fname = savestring(nstore); | ||
5868 | include_defaults[num_dirs].cplusplus = opts->cplusplus; | ||
5869 | include_defaults[num_dirs].cxx_aware = 1; | ||
5870 | num_dirs++; | ||
5871 | if (*endp == '\0') | ||
5872 | break; | ||
5873 | endp = startp = endp + 1; | ||
5874 | } | ||
5875 | else | ||
5876 | endp++; | ||
5877 | } | ||
5878 | /* Put the usual defaults back in at the end. */ | ||
5879 | memcpy((char *)&include_defaults[num_dirs], | ||
5880 | (char *)include_defaults_array, | ||
5881 | sizeof(include_defaults_array)); | ||
5882 | } | ||
5883 | } | ||
5884 | |||
5885 | append_include_chain(pfile, opts->before_system, opts->last_before_system); | ||
5886 | opts->first_system_include = opts->before_system; | ||
5887 | |||
5888 | /* Unless -fnostdinc, | ||
5889 | * tack on the standard include file dirs to the specified list */ | ||
5890 | if (!opts->no_standard_includes) | ||
5891 | { | ||
5892 | struct default_include *di = include_defaults; | ||
5893 | char *specd_prefix = opts->include_prefix; | ||
5894 | char *default_prefix = savestring(GCC_INCLUDE_DIR); | ||
5895 | int default_len = 0; | ||
5896 | |||
5897 | /* Remove the `include' from /usr/local/lib/gcc.../include. */ | ||
5898 | if (!strcmp(default_prefix + strlen(default_prefix) - 8, "/include")) | ||
5899 | { | ||
5900 | default_len = strlen(default_prefix) - 7; | ||
5901 | default_prefix[default_len] = 0; | ||
5902 | } | ||
5903 | /* Search "translated" versions of GNU directories. | ||
5904 | * These have /usr/local/lib/gcc... replaced by specd_prefix. */ | ||
5905 | if (specd_prefix && default_len != 0) | ||
5906 | for (di = include_defaults; di->fname; di++) | ||
5907 | { | ||
5908 | /* Some standard dirs are only for C++. */ | ||
5909 | if (!di->cplusplus | ||
5910 | || (opts->cplusplus | ||
5911 | && !opts->no_standard_cplusplus_includes)) | ||
5912 | { | ||
5913 | /* Does this dir start with the prefix? */ | ||
5914 | if (!strncmp(di->fname, default_prefix, default_len)) | ||
5915 | { | ||
5916 | /* Yes; change prefix and add to search list. */ | ||
5917 | file_name_list *new_ | ||
5918 | = | ||
5919 | (file_name_list *) xmalloc(sizeof(file_name_list)); | ||
5920 | int this_len = | ||
5921 | strlen(specd_prefix) + strlen(di->fname) - | ||
5922 | default_len; | ||
5923 | char *str = | ||
5924 | (char *)xmalloc(this_len + 1); | ||
5925 | |||
5926 | strcpy(str, specd_prefix); | ||
5927 | strcat(str, di->fname + default_len); | ||
5928 | new_->fname = str; | ||
5929 | new_->control_macro = 0; | ||
5930 | new_->c_system_include_path = !di->cxx_aware; | ||
5931 | new_->got_name_map = 0; | ||
5932 | append_include_chain(pfile, new_, new_); | ||
5933 | if (!opts->first_system_include) | ||
5934 | opts->first_system_include = new_; | ||
5935 | } | ||
5936 | } | ||
5937 | } | ||
5938 | /* Search ordinary names for GNU include directories. */ | ||
5939 | for (di = include_defaults; di->fname; di++) | ||
5940 | { | ||
5941 | /* Some standard dirs are only for C++. */ | ||
5942 | if (!di->cplusplus | ||
5943 | || (opts->cplusplus && !opts->no_standard_cplusplus_includes)) | ||
5944 | { | ||
5945 | file_name_list *new_ | ||
5946 | = (file_name_list *) xmalloc(sizeof(file_name_list)); | ||
5947 | |||
5948 | new_->control_macro = 0; | ||
5949 | new_->c_system_include_path = !di->cxx_aware; | ||
5950 | new_->fname = (char *)di->fname; | ||
5951 | new_->got_name_map = 0; | ||
5952 | append_include_chain(pfile, new_, new_); | ||
5953 | if (!opts->first_system_include) | ||
5954 | opts->first_system_include = new_; | ||
5955 | } | ||
5956 | } | ||
5957 | } | ||
5958 | /* Tack the after_include chain at the end of the include chain. */ | ||
5959 | append_include_chain(pfile, opts->after_include, opts->last_after_include); | ||
5960 | if (!opts->first_system_include) | ||
5961 | opts->first_system_include = opts->after_include; | ||
5962 | |||
5963 | /* With -v, print the list of dirs to search. */ | ||
5964 | if (opts->verbose) | ||
5965 | { | ||
5966 | file_name_list *fl; | ||
5967 | |||
5968 | fprintf(stderr, "#include \"...\" search starts here:\n"); | ||
5969 | for (fl = opts->include; fl; fl = fl->next) | ||
5970 | { | ||
5971 | if (fl == opts->first_bracket_include) | ||
5972 | fprintf(stderr, "#include <...> search starts here:\n"); | ||
5973 | fprintf(stderr, " %s\n", fl->fname); | ||
5974 | } | ||
5975 | fprintf(stderr, "End of search list.\n"); | ||
5976 | } | ||
5977 | /* Scan the -imacros files before the main input. | ||
5978 | * Much like #including them, but with no_output set | ||
5979 | * so that only their macro definitions matter. */ | ||
5980 | |||
5981 | opts->no_output++; | ||
5982 | pfile->no_record_file++; | ||
5983 | for (pend = opts->pending; pend; pend = pend->next) | ||
5984 | { | ||
5985 | if (pend->cmd && strcmp(pend->cmd, "-imacros") == 0) | ||
5986 | { | ||
5987 | int fd = open(pend->arg, O_RDONLY | O_BINARY, 0666); | ||
5988 | |||
5989 | if (fd < 0) | ||
5990 | { | ||
5991 | cpp_perror_with_name(pfile, pend->arg); | ||
5992 | return FATAL_EXIT_CODE; | ||
5993 | } | ||
5994 | cpp_push_buffer(pfile, NULL, 0); | ||
5995 | finclude(pfile, fd, pend->arg, 0, NULL); | ||
5996 | cpp_scan_buffer(pfile); | ||
5997 | } | ||
5998 | } | ||
5999 | opts->no_output--; | ||
6000 | pfile->no_record_file--; | ||
6001 | |||
6002 | /* Copy the entire contents of the main input file into | ||
6003 | * the stacked input buffer previously allocated for it. */ | ||
6004 | if (!fname || *fname == 0) | ||
6005 | { | ||
6006 | fname = ""; | ||
6007 | f = 0; | ||
6008 | } | ||
6009 | else if ((f = open(fname, O_RDONLY | O_BINARY, 0666)) < 0) | ||
6010 | cpp_pfatal_with_name(pfile, fname); | ||
6011 | |||
6012 | /* -MG doesn't select the form of output and must be specified with one of | ||
6013 | * -M or -MM. -MG doesn't make sense with -MD or -MMD since they don't | ||
6014 | * inhibit compilation. */ | ||
6015 | if (opts->print_deps_missing_files | ||
6016 | && (opts->print_deps == 0 || !opts->no_output)) | ||
6017 | cpp_fatal("-MG must be specified with one of -M or -MM"); | ||
6018 | |||
6019 | /* Either of two environment variables can specify output of deps. | ||
6020 | * Its value is either "OUTPUT_FILE" or "OUTPUT_FILE DEPS_TARGET", | ||
6021 | * where OUTPUT_FILE is the file to write deps info to | ||
6022 | * and DEPS_TARGET is the target to mention in the deps. */ | ||
6023 | |||
6024 | if (opts->print_deps == 0 | ||
6025 | && (getenv("SUNPRO_DEPENDENCIES") != 0 | ||
6026 | || getenv("DEPENDENCIES_OUTPUT") != 0)) | ||
6027 | { | ||
6028 | char *spec = getenv("DEPENDENCIES_OUTPUT"); | ||
6029 | char *s; | ||
6030 | char *output_file; | ||
6031 | |||
6032 | if (!spec) | ||
6033 | { | ||
6034 | spec = getenv("SUNPRO_DEPENDENCIES"); | ||
6035 | opts->print_deps = 2; | ||
6036 | } | ||
6037 | else | ||
6038 | opts->print_deps = 1; | ||
6039 | |||
6040 | s = spec; | ||
6041 | /* Find the space before the DEPS_TARGET, if there is one. */ | ||
6042 | /* This should use index. (mrs) */ | ||
6043 | while (*s != 0 && *s != ' ') | ||
6044 | s++; | ||
6045 | if (*s != 0) | ||
6046 | { | ||
6047 | opts->deps_target = s + 1; | ||
6048 | output_file = (char *)xmalloc(s - spec + 1); | ||
6049 | memcpy(output_file, spec, s - spec); | ||
6050 | output_file[s - spec] = 0; | ||
6051 | } | ||
6052 | else | ||
6053 | { | ||
6054 | opts->deps_target = 0; | ||
6055 | output_file = spec; | ||
6056 | } | ||
6057 | |||
6058 | opts->deps_file = output_file; | ||
6059 | opts->print_deps_append = 1; | ||
6060 | } | ||
6061 | /* For -M, print the expected object file name | ||
6062 | * as the target of this Make-rule. */ | ||
6063 | if (opts->print_deps) | ||
6064 | { | ||
6065 | pfile->deps_allocated_size = 200; | ||
6066 | pfile->deps_buffer = (char *)xmalloc(pfile->deps_allocated_size); | ||
6067 | pfile->deps_buffer[0] = 0; | ||
6068 | pfile->deps_size = 0; | ||
6069 | pfile->deps_column = 0; | ||
6070 | |||
6071 | if (opts->deps_target) | ||
6072 | deps_output(pfile, opts->deps_target, ':'); | ||
6073 | else if (*opts->in_fname == 0) | ||
6074 | deps_output(pfile, "-", ':'); | ||
6075 | else | ||
6076 | { | ||
6077 | char *q; | ||
6078 | int len; | ||
6079 | |||
6080 | /* Discard all directory prefixes from filename. */ | ||
6081 | if ((q = (char *)strrchr(opts->in_fname, '/')) | ||
6082 | #ifdef DIR_SEPARATOR | ||
6083 | && (q = strrchr(opts->in_fname, DIR_SEPARATOR)) | ||
6084 | #endif | ||
6085 | ) | ||
6086 | ++q; | ||
6087 | else | ||
6088 | q = (char *)opts->in_fname; | ||
6089 | |||
6090 | /* Copy remainder to mungable area. */ | ||
6091 | p = (char *)alloca(strlen(q) + 8); | ||
6092 | strcpy(p, q); | ||
6093 | |||
6094 | /* Output P, but remove known suffixes. */ | ||
6095 | len = strlen(p); | ||
6096 | q = p + len; | ||
6097 | if (len >= 2 && p[len - 2] == '.' && strchr("cCsSm", p[len - 1])) | ||
6098 | q = p + (len - 2); | ||
6099 | else if (len >= 3 | ||
6100 | && p[len - 3] == '.' | ||
6101 | && p[len - 2] == 'c' && p[len - 1] == 'c') | ||
6102 | q = p + (len - 3); | ||
6103 | else if (len >= 4 | ||
6104 | && p[len - 4] == '.' | ||
6105 | && p[len - 3] == 'c' | ||
6106 | && p[len - 2] == 'x' && p[len - 1] == 'x') | ||
6107 | q = p + (len - 4); | ||
6108 | else if (len >= 4 | ||
6109 | && p[len - 4] == '.' | ||
6110 | && p[len - 3] == 'c' | ||
6111 | && p[len - 2] == 'p' && p[len - 1] == 'p') | ||
6112 | q = p + (len - 4); | ||
6113 | |||
6114 | /* Supply our own suffix. */ | ||
6115 | strcpy(q, ".o"); | ||
6116 | |||
6117 | deps_output(pfile, p, ':'); | ||
6118 | deps_output(pfile, opts->in_fname, ' '); | ||
6119 | } | ||
6120 | } | ||
6121 | |||
6122 | /* Scan the -include files before the main input. | ||
6123 | * We push these in reverse order, so that the first one is handled first. */ | ||
6124 | |||
6125 | pfile->no_record_file++; | ||
6126 | opts->pending = nreverse_pending(opts->pending); | ||
6127 | for (pend = opts->pending; pend; pend = pend->next) | ||
6128 | { | ||
6129 | if (pend->cmd && strcmp(pend->cmd, "-include") == 0) | ||
6130 | { | ||
6131 | int fd = open(pend->arg, O_RDONLY | O_BINARY, 0666); | ||
6132 | |||
6133 | if (fd < 0) | ||
6134 | { | ||
6135 | cpp_perror_with_name(pfile, pend->arg); | ||
6136 | return FATAL_EXIT_CODE; | ||
6137 | } | ||
6138 | cpp_push_buffer(pfile, NULL, 0); | ||
6139 | finclude(pfile, fd, pend->arg, 0, NULL); | ||
6140 | } | ||
6141 | } | ||
6142 | pfile->no_record_file--; | ||
6143 | |||
6144 | /* Free the pending list. */ | ||
6145 | for (pend = opts->pending; pend;) | ||
6146 | { | ||
6147 | struct cpp_pending *next = pend->next; | ||
6148 | |||
6149 | free(pend); | ||
6150 | pend = next; | ||
6151 | } | ||
6152 | opts->pending = NULL; | ||
6153 | |||
6154 | if (finclude(pfile, f, fname, 0, NULL)) | ||
6155 | output_line_command(pfile, 0, same_file); | ||
6156 | return SUCCESS_EXIT_CODE; | ||
6157 | } | ||
6158 | |||
6159 | void | ||
6160 | init_parse_file(cpp_reader * pfile) | ||
6161 | { | ||
6162 | memset((char *)pfile, 0, sizeof(cpp_reader)); | ||
6163 | pfile->get_token = cpp_get_token; | ||
6164 | |||
6165 | pfile->token_buffer_size = 200; | ||
6166 | pfile->token_buffer = (unsigned char *)xmalloc(pfile->token_buffer_size); | ||
6167 | CPP_SET_WRITTEN(pfile, 0); | ||
6168 | |||
6169 | pfile->system_include_depth = 0; | ||
6170 | pfile->dont_repeat_files = 0; | ||
6171 | pfile->all_include_files = 0; | ||
6172 | pfile->max_include_len = 0; | ||
6173 | pfile->timebuf = NULL; | ||
6174 | pfile->only_seen_white = 1; | ||
6175 | pfile->buffer = CPP_NULL_BUFFER(pfile); | ||
6176 | } | ||
6177 | |||
6178 | static struct cpp_pending * | ||
6179 | nreverse_pending(struct cpp_pending *list) | ||
6180 | { | ||
6181 | struct cpp_pending *prev = 0, *next, *pend; | ||
6182 | |||
6183 | for (pend = list; pend; pend = next) | ||
6184 | { | ||
6185 | next = pend->next; | ||
6186 | pend->next = prev; | ||
6187 | prev = pend; | ||
6188 | } | ||
6189 | return prev; | ||
6190 | } | ||
6191 | |||
6192 | static void | ||
6193 | push_pending(cpp_reader * pfile, const char *cmd, const char *arg) | ||
6194 | { | ||
6195 | struct cpp_pending *pend | ||
6196 | = (struct cpp_pending *)xmalloc(sizeof(struct cpp_pending)); | ||
6197 | |||
6198 | pend->cmd = cmd; | ||
6199 | pend->arg = arg; | ||
6200 | pend->next = CPP_OPTIONS(pfile)->pending; | ||
6201 | CPP_OPTIONS(pfile)->pending = pend; | ||
6202 | } | ||
6203 | |||
6204 | /* Handle command-line options in (argc, argv). | ||
6205 | * Can be called multiple times, to handle multiple sets of options. | ||
6206 | * Returns if an unrecognized option is seen. | ||
6207 | * Returns number of handled arguments. */ | ||
6208 | |||
6209 | int | ||
6210 | cpp_handle_options(cpp_reader * pfile, int argc, char **argv) | ||
6211 | { | ||
6212 | int i; | ||
6213 | struct cpp_options *opts = CPP_OPTIONS(pfile); | ||
6214 | |||
6215 | for (i = 0; i < argc; i++) | ||
6216 | { | ||
6217 | if (argv[i][0] != '-') | ||
6218 | { | ||
6219 | if (opts->out_fname) | ||
6220 | cpp_fatal("Usage: %s [switches] input output", argv[0]); | ||
6221 | else if (opts->in_fname) | ||
6222 | opts->out_fname = argv[i]; | ||
6223 | else | ||
6224 | opts->in_fname = argv[i]; | ||
6225 | } | ||
6226 | else | ||
6227 | { | ||
6228 | switch (argv[i][1]) | ||
6229 | { | ||
6230 | |||
6231 | case 'i': | ||
6232 | if (!strcmp(argv[i], "-include") | ||
6233 | || !strcmp(argv[i], "-imacros")) | ||
6234 | { | ||
6235 | if (i + 1 == argc) | ||
6236 | cpp_fatal("Filename missing after `%s' option", | ||
6237 | argv[i]); | ||
6238 | else | ||
6239 | push_pending(pfile, argv[i], argv[i + 1]), i++; | ||
6240 | } | ||
6241 | if (!strcmp(argv[i], "-iprefix")) | ||
6242 | { | ||
6243 | if (i + 1 == argc) | ||
6244 | cpp_fatal("Filename missing after `-iprefix' option"); | ||
6245 | else | ||
6246 | opts->include_prefix = argv[++i]; | ||
6247 | } | ||
6248 | if (!strcmp(argv[i], "-ifoutput")) | ||
6249 | { | ||
6250 | opts->output_conditionals = 1; | ||
6251 | } | ||
6252 | if (!strcmp(argv[i], "-isystem")) | ||
6253 | { | ||
6254 | file_name_list *dirtmp; | ||
6255 | |||
6256 | if (i + 1 == argc) | ||
6257 | cpp_fatal("Filename missing after `-isystem' option"); | ||
6258 | |||
6259 | dirtmp = | ||
6260 | (file_name_list *) xmalloc(sizeof(file_name_list)); | ||
6261 | |||
6262 | dirtmp->next = 0; | ||
6263 | dirtmp->control_macro = 0; | ||
6264 | dirtmp->c_system_include_path = 1; | ||
6265 | dirtmp->fname = (char *)xmalloc(strlen(argv[i + 1]) + 1); | ||
6266 | strcpy(dirtmp->fname, argv[++i]); | ||
6267 | dirtmp->got_name_map = 0; | ||
6268 | |||
6269 | if (!opts->before_system) | ||
6270 | opts->before_system = dirtmp; | ||
6271 | else | ||
6272 | opts->last_before_system->next = dirtmp; | ||
6273 | opts->last_before_system = dirtmp; /* Tail follows the last one */ | ||
6274 | } | ||
6275 | /* Add directory to end of path for includes, | ||
6276 | * with the default prefix at the front of its name. */ | ||
6277 | if (!strcmp(argv[i], "-iwithprefix")) | ||
6278 | { | ||
6279 | file_name_list *dirtmp; | ||
6280 | char *prefix; | ||
6281 | |||
6282 | if (opts->include_prefix) | ||
6283 | prefix = opts->include_prefix; | ||
6284 | else | ||
6285 | { | ||
6286 | prefix = savestring(GCC_INCLUDE_DIR); | ||
6287 | /* Remove the `include' from /usr/local/lib/gcc.../include. */ | ||
6288 | if (!strcmp | ||
6289 | (prefix + strlen(prefix) - 8, "/include")) | ||
6290 | prefix[strlen(prefix) - 7] = 0; | ||
6291 | } | ||
6292 | |||
6293 | dirtmp = | ||
6294 | (file_name_list *) xmalloc(sizeof(file_name_list)); | ||
6295 | |||
6296 | dirtmp->next = 0; /* New one goes on the end */ | ||
6297 | dirtmp->control_macro = 0; | ||
6298 | dirtmp->c_system_include_path = 0; | ||
6299 | if (i + 1 == argc) | ||
6300 | cpp_fatal | ||
6301 | ("Directory name missing after `-iwithprefix' option"); | ||
6302 | |||
6303 | dirtmp->fname = (char *)xmalloc(strlen(argv[i + 1]) | ||
6304 | + strlen(prefix) + 1); | ||
6305 | strcpy(dirtmp->fname, prefix); | ||
6306 | strcat(dirtmp->fname, argv[++i]); | ||
6307 | dirtmp->got_name_map = 0; | ||
6308 | |||
6309 | if (!opts->after_include) | ||
6310 | opts->after_include = dirtmp; | ||
6311 | else | ||
6312 | opts->last_after_include->next = dirtmp; | ||
6313 | opts->last_after_include = dirtmp; /* Tail follows the last one */ | ||
6314 | } | ||
6315 | /* Add directory to main path for includes, | ||
6316 | * with the default prefix at the front of its name. */ | ||
6317 | if (!strcmp(argv[i], "-iwithprefixbefore")) | ||
6318 | { | ||
6319 | file_name_list *dirtmp; | ||
6320 | char *prefix; | ||
6321 | |||
6322 | if (opts->include_prefix) | ||
6323 | prefix = opts->include_prefix; | ||
6324 | else | ||
6325 | { | ||
6326 | prefix = savestring(GCC_INCLUDE_DIR); | ||
6327 | /* Remove the `include' from /usr/local/lib/gcc.../include. */ | ||
6328 | if (!strcmp | ||
6329 | (prefix + strlen(prefix) - 8, "/include")) | ||
6330 | prefix[strlen(prefix) - 7] = 0; | ||
6331 | } | ||
6332 | |||
6333 | dirtmp = | ||
6334 | (file_name_list *) xmalloc(sizeof(file_name_list)); | ||
6335 | |||
6336 | dirtmp->next = 0; /* New one goes on the end */ | ||
6337 | dirtmp->control_macro = 0; | ||
6338 | dirtmp->c_system_include_path = 0; | ||
6339 | if (i + 1 == argc) | ||
6340 | cpp_fatal | ||
6341 | ("Directory name missing after `-iwithprefixbefore' option"); | ||
6342 | |||
6343 | dirtmp->fname = (char *)xmalloc(strlen(argv[i + 1]) | ||
6344 | + strlen(prefix) + 1); | ||
6345 | strcpy(dirtmp->fname, prefix); | ||
6346 | strcat(dirtmp->fname, argv[++i]); | ||
6347 | dirtmp->got_name_map = 0; | ||
6348 | |||
6349 | append_include_chain(pfile, dirtmp, dirtmp); | ||
6350 | } | ||
6351 | /* Add directory to end of path for includes. */ | ||
6352 | if (!strcmp(argv[i], "-idirafter")) | ||
6353 | { | ||
6354 | file_name_list *dirtmp; | ||
6355 | |||
6356 | dirtmp = | ||
6357 | (file_name_list *) xmalloc(sizeof(file_name_list)); | ||
6358 | |||
6359 | dirtmp->next = 0; /* New one goes on the end */ | ||
6360 | dirtmp->control_macro = 0; | ||
6361 | dirtmp->c_system_include_path = 0; | ||
6362 | if (i + 1 == argc) | ||
6363 | cpp_fatal | ||
6364 | ("Directory name missing after `-idirafter' option"); | ||
6365 | else | ||
6366 | dirtmp->fname = argv[++i]; | ||
6367 | dirtmp->got_name_map = 0; | ||
6368 | |||
6369 | if (!opts->after_include) | ||
6370 | opts->after_include = dirtmp; | ||
6371 | else | ||
6372 | opts->last_after_include->next = dirtmp; | ||
6373 | opts->last_after_include = dirtmp; /* Tail follows the last one */ | ||
6374 | } | ||
6375 | break; | ||
6376 | |||
6377 | case 'o': | ||
6378 | if (opts->out_fname) | ||
6379 | cpp_fatal("Output filename specified twice"); | ||
6380 | if (i + 1 == argc) | ||
6381 | cpp_fatal("Filename missing after -o option"); | ||
6382 | opts->out_fname = argv[++i]; | ||
6383 | if (!strcmp(opts->out_fname, "-")) | ||
6384 | opts->out_fname = ""; | ||
6385 | break; | ||
6386 | |||
6387 | case 'p': | ||
6388 | if (!strcmp(argv[i], "-pedantic")) | ||
6389 | CPP_PEDANTIC(pfile) = 1; | ||
6390 | else if (!strcmp(argv[i], "-pedantic-errors")) | ||
6391 | { | ||
6392 | CPP_PEDANTIC(pfile) = 1; | ||
6393 | opts->pedantic_errors = 1; | ||
6394 | } | ||
6395 | break; | ||
6396 | |||
6397 | case 't': | ||
6398 | if (!strcmp(argv[i], "-trigraphs")) | ||
6399 | { | ||
6400 | if (!opts->chill) | ||
6401 | opts->no_trigraphs = 0; | ||
6402 | } | ||
6403 | break; | ||
6404 | |||
6405 | case 'l': | ||
6406 | if (!strcmp(argv[i], "-lang-c")) | ||
6407 | opts->cplusplus = 0, opts->cplusplus_comments = | ||
6408 | 0, opts->objc = 0; | ||
6409 | if (!strcmp(argv[i], "-lang-c++")) | ||
6410 | opts->cplusplus = 1, opts->cplusplus_comments = | ||
6411 | 1, opts->objc = 0; | ||
6412 | if (!strcmp(argv[i], "-lang-c-c++-comments")) | ||
6413 | opts->cplusplus = 0, opts->cplusplus_comments = | ||
6414 | 1, opts->objc = 0; | ||
6415 | if (!strcmp(argv[i], "-lang-objc")) | ||
6416 | opts->objc = 1, opts->cplusplus = | ||
6417 | 0, opts->cplusplus_comments = 1; | ||
6418 | if (!strcmp(argv[i], "-lang-objc++")) | ||
6419 | opts->objc = 1, opts->cplusplus = | ||
6420 | 1, opts->cplusplus_comments = 1; | ||
6421 | if (!strcmp(argv[i], "-lang-asm")) | ||
6422 | opts->lang_asm = 1; | ||
6423 | if (!strcmp(argv[i], "-lint")) | ||
6424 | opts->for_lint = 1; | ||
6425 | if (!strcmp(argv[i], "-lang-chill")) | ||
6426 | opts->objc = 0, opts->cplusplus = 0, opts->chill = 1, | ||
6427 | opts->traditional = 1, opts->no_trigraphs = 1; | ||
6428 | break; | ||
6429 | |||
6430 | case '+': | ||
6431 | opts->cplusplus = 1, opts->cplusplus_comments = 1; | ||
6432 | break; | ||
6433 | |||
6434 | case 'w': | ||
6435 | opts->inhibit_warnings = 1; | ||
6436 | break; | ||
6437 | |||
6438 | case 'W': | ||
6439 | if (!strcmp(argv[i], "-Wtrigraphs")) | ||
6440 | opts->warn_trigraphs = 1; | ||
6441 | else if (!strcmp(argv[i], "-Wno-trigraphs")) | ||
6442 | opts->warn_trigraphs = 0; | ||
6443 | else if (!strcmp(argv[i], "-Wcomment")) | ||
6444 | opts->warn_comments = 1; | ||
6445 | else if (!strcmp(argv[i], "-Wno-comment")) | ||
6446 | opts->warn_comments = 0; | ||
6447 | else if (!strcmp(argv[i], "-Wcomments")) | ||
6448 | opts->warn_comments = 1; | ||
6449 | else if (!strcmp(argv[i], "-Wno-comments")) | ||
6450 | opts->warn_comments = 0; | ||
6451 | else if (!strcmp(argv[i], "-Wtraditional")) | ||
6452 | opts->warn_stringify = 1; | ||
6453 | else if (!strcmp(argv[i], "-Wno-traditional")) | ||
6454 | opts->warn_stringify = 0; | ||
6455 | else if (!strcmp(argv[i], "-Wimport")) | ||
6456 | opts->warn_import = 1; | ||
6457 | else if (!strcmp(argv[i], "-Wno-import")) | ||
6458 | opts->warn_import = 0; | ||
6459 | else if (!strcmp(argv[i], "-Werror")) | ||
6460 | opts->warnings_are_errors = 1; | ||
6461 | else if (!strcmp(argv[i], "-Wno-error")) | ||
6462 | opts->warnings_are_errors = 0; | ||
6463 | else if (!strcmp(argv[i], "-Wall")) | ||
6464 | { | ||
6465 | opts->warn_trigraphs = 1; | ||
6466 | opts->warn_comments = 1; | ||
6467 | } | ||
6468 | break; | ||
6469 | |||
6470 | case 'M': | ||
6471 | /* The style of the choices here is a bit mixed. | ||
6472 | * The chosen scheme is a hybrid of keeping all options in one string | ||
6473 | * and specifying each option in a separate argument: | ||
6474 | * -M|-MM|-MD file|-MMD file [-MG]. An alternative is: | ||
6475 | * -M|-MM|-MD file|-MMD file|-MG|-MMG; or more concisely: | ||
6476 | * -M[M][G][D file]. This is awkward to handle in specs, and is not | ||
6477 | * as extensible. */ | ||
6478 | /* ??? -MG must be specified in addition to one of -M or -MM. | ||
6479 | * This can be relaxed in the future without breaking anything. | ||
6480 | * The converse isn't true. */ | ||
6481 | |||
6482 | /* -MG isn't valid with -MD or -MMD. This is checked for later. */ | ||
6483 | if (!strcmp(argv[i], "-MG")) | ||
6484 | { | ||
6485 | opts->print_deps_missing_files = 1; | ||
6486 | break; | ||
6487 | } | ||
6488 | if (!strcmp(argv[i], "-M")) | ||
6489 | opts->print_deps = 2; | ||
6490 | else if (!strcmp(argv[i], "-MM")) | ||
6491 | opts->print_deps = 1; | ||
6492 | else if (!strcmp(argv[i], "-MD")) | ||
6493 | opts->print_deps = 2; | ||
6494 | else if (!strcmp(argv[i], "-MMD")) | ||
6495 | opts->print_deps = 1; | ||
6496 | /* For -MD and -MMD options, write deps on file named by next arg. */ | ||
6497 | if (!strcmp(argv[i], "-MD") || !strcmp(argv[i], "-MMD")) | ||
6498 | { | ||
6499 | if (i + 1 == argc) | ||
6500 | cpp_fatal("Filename missing after %s option", | ||
6501 | argv[i]); | ||
6502 | opts->deps_file = argv[++i]; | ||
6503 | } | ||
6504 | else | ||
6505 | { | ||
6506 | /* For -M and -MM, write deps on standard output | ||
6507 | * and suppress the usual output. */ | ||
6508 | opts->no_output = 1; | ||
6509 | } | ||
6510 | break; | ||
6511 | |||
6512 | case 'd': | ||
6513 | { | ||
6514 | char *p = argv[i] + 2; | ||
6515 | char c; | ||
6516 | |||
6517 | while ((c = *p++) != 0) | ||
6518 | { | ||
6519 | /* Arg to -d specifies what parts of macros to dump */ | ||
6520 | switch (c) | ||
6521 | { | ||
6522 | case 'M': | ||
6523 | opts->dump_macros = dump_only; | ||
6524 | opts->no_output = 1; | ||
6525 | break; | ||
6526 | case 'N': | ||
6527 | opts->dump_macros = dump_names; | ||
6528 | break; | ||
6529 | case 'D': | ||
6530 | opts->dump_macros = dump_definitions; | ||
6531 | break; | ||
6532 | } | ||
6533 | } | ||
6534 | } | ||
6535 | break; | ||
6536 | |||
6537 | case 'g': | ||
6538 | if (argv[i][2] == '3') | ||
6539 | opts->debug_output = 1; | ||
6540 | break; | ||
6541 | |||
6542 | case 'v': | ||
6543 | fprintf(stderr, "GNU CPP version %s", version_string); | ||
6544 | #ifdef TARGET_VERSION | ||
6545 | TARGET_VERSION; | ||
6546 | #endif | ||
6547 | fprintf(stderr, "\n"); | ||
6548 | opts->verbose = 1; | ||
6549 | break; | ||
6550 | |||
6551 | case 'H': | ||
6552 | opts->print_include_names = 1; | ||
6553 | break; | ||
6554 | |||
6555 | case 'D': | ||
6556 | if (argv[i][2] != 0) | ||
6557 | push_pending(pfile, "-D", argv[i] + 2); | ||
6558 | else if (i + 1 == argc) | ||
6559 | cpp_fatal("Macro name missing after -D option"); | ||
6560 | else | ||
6561 | i++, push_pending(pfile, "-D", argv[i]); | ||
6562 | break; | ||
6563 | |||
6564 | case 'A': | ||
6565 | { | ||
6566 | char *p = NULL; | ||
6567 | |||
6568 | if (argv[i][2] != 0) | ||
6569 | p = argv[i] + 2; | ||
6570 | else if (i + 1 == argc) | ||
6571 | cpp_fatal("Assertion missing after -A option"); | ||
6572 | else | ||
6573 | p = argv[++i]; | ||
6574 | |||
6575 | if (!strcmp(p, "-")) | ||
6576 | { | ||
6577 | struct cpp_pending **ptr; | ||
6578 | |||
6579 | /* -A- eliminates all predefined macros and assertions. | ||
6580 | * Let's include also any that were specified earlier | ||
6581 | * on the command line. That way we can get rid of any | ||
6582 | * that were passed automatically in from GCC. */ | ||
6583 | |||
6584 | opts->inhibit_predefs = 1; | ||
6585 | for (ptr = &opts->pending; *ptr;) | ||
6586 | { | ||
6587 | struct cpp_pending *pend = *ptr; | ||
6588 | |||
6589 | if (pend->cmd && pend->cmd[0] == '-' | ||
6590 | && (pend->cmd[1] == 'D' | ||
6591 | || pend->cmd[1] == 'A')) | ||
6592 | { | ||
6593 | *ptr = pend->next; | ||
6594 | free(pend); | ||
6595 | } | ||
6596 | else | ||
6597 | ptr = &pend->next; | ||
6598 | } | ||
6599 | } | ||
6600 | else | ||
6601 | { | ||
6602 | push_pending(pfile, "-A", p); | ||
6603 | } | ||
6604 | } | ||
6605 | break; | ||
6606 | |||
6607 | case 'U': /* JF #undef something */ | ||
6608 | if (argv[i][2] != 0) | ||
6609 | push_pending(pfile, "-U", argv[i] + 2); | ||
6610 | else if (i + 1 == argc) | ||
6611 | cpp_fatal("Macro name missing after -U option"); | ||
6612 | else | ||
6613 | push_pending(pfile, "-U", argv[i + 1]), i++; | ||
6614 | break; | ||
6615 | |||
6616 | case 'C': | ||
6617 | opts->put_out_comments = 1; | ||
6618 | break; | ||
6619 | |||
6620 | case 'E': /* -E comes from cc -E; ignore it. */ | ||
6621 | break; | ||
6622 | |||
6623 | case 'P': | ||
6624 | opts->no_line_commands = 1; | ||
6625 | break; | ||
6626 | |||
6627 | case '$': /* Don't include $ in identifiers. */ | ||
6628 | opts->dollars_in_ident = 0; | ||
6629 | break; | ||
6630 | |||
6631 | case 'I': /* Add directory to path for includes. */ | ||
6632 | { | ||
6633 | file_name_list *dirtmp; | ||
6634 | |||
6635 | if (!CPP_OPTIONS(pfile)->ignore_srcdir | ||
6636 | && !strcmp(argv[i] + 2, "-")) | ||
6637 | { | ||
6638 | CPP_OPTIONS(pfile)->ignore_srcdir = 1; | ||
6639 | /* Don't use any preceding -I directories for #include <...>. */ | ||
6640 | CPP_OPTIONS(pfile)->first_bracket_include = 0; | ||
6641 | } | ||
6642 | else | ||
6643 | { | ||
6644 | dirtmp = | ||
6645 | (file_name_list *) xmalloc(sizeof(file_name_list)); | ||
6646 | |||
6647 | dirtmp->next = 0; /* New one goes on the end */ | ||
6648 | dirtmp->control_macro = 0; | ||
6649 | dirtmp->c_system_include_path = 0; | ||
6650 | if (argv[i][2] != 0) | ||
6651 | dirtmp->fname = argv[i] + 2; | ||
6652 | else if (i + 1 == argc) | ||
6653 | cpp_fatal | ||
6654 | ("Directory name missing after -I option"); | ||
6655 | else | ||
6656 | dirtmp->fname = argv[++i]; | ||
6657 | dirtmp->got_name_map = 0; | ||
6658 | append_include_chain(pfile, dirtmp, dirtmp); | ||
6659 | } | ||
6660 | } | ||
6661 | break; | ||
6662 | |||
6663 | case 'n': | ||
6664 | if (!strcmp(argv[i], "-nostdinc")) | ||
6665 | /* -nostdinc causes no default include directories. | ||
6666 | * You must specify all include-file directories with -I. */ | ||
6667 | opts->no_standard_includes = 1; | ||
6668 | else if (!strcmp(argv[i], "-nostdinc++")) | ||
6669 | /* -nostdinc++ causes no default C++-specific include directories. */ | ||
6670 | opts->no_standard_cplusplus_includes = 1; | ||
6671 | break; | ||
6672 | |||
6673 | case 'u': | ||
6674 | /* Sun compiler passes undocumented switch "-undef". | ||
6675 | * Let's assume it means to inhibit the predefined symbols. */ | ||
6676 | opts->inhibit_predefs = 1; | ||
6677 | break; | ||
6678 | |||
6679 | case '\0': /* JF handle '-' as file name meaning stdin or stdout */ | ||
6680 | if (!opts->in_fname) | ||
6681 | { | ||
6682 | opts->in_fname = ""; | ||
6683 | break; | ||
6684 | } | ||
6685 | else if (!opts->out_fname) | ||
6686 | { | ||
6687 | opts->out_fname = ""; | ||
6688 | break; | ||
6689 | } /* else fall through into error */ | ||
6690 | default: | ||
6691 | return i; | ||
6692 | } | ||
6693 | } | ||
6694 | } | ||
6695 | return i; | ||
6696 | } | ||
6697 | |||
6698 | void | ||
6699 | cpp_finish(cpp_reader * pfile) | ||
6700 | { | ||
6701 | struct cpp_options *opts = CPP_OPTIONS(pfile); | ||
6702 | |||
6703 | if (opts->print_deps) | ||
6704 | { | ||
6705 | /* Stream on which to print the dependency information. */ | ||
6706 | FILE *deps_stream; | ||
6707 | |||
6708 | /* Don't actually write the deps file if compilation has failed. */ | ||
6709 | if (pfile->errors == 0) | ||
6710 | { | ||
6711 | const char *deps_mode = | ||
6712 | opts->print_deps_append ? "ab" : "wb"; | ||
6713 | |||
6714 | if (!opts->deps_file) | ||
6715 | deps_stream = stdout; | ||
6716 | else if (!(deps_stream = fopen(opts->deps_file, deps_mode))) | ||
6717 | cpp_pfatal_with_name(pfile, opts->deps_file); | ||
6718 | fputs(pfile->deps_buffer, deps_stream); | ||
6719 | putc('\n', deps_stream); | ||
6720 | if (opts->deps_file) | ||
6721 | { | ||
6722 | if (ferror(deps_stream) || fclose(deps_stream) != 0) | ||
6723 | cpp_fatal("I/O error on output"); | ||
6724 | } | ||
6725 | } | ||
6726 | } | ||
6727 | } | ||
6728 | |||
6729 | static int | ||
6730 | do_assert(cpp_reader * pfile, struct directive *keyword __UNUSED__, | ||
6731 | unsigned char *buf __UNUSED__, unsigned char *limit __UNUSED__) | ||
6732 | { | ||
6733 | long symstart; /* remember where symbol name starts */ | ||
6734 | int c; | ||
6735 | int sym_length; /* and how long it is */ | ||
6736 | struct arglist *tokens = NULL; | ||
6737 | |||
6738 | if (CPP_PEDANTIC(pfile) && CPP_OPTIONS(pfile)->done_initializing | ||
6739 | && !CPP_BUFFER(pfile)->system_header_p) | ||
6740 | cpp_pedwarn(pfile, "ANSI C does not allow `#assert'"); | ||
6741 | |||
6742 | cpp_skip_hspace(pfile); | ||
6743 | symstart = CPP_WRITTEN(pfile); /* remember where it starts */ | ||
6744 | parse_name(pfile, GETC()); | ||
6745 | sym_length = check_macro_name(pfile, pfile->token_buffer + symstart, | ||
6746 | "assertion"); | ||
6747 | |||
6748 | cpp_skip_hspace(pfile); | ||
6749 | if (PEEKC() != '(') | ||
6750 | { | ||
6751 | cpp_error(pfile, "missing token-sequence in `#assert'"); | ||
6752 | goto error; | ||
6753 | } | ||
6754 | { | ||
6755 | int error_flag = 0; | ||
6756 | |||
6757 | tokens = read_token_list(pfile, &error_flag); | ||
6758 | if (error_flag) | ||
6759 | goto error; | ||
6760 | if (!tokens) | ||
6761 | { | ||
6762 | cpp_error(pfile, "empty token-sequence in `#assert'"); | ||
6763 | goto error; | ||
6764 | } | ||
6765 | cpp_skip_hspace(pfile); | ||
6766 | c = PEEKC(); | ||
6767 | if (c != EOF && c != '\n') | ||
6768 | cpp_pedwarn(pfile, "junk at end of `#assert'"); | ||
6769 | skip_rest_of_line(pfile); | ||
6770 | } | ||
6771 | |||
6772 | /* If this name isn't already an assertion name, make it one. | ||
6773 | * Error if it was already in use in some other way. */ | ||
6774 | |||
6775 | { | ||
6776 | ASSERTION_HASHNODE *hp; | ||
6777 | const char *symname = (char *)pfile->token_buffer + symstart; | ||
6778 | int hashcode = | ||
6779 | hashf(symname, sym_length, ASSERTION_HASHSIZE); | ||
6780 | struct tokenlist_list *value = | ||
6781 | (struct tokenlist_list *)xmalloc(sizeof(struct tokenlist_list)); | ||
6782 | |||
6783 | hp = assertion_lookup(pfile, symname, sym_length, hashcode); | ||
6784 | if (!hp) | ||
6785 | { | ||
6786 | if (sym_length == 7 && !strncmp(symname, "defined", sym_length)) | ||
6787 | cpp_error(pfile, "`defined' redefined as assertion"); | ||
6788 | hp = assertion_install(pfile, symname, sym_length, hashcode); | ||
6789 | } | ||
6790 | /* Add the spec'd token-sequence to the list of such. */ | ||
6791 | value->tokens = tokens; | ||
6792 | value->next = hp->value; | ||
6793 | hp->value = value; | ||
6794 | } | ||
6795 | CPP_SET_WRITTEN(pfile, symstart); /* Pop */ | ||
6796 | return 0; | ||
6797 | error: | ||
6798 | CPP_SET_WRITTEN(pfile, symstart); /* Pop */ | ||
6799 | skip_rest_of_line(pfile); | ||
6800 | return 1; | ||
6801 | } | ||
6802 | |||
6803 | static int | ||
6804 | do_unassert(cpp_reader * pfile, struct directive *keyword __UNUSED__, | ||
6805 | unsigned char *buf __UNUSED__, unsigned char *limit __UNUSED__) | ||
6806 | { | ||
6807 | long symstart; /* remember where symbol name starts */ | ||
6808 | int sym_length; /* and how long it is */ | ||
6809 | int c; | ||
6810 | |||
6811 | struct arglist *tokens = NULL; | ||
6812 | int tokens_specified = 0; | ||
6813 | |||
6814 | if (CPP_PEDANTIC(pfile) && CPP_OPTIONS(pfile)->done_initializing | ||
6815 | && !CPP_BUFFER(pfile)->system_header_p) | ||
6816 | cpp_pedwarn(pfile, "ANSI C does not allow `#unassert'"); | ||
6817 | |||
6818 | cpp_skip_hspace(pfile); | ||
6819 | |||
6820 | symstart = CPP_WRITTEN(pfile); /* remember where it starts */ | ||
6821 | parse_name(pfile, GETC()); | ||
6822 | sym_length = check_macro_name(pfile, pfile->token_buffer + symstart, | ||
6823 | "assertion"); | ||
6824 | |||
6825 | cpp_skip_hspace(pfile); | ||
6826 | if (PEEKC() == '(') | ||
6827 | { | ||
6828 | int error_flag = 0; | ||
6829 | |||
6830 | tokens = read_token_list(pfile, &error_flag); | ||
6831 | if (error_flag) | ||
6832 | goto error; | ||
6833 | if (!tokens) | ||
6834 | { | ||
6835 | cpp_error(pfile, "empty token list in `#unassert'"); | ||
6836 | goto error; | ||
6837 | } | ||
6838 | tokens_specified = 1; | ||
6839 | } | ||
6840 | cpp_skip_hspace(pfile); | ||
6841 | c = PEEKC(); | ||
6842 | if (c != EOF && c != '\n') | ||
6843 | cpp_error(pfile, "junk at end of `#unassert'"); | ||
6844 | skip_rest_of_line(pfile); | ||
6845 | |||
6846 | { | ||
6847 | ASSERTION_HASHNODE *hp; | ||
6848 | const char *symname = (char *)pfile->token_buffer + symstart; | ||
6849 | int hashcode = | ||
6850 | hashf(symname, sym_length, ASSERTION_HASHSIZE); | ||
6851 | struct tokenlist_list *tail, *prev; | ||
6852 | |||
6853 | hp = assertion_lookup(pfile, symname, sym_length, hashcode); | ||
6854 | if (!hp) | ||
6855 | return 1; | ||
6856 | |||
6857 | /* If no token list was specified, then eliminate this assertion | ||
6858 | * entirely. */ | ||
6859 | if (!tokens_specified) | ||
6860 | delete_assertion(hp); | ||
6861 | else | ||
6862 | { | ||
6863 | /* If a list of tokens was given, then delete any matching list. */ | ||
6864 | |||
6865 | tail = hp->value; | ||
6866 | prev = 0; | ||
6867 | while (tail) | ||
6868 | { | ||
6869 | struct tokenlist_list *next = tail->next; | ||
6870 | |||
6871 | if (compare_token_lists(tail->tokens, tokens)) | ||
6872 | { | ||
6873 | if (prev) | ||
6874 | prev->next = next; | ||
6875 | else | ||
6876 | hp->value = tail->next; | ||
6877 | free_token_list(tail->tokens); | ||
6878 | free(tail); | ||
6879 | } | ||
6880 | else | ||
6881 | { | ||
6882 | prev = tail; | ||
6883 | } | ||
6884 | tail = next; | ||
6885 | } | ||
6886 | } | ||
6887 | } | ||
6888 | |||
6889 | CPP_SET_WRITTEN(pfile, symstart); /* Pop */ | ||
6890 | return 0; | ||
6891 | error: | ||
6892 | CPP_SET_WRITTEN(pfile, symstart); /* Pop */ | ||
6893 | skip_rest_of_line(pfile); | ||
6894 | return 1; | ||
6895 | } | ||
6896 | |||
6897 | /* Test whether there is an assertion named NAME | ||
6898 | * and optionally whether it has an asserted token list TOKENS. | ||
6899 | * NAME is not null terminated; its length is SYM_LENGTH. | ||
6900 | * If TOKENS_SPECIFIED is 0, then don't check for any token list. */ | ||
6901 | |||
6902 | static int | ||
6903 | check_assertion(cpp_reader * pfile, const char *name, int sym_length, | ||
6904 | int tokens_specified, struct arglist *tokens) | ||
6905 | { | ||
6906 | ASSERTION_HASHNODE *hp; | ||
6907 | int hashcode = hashf(name, sym_length, ASSERTION_HASHSIZE); | ||
6908 | |||
6909 | if (CPP_PEDANTIC(pfile) && !CPP_BUFFER(pfile)->system_header_p) | ||
6910 | cpp_pedwarn(pfile, "ANSI C does not allow testing assertions"); | ||
6911 | |||
6912 | hp = assertion_lookup(pfile, name, sym_length, hashcode); | ||
6913 | if (!hp) | ||
6914 | /* It is not an assertion; just return false. */ | ||
6915 | return 0; | ||
6916 | |||
6917 | /* If no token list was specified, then value is 1. */ | ||
6918 | if (!tokens_specified) | ||
6919 | return 1; | ||
6920 | |||
6921 | { | ||
6922 | struct tokenlist_list *tail; | ||
6923 | |||
6924 | tail = hp->value; | ||
6925 | |||
6926 | /* If a list of tokens was given, | ||
6927 | * then succeed if the assertion records a matching list. */ | ||
6928 | |||
6929 | while (tail) | ||
6930 | { | ||
6931 | if (compare_token_lists(tail->tokens, tokens)) | ||
6932 | return 1; | ||
6933 | tail = tail->next; | ||
6934 | } | ||
6935 | |||
6936 | /* Fail if the assertion has no matching list. */ | ||
6937 | return 0; | ||
6938 | } | ||
6939 | } | ||
6940 | |||
6941 | /* Compare two lists of tokens for equality including order of tokens. */ | ||
6942 | |||
6943 | static int | ||
6944 | compare_token_lists(struct arglist *l1, struct arglist *l2) | ||
6945 | { | ||
6946 | while (l1 && l2) | ||
6947 | { | ||
6948 | if (l1->length != l2->length) | ||
6949 | return 0; | ||
6950 | if (strncmp(l1->name, l2->name, l1->length)) | ||
6951 | return 0; | ||
6952 | l1 = l1->next; | ||
6953 | l2 = l2->next; | ||
6954 | } | ||
6955 | |||
6956 | /* Succeed if both lists end at the same time. */ | ||
6957 | return l1 == l2; | ||
6958 | } | ||
6959 | |||
6960 | struct arglist * | ||
6961 | reverse_token_list(struct arglist *tokens) | ||
6962 | { | ||
6963 | struct arglist *prev = 0, *cur, *next; | ||
6964 | |||
6965 | for (cur = tokens; cur; cur = next) | ||
6966 | { | ||
6967 | next = cur->next; | ||
6968 | cur->next = prev; | ||
6969 | prev = cur; | ||
6970 | } | ||
6971 | return prev; | ||
6972 | } | ||
6973 | |||
6974 | /* Read a space-separated list of tokens ending in a close parenthesis. | ||
6975 | * Return a list of strings, in the order they were written. | ||
6976 | * (In case of error, return 0 and store -1 in *ERROR_FLAG.) */ | ||
6977 | |||
6978 | static struct arglist * | ||
6979 | read_token_list(cpp_reader * pfile, int *error_flag) | ||
6980 | { | ||
6981 | struct arglist *token_ptrs = 0; | ||
6982 | int depth = 1; | ||
6983 | int length; | ||
6984 | |||
6985 | *error_flag = 0; | ||
6986 | FORWARD(1); /* Skip '(' */ | ||
6987 | |||
6988 | /* Loop over the assertion value tokens. */ | ||
6989 | while (depth > 0) | ||
6990 | { | ||
6991 | struct arglist *temp; | ||
6992 | long name_written = CPP_WRITTEN(pfile); | ||
6993 | int c; | ||
6994 | |||
6995 | cpp_skip_hspace(pfile); | ||
6996 | |||
6997 | c = GETC(); | ||
6998 | |||
6999 | /* Find the end of the token. */ | ||
7000 | if (c == '(') | ||
7001 | { | ||
7002 | CPP_PUTC(pfile, c); | ||
7003 | depth++; | ||
7004 | } | ||
7005 | else if (c == ')') | ||
7006 | { | ||
7007 | depth--; | ||
7008 | if (depth == 0) | ||
7009 | break; | ||
7010 | CPP_PUTC(pfile, c); | ||
7011 | } | ||
7012 | else if (c == '"' || c == '\'') | ||
7013 | { | ||
7014 | FORWARD(-1); | ||
7015 | cpp_get_token(pfile); | ||
7016 | } | ||
7017 | else if (c == '\n') | ||
7018 | break; | ||
7019 | else | ||
7020 | { | ||
7021 | while (c != EOF && !is_space[c] && c != '(' && c != ')' | ||
7022 | && c != '"' && c != '\'') | ||
7023 | { | ||
7024 | CPP_PUTC(pfile, c); | ||
7025 | c = GETC(); | ||
7026 | } | ||
7027 | if (c != EOF) | ||
7028 | FORWARD(-1); | ||
7029 | } | ||
7030 | |||
7031 | length = CPP_WRITTEN(pfile) - name_written; | ||
7032 | temp = (struct arglist *)xmalloc(sizeof(struct arglist) + length + 1); | ||
7033 | |||
7034 | temp->name = (char *)(temp + 1); | ||
7035 | memcpy(temp->name, (char *)(pfile->token_buffer + name_written), | ||
7036 | length); | ||
7037 | temp->name[length] = 0; | ||
7038 | temp->next = token_ptrs; | ||
7039 | token_ptrs = temp; | ||
7040 | temp->length = length; | ||
7041 | |||
7042 | CPP_ADJUST_WRITTEN(pfile, -length); /* pop */ | ||
7043 | |||
7044 | if (c == EOF || c == '\n') | ||
7045 | { /* FIXME */ | ||
7046 | cpp_error(pfile, | ||
7047 | "unterminated token sequence following `#' operator"); | ||
7048 | return 0; | ||
7049 | } | ||
7050 | } | ||
7051 | |||
7052 | /* We accumulated the names in reverse order. | ||
7053 | * Now reverse them to get the proper order. */ | ||
7054 | return reverse_token_list(token_ptrs); | ||
7055 | } | ||
7056 | |||
7057 | static void | ||
7058 | free_token_list(struct arglist *tokens) | ||
7059 | { | ||
7060 | while (tokens) | ||
7061 | { | ||
7062 | struct arglist *next = tokens->next; | ||
7063 | |||
7064 | free(tokens->name); | ||
7065 | free(tokens); | ||
7066 | tokens = next; | ||
7067 | } | ||
7068 | } | ||
7069 | |||
7070 | /* Get the file-mode and data size of the file open on FD | ||
7071 | * and store them in *MODE_POINTER and *SIZE_POINTER. */ | ||
7072 | |||
7073 | static int | ||
7074 | file_size_and_mode(int fd, int *mode_pointer, long int *size_pointer) | ||
7075 | { | ||
7076 | struct stat sbuf; | ||
7077 | |||
7078 | if (fstat(fd, &sbuf) < 0) | ||
7079 | return (-1); | ||
7080 | if (mode_pointer) | ||
7081 | *mode_pointer = sbuf.st_mode; | ||
7082 | if (size_pointer) | ||
7083 | *size_pointer = sbuf.st_size; | ||
7084 | return 0; | ||
7085 | } | ||
7086 | |||
7087 | /* Read LEN bytes at PTR from descriptor DESC, for file FILENAME, | ||
7088 | * retrying if necessary. Return a negative value if an error occurs, | ||
7089 | * otherwise return the actual number of bytes read, | ||
7090 | * which must be LEN unless end-of-file was reached. */ | ||
7091 | |||
7092 | static int | ||
7093 | safe_read(int desc, char *ptr, int len) | ||
7094 | { | ||
7095 | int left = len; | ||
7096 | |||
7097 | while (left > 0) | ||
7098 | { | ||
7099 | int nchars = read(desc, ptr, left); | ||
7100 | |||
7101 | if (nchars < 0) | ||
7102 | { | ||
7103 | #ifdef EINTR | ||
7104 | if (errno == EINTR) | ||
7105 | continue; | ||
7106 | #endif | ||
7107 | return nchars; | ||
7108 | } | ||
7109 | if (nchars == 0) | ||
7110 | break; | ||
7111 | ptr += nchars; | ||
7112 | left -= nchars; | ||
7113 | } | ||
7114 | return len - left; | ||
7115 | } | ||
7116 | |||
7117 | static char * | ||
7118 | savestring(const char *input) | ||
7119 | { | ||
7120 | unsigned size = strlen(input); | ||
7121 | char *output = (char *)xmalloc(size + 1); | ||
7122 | |||
7123 | strcpy(output, input); | ||
7124 | return output; | ||
7125 | } | ||
7126 | |||
7127 | /* Initialize PMARK to remember the current position of PFILE. */ | ||
7128 | void | ||
7129 | parse_set_mark(struct parse_marker *pmark, cpp_reader * pfile) | ||
7130 | { | ||
7131 | cpp_buffer *pbuf = CPP_BUFFER(pfile); | ||
7132 | |||
7133 | pmark->next = pbuf->marks; | ||
7134 | pbuf->marks = pmark; | ||
7135 | pmark->buf = pbuf; | ||
7136 | pmark->position = pbuf->cur - pbuf->buf; | ||
7137 | } | ||
7138 | |||
7139 | /* Cleanup PMARK - we no longer need it. */ | ||
7140 | static void | ||
7141 | parse_clear_mark(struct parse_marker *pmark) | ||
7142 | { | ||
7143 | struct parse_marker **pp = &pmark->buf->marks; | ||
7144 | |||
7145 | for (;; pp = &(*pp)->next) | ||
7146 | { | ||
7147 | if (!*pp) | ||
7148 | cpp_fatal("internal error", "in parse_set_mark"); | ||
7149 | if (*pp == pmark) | ||
7150 | break; | ||
7151 | } | ||
7152 | *pp = pmark->next; | ||
7153 | } | ||
7154 | |||
7155 | /* Backup the current position of PFILE to that saved in PMARK. */ | ||
7156 | |||
7157 | static void | ||
7158 | parse_goto_mark(struct parse_marker *pmark, cpp_reader * pfile) | ||
7159 | { | ||
7160 | cpp_buffer *pbuf = CPP_BUFFER(pfile); | ||
7161 | |||
7162 | if (pbuf != pmark->buf) | ||
7163 | cpp_fatal("internal error %s", "parse_goto_mark"); | ||
7164 | pbuf->cur = pbuf->buf + pmark->position; | ||
7165 | } | ||
7166 | |||
7167 | /* Reset PMARK to point to the current position of PFILE. (Same | ||
7168 | * as parse_clear_mark (PMARK), parse_set_mark (PMARK, PFILE) but faster. */ | ||
7169 | |||
7170 | static void | ||
7171 | parse_move_mark(struct parse_marker *pmark, cpp_reader * pfile) | ||
7172 | { | ||
7173 | cpp_buffer *pbuf = CPP_BUFFER(pfile); | ||
7174 | |||
7175 | if (pbuf != pmark->buf) | ||
7176 | cpp_fatal("internal error %s", "parse_move_mark"); | ||
7177 | pmark->position = pbuf->cur - pbuf->buf; | ||
7178 | } | ||
7179 | |||
7180 | int | ||
7181 | cpp_read_check_assertion(cpp_reader * pfile) | ||
7182 | { | ||
7183 | int name_start = CPP_WRITTEN(pfile); | ||
7184 | int name_length, name_written; | ||
7185 | int result; | ||
7186 | |||
7187 | FORWARD(1); /* Skip '#' */ | ||
7188 | cpp_skip_hspace(pfile); | ||
7189 | parse_name(pfile, GETC()); | ||
7190 | name_written = CPP_WRITTEN(pfile); | ||
7191 | name_length = name_written - name_start; | ||
7192 | cpp_skip_hspace(pfile); | ||
7193 | if (CPP_BUF_PEEK(CPP_BUFFER(pfile)) == '(') | ||
7194 | { | ||
7195 | int error_flag; | ||
7196 | struct arglist *token_ptrs = read_token_list(pfile, &error_flag); | ||
7197 | |||
7198 | result = check_assertion(pfile, | ||
7199 | (char *)pfile->token_buffer + name_start, | ||
7200 | name_length, 1, token_ptrs); | ||
7201 | } | ||
7202 | else | ||
7203 | result = check_assertion(pfile, | ||
7204 | (char *)pfile->token_buffer + name_start, | ||
7205 | name_length, 0, NULL); | ||
7206 | CPP_ADJUST_WRITTEN(pfile, -name_length); /* pop */ | ||
7207 | return result; | ||
7208 | } | ||
7209 | |||
7210 | static void | ||
7211 | cpp_print_file_and_line(cpp_reader * pfile) | ||
7212 | { | ||
7213 | cpp_buffer *ip = cpp_file_buffer(pfile); | ||
7214 | |||
7215 | if (ip) | ||
7216 | { | ||
7217 | long line, col; | ||
7218 | |||
7219 | cpp_buf_line_and_col(ip, &line, &col); | ||
7220 | cpp_file_line_for_message(pfile, ip->nominal_fname, | ||
7221 | line, pfile->show_column ? col : -1); | ||
7222 | } | ||
7223 | } | ||
7224 | |||
7225 | static void | ||
7226 | cpp_error_v(cpp_reader * pfile, const char *msg, va_list args) | ||
7227 | { | ||
7228 | cpp_print_containing_files(pfile); | ||
7229 | cpp_print_file_and_line(pfile); | ||
7230 | cpp_message_v(pfile, 1, msg, args); | ||
7231 | } | ||
7232 | |||
7233 | void | ||
7234 | cpp_error(cpp_reader * pfile, const char *msg, ...) | ||
7235 | { | ||
7236 | va_list args; | ||
7237 | |||
7238 | va_start(args, msg); | ||
7239 | |||
7240 | cpp_error_v(pfile, msg, args); | ||
7241 | |||
7242 | va_end(args); | ||
7243 | } | ||
7244 | |||
7245 | /* Print error message but don't count it. */ | ||
7246 | |||
7247 | static void | ||
7248 | cpp_warning_v(cpp_reader * pfile, const char *msg, va_list args) | ||
7249 | { | ||
7250 | if (CPP_OPTIONS(pfile)->inhibit_warnings) | ||
7251 | return; | ||
7252 | |||
7253 | if (CPP_OPTIONS(pfile)->warnings_are_errors) | ||
7254 | pfile->errors++; | ||
7255 | |||
7256 | cpp_print_containing_files(pfile); | ||
7257 | cpp_print_file_and_line(pfile); | ||
7258 | cpp_message_v(pfile, 0, msg, args); | ||
7259 | } | ||
7260 | |||
7261 | void | ||
7262 | cpp_warning(cpp_reader * pfile, const char *msg, ...) | ||
7263 | { | ||
7264 | va_list args; | ||
7265 | |||
7266 | va_start(args, msg); | ||
7267 | |||
7268 | cpp_warning_v(pfile, msg, args); | ||
7269 | |||
7270 | va_end(args); | ||
7271 | } | ||
7272 | |||
7273 | /* Print an error message and maybe count it. */ | ||
7274 | |||
7275 | void | ||
7276 | cpp_pedwarn(cpp_reader * pfile, const char *msg, ...) | ||
7277 | { | ||
7278 | va_list args; | ||
7279 | |||
7280 | va_start(args, msg); | ||
7281 | |||
7282 | if (CPP_OPTIONS(pfile)->pedantic_errors) | ||
7283 | cpp_error_v(pfile, msg, args); | ||
7284 | else | ||
7285 | cpp_warning_v(pfile, msg, args); | ||
7286 | |||
7287 | va_end(args); | ||
7288 | } | ||
7289 | |||
7290 | static void | ||
7291 | cpp_error_with_line(cpp_reader * pfile, int line, int column, const char *msg) | ||
7292 | { | ||
7293 | cpp_buffer *ip = cpp_file_buffer(pfile); | ||
7294 | |||
7295 | cpp_print_containing_files(pfile); | ||
7296 | |||
7297 | if (ip) | ||
7298 | cpp_file_line_for_message(pfile, ip->nominal_fname, line, column); | ||
7299 | |||
7300 | cpp_message(pfile, 1, msg, NULL, NULL, NULL); | ||
7301 | } | ||
7302 | |||
7303 | static void | ||
7304 | cpp_warning_with_line(cpp_reader * pfile, int line, int column, const char *msg) | ||
7305 | { | ||
7306 | cpp_buffer *ip; | ||
7307 | |||
7308 | if (CPP_OPTIONS(pfile)->inhibit_warnings) | ||
7309 | return; | ||
7310 | |||
7311 | if (CPP_OPTIONS(pfile)->warnings_are_errors) | ||
7312 | pfile->errors++; | ||
7313 | |||
7314 | cpp_print_containing_files(pfile); | ||
7315 | |||
7316 | ip = cpp_file_buffer(pfile); | ||
7317 | |||
7318 | if (ip) | ||
7319 | cpp_file_line_for_message(pfile, ip->nominal_fname, line, column); | ||
7320 | |||
7321 | cpp_message(pfile, 0, msg, NULL, NULL, NULL); | ||
7322 | } | ||
7323 | |||
7324 | static void | ||
7325 | cpp_pedwarn_with_line(cpp_reader * pfile, int line, int column, const char *msg) | ||
7326 | { | ||
7327 | if (CPP_OPTIONS(pfile)->pedantic_errors) | ||
7328 | cpp_error_with_line(pfile, column, line, msg); | ||
7329 | else | ||
7330 | cpp_warning_with_line(pfile, line, column, msg); | ||
7331 | } | ||
7332 | |||
7333 | /* Report a warning (or an error if pedantic_errors) | ||
7334 | * giving specified file name and line number, not current. */ | ||
7335 | |||
7336 | void | ||
7337 | cpp_pedwarn_with_file_and_line(cpp_reader * pfile, | ||
7338 | const char *file, int line, | ||
7339 | const char *msg, const char *arg1, | ||
7340 | const char *arg2, const char *arg3) | ||
7341 | { | ||
7342 | if (!CPP_OPTIONS(pfile)->pedantic_errors | ||
7343 | && CPP_OPTIONS(pfile)->inhibit_warnings) | ||
7344 | return; | ||
7345 | if (file) | ||
7346 | cpp_file_line_for_message(pfile, file, line, -1); | ||
7347 | cpp_message(pfile, CPP_OPTIONS(pfile)->pedantic_errors, | ||
7348 | msg, arg1, arg2, arg3); | ||
7349 | } | ||
7350 | |||
7351 | /* This defines "errno" properly for VMS, and gives us EACCES. */ | ||
7352 | #include <errno.h> | ||
7353 | #ifndef errno | ||
7354 | extern int errno; | ||
7355 | |||
7356 | #endif | ||
7357 | |||
7358 | #ifndef HAVE_STRERROR | ||
7359 | extern int sys_nerr; | ||
7360 | |||
7361 | #if defined(bsd4_4) | ||
7362 | extern const char *const sys_errlist[]; | ||
7363 | |||
7364 | #else | ||
7365 | extern char *sys_errlist[]; | ||
7366 | |||
7367 | #endif | ||
7368 | #endif /* HAVE_STRERROR */ | ||
7369 | |||
7370 | /* | ||
7371 | * my_strerror - return the descriptive text associated with an `errno' code. | ||
7372 | */ | ||
7373 | |||
7374 | static const char * | ||
7375 | my_strerror(int errnum) | ||
7376 | { | ||
7377 | const char *result; | ||
7378 | |||
7379 | #ifndef HAVE_STRERROR | ||
7380 | result = ((errnum < sys_nerr) ? sys_errlist[errnum] : 0); | ||
7381 | #else | ||
7382 | result = strerror(errnum); | ||
7383 | #endif | ||
7384 | |||
7385 | if (!result) | ||
7386 | result = "undocumented I/O error"; | ||
7387 | |||
7388 | return result; | ||
7389 | } | ||
7390 | |||
7391 | /* Error including a message from `errno'. */ | ||
7392 | |||
7393 | static void | ||
7394 | cpp_error_from_errno(cpp_reader * pfile, const char *name) | ||
7395 | { | ||
7396 | cpp_buffer *ip = cpp_file_buffer(pfile); | ||
7397 | |||
7398 | cpp_print_containing_files(pfile); | ||
7399 | |||
7400 | if (ip) | ||
7401 | cpp_file_line_for_message(pfile, ip->nominal_fname, ip->lineno, -1); | ||
7402 | |||
7403 | cpp_message(pfile, 1, "%s: %s", name, my_strerror(errno), NULL); | ||
7404 | } | ||
7405 | |||
7406 | void | ||
7407 | cpp_perror_with_name(cpp_reader * pfile, const char *name) | ||
7408 | { | ||
7409 | cpp_message(pfile, 1, "%s: %s: %s", progname, name, my_strerror(errno)); | ||
7410 | } | ||
7411 | |||
7412 | /* TODO: | ||
7413 | * No pre-compiled header file support. | ||
7414 | * | ||
7415 | * Possibly different enum token codes for each C/C++ token. | ||
7416 | * | ||
7417 | * Should clean up remaining directives to that do_XXX functions | ||
7418 | * only take two arguments and all have command_reads_line. | ||
7419 | * | ||
7420 | * Find and cleanup remaining uses of static variables, | ||
7421 | * | ||
7422 | * Support for trigraphs. | ||
7423 | * | ||
7424 | * Support -dM flag (dump_all_macros). | ||
7425 | * | ||
7426 | * Support for_lint flag. | ||
7427 | */ | ||
diff --git a/libraries/edje/src/bin/epp/cpplib.h b/libraries/edje/src/bin/epp/cpplib.h new file mode 100644 index 0000000..5653dd2 --- /dev/null +++ b/libraries/edje/src/bin/epp/cpplib.h | |||
@@ -0,0 +1,641 @@ | |||
1 | /* Definitions for CPP library. | ||
2 | Copyright (C) 1995 Free Software Foundation, Inc. | ||
3 | Written by Per Bothner, 1994-95. | ||
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 2, 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; if not, write to the Free Software | ||
17 | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | |||
19 | In other words, you are welcome to use, share and improve this program. | ||
20 | You are forbidden to forbid anyone else to use, share and improve | ||
21 | what you give them. Help stamp out software-hoarding! */ | ||
22 | |||
23 | #include <stdarg.h> | ||
24 | #include <sys/types.h> | ||
25 | #include <sys/stat.h> | ||
26 | |||
27 | #ifndef HOST_BITS_PER_WIDE_INT | ||
28 | |||
29 | #if HOST_BITS_PER_LONG > HOST_BITS_PER_INT | ||
30 | #define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONG | ||
31 | #define HOST_WIDE_INT long | ||
32 | #else | ||
33 | #define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_INT | ||
34 | #define HOST_WIDE_INT int | ||
35 | #endif | ||
36 | |||
37 | #endif | ||
38 | |||
39 | #define STATIC_BUFFERS | ||
40 | |||
41 | typedef struct cpp_reader cpp_reader; | ||
42 | typedef struct cpp_buffer cpp_buffer; | ||
43 | typedef struct cpp_options cpp_options; | ||
44 | |||
45 | enum cpp_token { | ||
46 | CPP_EOF = -1, | ||
47 | CPP_OTHER = 0, | ||
48 | CPP_COMMENT = 1, | ||
49 | CPP_HSPACE, | ||
50 | CPP_VSPACE, /* newlines and #line directives */ | ||
51 | CPP_NAME, | ||
52 | CPP_NUMBER, | ||
53 | CPP_CHAR, | ||
54 | CPP_STRING, | ||
55 | CPP_DIRECTIVE, | ||
56 | CPP_LPAREN, /* "(" */ | ||
57 | CPP_RPAREN, /* ")" */ | ||
58 | CPP_LBRACE, /* "{" */ | ||
59 | CPP_RBRACE, /* "}" */ | ||
60 | CPP_COMMA, /* "," */ | ||
61 | CPP_SEMICOLON, /* ";" */ | ||
62 | CPP_3DOTS, /* "..." */ | ||
63 | /* POP_TOKEN is returned when we've popped a cpp_buffer. */ | ||
64 | CPP_POP | ||
65 | }; | ||
66 | |||
67 | typedef enum cpp_token (*parse_underflow_t) (cpp_reader *); | ||
68 | typedef int (*parse_cleanup_t) (cpp_buffer *, cpp_reader *); | ||
69 | |||
70 | /* A parse_marker indicates a previous position, | ||
71 | which we can backtrack to. */ | ||
72 | |||
73 | struct parse_marker { | ||
74 | cpp_buffer *buf; | ||
75 | struct parse_marker *next; | ||
76 | int position; | ||
77 | }; | ||
78 | |||
79 | extern int cpp_handle_options(cpp_reader * pfile, int, char **); | ||
80 | extern enum cpp_token cpp_get_token(cpp_reader * pfile); | ||
81 | extern void cpp_skip_hspace(cpp_reader * pfile); | ||
82 | |||
83 | /* Maintain and search list of included files, for #import. */ | ||
84 | |||
85 | #define IMPORT_HASH_SIZE 31 | ||
86 | |||
87 | struct import_file { | ||
88 | char *name; | ||
89 | ino_t inode; | ||
90 | dev_t dev; | ||
91 | struct import_file *next; | ||
92 | }; | ||
93 | |||
94 | /* If we have a huge buffer, may need to cache more recent counts */ | ||
95 | #define CPP_LINE_BASE(BUF) ((BUF)->buf + (BUF)->line_base) | ||
96 | |||
97 | enum dump_type { | ||
98 | dump_none = 0, dump_only, dump_names, dump_definitions | ||
99 | }; | ||
100 | |||
101 | struct cpp_buffer { | ||
102 | unsigned char *buf; | ||
103 | unsigned char *cur; | ||
104 | unsigned char *rlimit; /* end of valid data */ | ||
105 | unsigned char *alimit; /* end of allocated buffer */ | ||
106 | unsigned char *prev; /* start of current token */ | ||
107 | |||
108 | const char *fname; | ||
109 | /* Filename specified with #line command. */ | ||
110 | const char *nominal_fname; | ||
111 | |||
112 | /* Record where in the search path this file was found. | ||
113 | * For #include_next. */ | ||
114 | struct file_name_list *dir; | ||
115 | |||
116 | long line_base; | ||
117 | long lineno; /* Line number at CPP_LINE_BASE. */ | ||
118 | long colno; /* Column number at CPP_LINE_BASE. */ | ||
119 | #ifndef STATIC_BUFFERS | ||
120 | cpp_buffer *chain; | ||
121 | #endif | ||
122 | parse_underflow_t underflow; | ||
123 | parse_cleanup_t cleanup; | ||
124 | void *data; | ||
125 | struct parse_marker *marks; | ||
126 | /* Value of if_stack at start of this file. | ||
127 | * Used to prohibit unmatched #endif (etc) in an include file. */ | ||
128 | struct if_stack *if_stack; | ||
129 | |||
130 | /* True if this is a header file included using <FILENAME>. */ | ||
131 | char system_header_p; | ||
132 | char seen_eof; | ||
133 | |||
134 | /* True if buffer contains escape sequences. | ||
135 | * Currently there are are only two kind: | ||
136 | * "@-" means following identifier should not be macro-expanded. | ||
137 | * "@ " means a token-separator. This turns into " " in final output | ||
138 | * if not stringizing and needed to separate tokens; otherwise nothing. | ||
139 | * "@@" means a normal '@'. | ||
140 | * (An '@' inside a string stands for itself and is never an escape.) */ | ||
141 | char has_escapes; | ||
142 | }; | ||
143 | |||
144 | struct cpp_pending; /* Forward declaration - for C++. */ | ||
145 | struct file_name_map_list; | ||
146 | |||
147 | typedef struct assertion_hashnode ASSERTION_HASHNODE; | ||
148 | |||
149 | #define ASSERTION_HASHSIZE 37 | ||
150 | |||
151 | #ifdef STATIC_BUFFERS | ||
152 | /* Maximum nesting of cpp_buffers. We use a static limit, partly for | ||
153 | efficiency, and partly to limit runaway recursion. */ | ||
154 | #define CPP_STACK_MAX 200 | ||
155 | #endif | ||
156 | |||
157 | struct cpp_reader { | ||
158 | unsigned char *limit; | ||
159 | parse_underflow_t get_token; | ||
160 | cpp_buffer *buffer; | ||
161 | #ifdef STATIC_BUFFERS | ||
162 | cpp_buffer buffer_stack[CPP_STACK_MAX]; | ||
163 | #endif | ||
164 | |||
165 | int errors; /* Error counter for exit code */ | ||
166 | void *data; | ||
167 | |||
168 | unsigned char *token_buffer; | ||
169 | int token_buffer_size; | ||
170 | |||
171 | /* Line where a newline was first seen in a string constant. */ | ||
172 | int multiline_string_line; | ||
173 | |||
174 | /* Current depth in #include directives that use <...>. */ | ||
175 | int system_include_depth; | ||
176 | |||
177 | /* List of included files that contained #pragma once. */ | ||
178 | struct file_name_list *dont_repeat_files; | ||
179 | |||
180 | /* List of other included files. | ||
181 | * If ->control_macro if nonzero, the file had a #ifndef | ||
182 | * around the entire contents, and ->control_macro gives the macro name. */ | ||
183 | struct file_name_list *all_include_files; | ||
184 | |||
185 | /* Current maximum length of directory names in the search path | ||
186 | * for include files. (Altered as we get more of them.) */ | ||
187 | int max_include_len; | ||
188 | |||
189 | /* Hash table of files already included with #include or #import. */ | ||
190 | struct import_file *import_hash_table[IMPORT_HASH_SIZE]; | ||
191 | |||
192 | struct if_stack *if_stack; | ||
193 | |||
194 | /* Nonzero means we are inside an IF during a -pcp run. In this mode | ||
195 | * macro expansion is done, and preconditions are output for all macro | ||
196 | * uses requiring them. */ | ||
197 | char pcp_inside_if; | ||
198 | |||
199 | /* Nonzero means we have printed (while error reporting) a list of | ||
200 | * containing files that matches the current status. */ | ||
201 | char input_stack_listing_current; | ||
202 | |||
203 | /* If non-zero, macros are not expanded. */ | ||
204 | char no_macro_expand; | ||
205 | |||
206 | /* Print column number in error messages. */ | ||
207 | char show_column; | ||
208 | |||
209 | /* We're printed a warning recommending against using #import. */ | ||
210 | char import_warning; | ||
211 | |||
212 | /* If true, character between '<' and '>' are a single (string) token. */ | ||
213 | char parsing_include_directive; | ||
214 | |||
215 | /* True if escape sequences (as described for has_escapes in | ||
216 | * parse_buffer) should be emitted. */ | ||
217 | char output_escapes; | ||
218 | |||
219 | /* 0: Have seen non-white-space on this line. | ||
220 | * 1: Only seen white space so far on this line. | ||
221 | * 2: Only seen white space so far in this file. */ | ||
222 | char only_seen_white; | ||
223 | |||
224 | /* Nonzero means this file was included with a -imacros or -include | ||
225 | * command line and should not be recorded as an include file. */ | ||
226 | |||
227 | int no_record_file; | ||
228 | |||
229 | long lineno; | ||
230 | |||
231 | struct tm *timebuf; | ||
232 | |||
233 | ASSERTION_HASHNODE *assertion_hashtab[ASSERTION_HASHSIZE]; | ||
234 | |||
235 | /* Buffer of -M output. */ | ||
236 | char *deps_buffer; | ||
237 | |||
238 | /* Number of bytes allocated in above. */ | ||
239 | int deps_allocated_size; | ||
240 | |||
241 | /* Number of bytes used. */ | ||
242 | int deps_size; | ||
243 | |||
244 | /* Number of bytes since the last newline. */ | ||
245 | int deps_column; | ||
246 | }; | ||
247 | |||
248 | #define CPP_BUF_PEEK(BUFFER) \ | ||
249 | ((BUFFER)->cur < (BUFFER)->rlimit ? *(BUFFER)->cur : EOF) | ||
250 | #define CPP_BUF_GET(BUFFER) \ | ||
251 | ((BUFFER)->cur < (BUFFER)->rlimit ? *(BUFFER)->cur++ : EOF) | ||
252 | #define CPP_FORWARD(BUFFER, N) ((BUFFER)->cur += (N)) | ||
253 | |||
254 | /* Number of characters currently in PFILE's output buffer. */ | ||
255 | #define CPP_WRITTEN(PFILE) ((PFILE)->limit - (PFILE)->token_buffer) | ||
256 | #define CPP_PWRITTEN(PFILE) ((PFILE)->limit) | ||
257 | |||
258 | /* Make sure PFILE->token_buffer has space for at least N more characters. */ | ||
259 | #define CPP_RESERVE(PFILE, N) \ | ||
260 | ((unsigned int)(CPP_WRITTEN (PFILE) + N) > (unsigned int) (PFILE)->token_buffer_size \ | ||
261 | && (cpp_grow_buffer (PFILE, N), 0)) | ||
262 | |||
263 | /* Append string STR (of length N) to PFILE's output buffer. | ||
264 | Assume there is enough space. */ | ||
265 | #define CPP_PUTS_Q(PFILE, STR, N) \ | ||
266 | do { memcpy ((PFILE)->limit, STR, (N)); (PFILE)->limit += (N); } while(0) | ||
267 | /* Append string STR (of length N) to PFILE's output buffer. Make space. */ | ||
268 | #define CPP_PUTS(PFILE, STR, N) \ | ||
269 | do { CPP_RESERVE(PFILE, N); CPP_PUTS_Q(PFILE, STR,N); } while(0) | ||
270 | /* Append character CH to PFILE's output buffer. Assume sufficient space. */ | ||
271 | #define CPP_PUTC_Q(PFILE, CH) (*(PFILE)->limit++ = (CH)) | ||
272 | /* Append character CH to PFILE's output buffer. Make space if need be. */ | ||
273 | #define CPP_PUTC(PFILE, CH) \ | ||
274 | do { CPP_RESERVE (PFILE, 1); CPP_PUTC_Q (PFILE, CH); } while(0) | ||
275 | /* Make sure PFILE->limit is followed by '\0'. */ | ||
276 | #define CPP_NUL_TERMINATE_Q(PFILE) (*(PFILE)->limit = 0) | ||
277 | #define CPP_NUL_TERMINATE(PFILE) \ | ||
278 | do { CPP_RESERVE(PFILE, 1); *(PFILE)->limit = 0; } while(0) | ||
279 | #define CPP_ADJUST_WRITTEN(PFILE,DELTA) ((PFILE)->limit += (DELTA)) | ||
280 | #define CPP_SET_WRITTEN(PFILE,N) ((PFILE)->limit = (PFILE)->token_buffer + (N)) | ||
281 | |||
282 | #define CPP_OPTIONS(PFILE) ((cpp_options*)(PFILE)->data) | ||
283 | #define CPP_BUFFER(PFILE) ((PFILE)->buffer) | ||
284 | #ifdef STATIC_BUFFERS | ||
285 | #define CPP_PREV_BUFFER(BUFFER) ((BUFFER)+1) | ||
286 | #define CPP_NULL_BUFFER(PFILE) (&(PFILE)->buffer_stack[CPP_STACK_MAX]) | ||
287 | #else | ||
288 | #define CPP_PREV_BUFFER(BUFFER) ((BUFFER)->chain) | ||
289 | #define CPP_NULL_BUFFER(PFILE) ((cpp_buffer*)0) | ||
290 | #endif | ||
291 | |||
292 | /* Pointed to by parse_file::data. */ | ||
293 | struct cpp_options { | ||
294 | const char *in_fname; | ||
295 | |||
296 | /* Name of output file, for error messages. */ | ||
297 | const char *out_fname; | ||
298 | |||
299 | struct file_name_map_list *map_list; | ||
300 | |||
301 | /* Non-0 means -v, so print the full set of include dirs. */ | ||
302 | char verbose; | ||
303 | |||
304 | /* Nonzero means use extra default include directories for C++. */ | ||
305 | |||
306 | char cplusplus; | ||
307 | |||
308 | /* Nonzero means handle cplusplus style comments */ | ||
309 | |||
310 | char cplusplus_comments; | ||
311 | |||
312 | /* Nonzero means handle #import, for objective C. */ | ||
313 | |||
314 | char objc; | ||
315 | |||
316 | /* Nonzero means this is an assembly file, and allow | ||
317 | * unknown directives, which could be comments. */ | ||
318 | |||
319 | int lang_asm; | ||
320 | |||
321 | /* Nonzero means turn NOTREACHED into #pragma NOTREACHED etc */ | ||
322 | |||
323 | char for_lint; | ||
324 | |||
325 | /* Nonzero means handle CHILL comment syntax | ||
326 | * and output CHILL string delimiter for __DATE___ etc. */ | ||
327 | |||
328 | char chill; | ||
329 | |||
330 | /* Nonzero means copy comments into the output file. */ | ||
331 | |||
332 | char put_out_comments; | ||
333 | |||
334 | /* Nonzero means don't process the ANSI trigraph sequences. */ | ||
335 | |||
336 | char no_trigraphs; | ||
337 | |||
338 | /* Nonzero means print the names of included files rather than | ||
339 | * the preprocessed output. 1 means just the #include "...", | ||
340 | * 2 means #include <...> as well. */ | ||
341 | |||
342 | char print_deps; | ||
343 | |||
344 | /* Nonzero if missing .h files in -M output are assumed to be generated | ||
345 | * files and not errors. */ | ||
346 | |||
347 | char print_deps_missing_files; | ||
348 | |||
349 | /* If true, fopen (deps_file, "a") else fopen (deps_file, "w"). */ | ||
350 | char print_deps_append; | ||
351 | |||
352 | /* Nonzero means print names of header files (-H). */ | ||
353 | |||
354 | char print_include_names; | ||
355 | |||
356 | /* Nonzero means try to make failure to fit ANSI C an error. */ | ||
357 | |||
358 | char pedantic_errors; | ||
359 | |||
360 | /* Nonzero means don't print warning messages. -w. */ | ||
361 | |||
362 | char inhibit_warnings; | ||
363 | |||
364 | /* Nonzero means warn if slash-star appears in a comment. */ | ||
365 | |||
366 | char warn_comments; | ||
367 | |||
368 | /* Nonzero means warn if there are any trigraphs. */ | ||
369 | |||
370 | char warn_trigraphs; | ||
371 | |||
372 | /* Nonzero means warn if #import is used. */ | ||
373 | |||
374 | char warn_import; | ||
375 | |||
376 | /* Nonzero means warn if a macro argument is (or would be) | ||
377 | * stringified with -traditional. */ | ||
378 | |||
379 | char warn_stringify; | ||
380 | |||
381 | /* Nonzero means turn warnings into errors. */ | ||
382 | |||
383 | char warnings_are_errors; | ||
384 | |||
385 | /* Nonzero causes output not to be done, | ||
386 | * but directives such as #define that have side effects | ||
387 | * are still obeyed. */ | ||
388 | |||
389 | char no_output; | ||
390 | |||
391 | /* Nonzero means don't output line number information. */ | ||
392 | |||
393 | char no_line_commands; | ||
394 | |||
395 | /* Nonzero means output the text in failing conditionals, | ||
396 | inside #failed ... #endfailed. */ | ||
397 | |||
398 | char output_conditionals; | ||
399 | |||
400 | /* Nonzero means -I- has been seen, | ||
401 | * so don't look for #include "foo" the source-file directory. */ | ||
402 | char ignore_srcdir; | ||
403 | |||
404 | /* Zero means dollar signs are punctuation. | ||
405 | -$ stores 0; -traditional may store 1. Default is 1 for VMS, 0 otherwise. | ||
406 | This must be 0 for correct processing of this ANSI C program: | ||
407 | #define foo(a) #a | ||
408 | #define lose(b) foo (b) | ||
409 | #define test$ | ||
410 | lose (test) */ | ||
411 | char dollars_in_ident; | ||
412 | #ifndef DOLLARS_IN_IDENTIFIERS | ||
413 | #define DOLLARS_IN_IDENTIFIERS 1 | ||
414 | #endif | ||
415 | |||
416 | /* Nonzero means try to imitate old fashioned non-ANSI preprocessor. */ | ||
417 | char traditional; | ||
418 | |||
419 | /* Nonzero means give all the error messages the ANSI standard requires. */ | ||
420 | char pedantic; | ||
421 | |||
422 | char done_initializing; | ||
423 | |||
424 | struct file_name_list *include; /* First dir to search */ | ||
425 | /* First dir to search for <file> */ | ||
426 | /* This is the first element to use for #include <...>. | ||
427 | * If it is 0, use the entire chain for such includes. */ | ||
428 | struct file_name_list *first_bracket_include; | ||
429 | /* This is the first element in the chain that corresponds to | ||
430 | * a directory of system header files. */ | ||
431 | struct file_name_list *first_system_include; | ||
432 | struct file_name_list *last_include; /* Last in chain */ | ||
433 | |||
434 | /* Chain of include directories to put at the end of the other chain. */ | ||
435 | struct file_name_list *after_include; | ||
436 | struct file_name_list *last_after_include; /* Last in chain */ | ||
437 | |||
438 | /* Chain to put at the start of the system include files. */ | ||
439 | struct file_name_list *before_system; | ||
440 | struct file_name_list *last_before_system; /* Last in chain */ | ||
441 | |||
442 | /* Directory prefix that should replace `/usr' in the standard | ||
443 | * include file directories. */ | ||
444 | char *include_prefix; | ||
445 | |||
446 | char inhibit_predefs; | ||
447 | char no_standard_includes; | ||
448 | char no_standard_cplusplus_includes; | ||
449 | |||
450 | /* dump_only means inhibit output of the preprocessed text | ||
451 | and instead output the definitions of all user-defined | ||
452 | macros in a form suitable for use as input to cccp. | ||
453 | dump_names means pass #define and the macro name through to output. | ||
454 | dump_definitions means pass the whole definition (plus #define) through | ||
455 | */ | ||
456 | |||
457 | enum dump_type dump_macros; | ||
458 | |||
459 | /* Nonzero means pass all #define and #undef directives which we actually | ||
460 | process through to the output stream. This feature is used primarily | ||
461 | to allow cc1 to record the #defines and #undefs for the sake of | ||
462 | debuggers which understand about preprocessor macros, but it may | ||
463 | also be useful with -E to figure out how symbols are defined, and | ||
464 | where they are defined. */ | ||
465 | int debug_output; | ||
466 | |||
467 | /* Pending -D, -U and -A options, in reverse order. */ | ||
468 | struct cpp_pending *pending; | ||
469 | |||
470 | /* File name which deps are being written to. | ||
471 | * This is 0 if deps are being written to stdout. */ | ||
472 | char *deps_file; | ||
473 | |||
474 | /* Target-name to write with the dependency information. */ | ||
475 | char *deps_target; | ||
476 | }; | ||
477 | |||
478 | #define CPP_TRADITIONAL(PFILE) (CPP_OPTIONS(PFILE)-> traditional) | ||
479 | #define CPP_PEDANTIC(PFILE) (CPP_OPTIONS (PFILE)->pedantic) | ||
480 | #define CPP_PRINT_DEPS(PFILE) (CPP_OPTIONS (PFILE)->print_deps) | ||
481 | |||
482 | /* Name under which this program was invoked. */ | ||
483 | |||
484 | extern char *progname; | ||
485 | |||
486 | /* The structure of a node in the hash table. The hash table | ||
487 | has entries for all tokens defined by #define commands (type T_MACRO), | ||
488 | plus some special tokens like __LINE__ (these each have their own | ||
489 | type, and the appropriate code is run when that type of node is seen. | ||
490 | It does not contain control words like "#define", which are recognized | ||
491 | by a separate piece of code. */ | ||
492 | |||
493 | /* different flavors of hash nodes --- also used in keyword table */ | ||
494 | enum node_type { | ||
495 | T_DEFINE = 1, /* the `#define' keyword */ | ||
496 | T_INCLUDE, /* the `#include' keyword */ | ||
497 | T_INCLUDE_NEXT, /* the `#include_next' keyword */ | ||
498 | T_IMPORT, /* the `#import' keyword */ | ||
499 | T_IFDEF, /* the `#ifdef' keyword */ | ||
500 | T_IFNDEF, /* the `#ifndef' keyword */ | ||
501 | T_IF, /* the `#if' keyword */ | ||
502 | T_ELSE, /* `#else' */ | ||
503 | T_PRAGMA, /* `#pragma' */ | ||
504 | T_ELIF, /* `#elif' */ | ||
505 | T_UNDEF, /* `#undef' */ | ||
506 | T_LINE, /* `#line' */ | ||
507 | T_ERROR, /* `#error' */ | ||
508 | T_WARNING, /* `#warning' */ | ||
509 | T_ENDIF, /* `#endif' */ | ||
510 | T_SCCS, /* `#sccs', used on system V. */ | ||
511 | T_IDENT, /* `#ident', used on system V. */ | ||
512 | T_ASSERT, /* `#assert', taken from system V. */ | ||
513 | T_UNASSERT, /* `#unassert', taken from system V. */ | ||
514 | T_SPECLINE, /* special symbol `__LINE__' */ | ||
515 | T_DATE, /* `__DATE__' */ | ||
516 | T_FILE, /* `__FILE__' */ | ||
517 | T_BASE_FILE, /* `__BASE_FILE__' */ | ||
518 | T_INCLUDE_LEVEL, /* `__INCLUDE_LEVEL__' */ | ||
519 | T_VERSION, /* `__VERSION__' */ | ||
520 | T_SIZE_TYPE, /* `__SIZE_TYPE__' */ | ||
521 | T_PTRDIFF_TYPE, /* `__PTRDIFF_TYPE__' */ | ||
522 | T_WCHAR_TYPE, /* `__WCHAR_TYPE__' */ | ||
523 | T_USER_LABEL_PREFIX_TYPE, /* `__USER_LABEL_PREFIX__' */ | ||
524 | T_REGISTER_PREFIX_TYPE, /* `__REGISTER_PREFIX__' */ | ||
525 | T_TIME, /* `__TIME__' */ | ||
526 | T_CONST, /* Constant value, used by `__STDC__' */ | ||
527 | T_MACRO, /* macro defined by `#define' */ | ||
528 | T_DISABLED, /* macro temporarily turned off for rescan */ | ||
529 | T_SPEC_DEFINED, /* special `defined' macro for use in #if statements */ | ||
530 | T_PCSTRING, /* precompiled string (hashval is KEYDEF *) */ | ||
531 | T_UNUSED /* Used for something not defined. */ | ||
532 | }; | ||
533 | |||
534 | /* Structure allocated for every #define. For a simple replacement | ||
535 | such as | ||
536 | #define foo bar , | ||
537 | nargs = -1, the `pattern' list is null, and the expansion is just | ||
538 | the replacement text. Nargs = 0 means a functionlike macro with no args, | ||
539 | e.g., | ||
540 | #define getchar() getc (stdin) . | ||
541 | When there are args, the expansion is the replacement text with the | ||
542 | args squashed out, and the reflist is a list describing how to | ||
543 | build the output from the input: e.g., "3 chars, then the 1st arg, | ||
544 | then 9 chars, then the 3rd arg, then 0 chars, then the 2nd arg". | ||
545 | The chars here come from the expansion. Whatever is left of the | ||
546 | expansion after the last arg-occurrence is copied after that arg. | ||
547 | Note that the reflist can be arbitrarily long--- | ||
548 | its length depends on the number of times the arguments appear in | ||
549 | the replacement text, not how many args there are. Example: | ||
550 | #define f(x) x+x+x+x+x+x+x would have replacement text "++++++" and | ||
551 | pattern list | ||
552 | { (0, 1), (1, 1), (1, 1), ..., (1, 1), NULL } | ||
553 | where (x, y) means (nchars, argno). */ | ||
554 | |||
555 | typedef struct reflist reflist; | ||
556 | struct reflist { | ||
557 | reflist *next; | ||
558 | char stringify; /* nonzero if this arg was preceded by a | ||
559 | * # operator. */ | ||
560 | char raw_before; /* Nonzero if a ## operator before arg. */ | ||
561 | char raw_after; /* Nonzero if a ## operator after arg. */ | ||
562 | char rest_args; /* Nonzero if this arg. absorbs the rest */ | ||
563 | int nchars; /* Number of literal chars to copy before | ||
564 | * this arg occurrence. */ | ||
565 | int argno; /* Number of arg to substitute (origin-0) */ | ||
566 | }; | ||
567 | |||
568 | typedef struct definition DEFINITION; | ||
569 | struct definition { | ||
570 | int nargs; | ||
571 | int length; /* length of expansion string */ | ||
572 | int predefined; /* True if the macro was builtin or */ | ||
573 | /* came from the command line */ | ||
574 | unsigned char *expansion; | ||
575 | int line; /* Line number of definition */ | ||
576 | const char *file; /* File of definition */ | ||
577 | char rest_args; /* Nonzero if last arg. absorbs the rest */ | ||
578 | reflist *pattern; | ||
579 | union { | ||
580 | /* Names of macro args, concatenated in reverse order | ||
581 | * with comma-space between them. | ||
582 | * The only use of this is that we warn on redefinition | ||
583 | * if this differs between the old and new definitions. */ | ||
584 | unsigned char *argnames; | ||
585 | } args; | ||
586 | }; | ||
587 | |||
588 | extern unsigned char is_idchar[256]; | ||
589 | |||
590 | /* Stack of conditionals currently in progress | ||
591 | (including both successful and failing conditionals). */ | ||
592 | |||
593 | struct if_stack { | ||
594 | struct if_stack *next; /* for chaining to the next stack frame */ | ||
595 | const char *fname; /* copied from input when frame is made */ | ||
596 | int lineno; /* similarly */ | ||
597 | int if_succeeded; /* true if a leg of this if-group | ||
598 | * has been passed through rescan */ | ||
599 | unsigned char *control_macro; /* For #ifndef at start of file, | ||
600 | * this is the macro name tested. */ | ||
601 | enum node_type type; /* type of last directive seen in this group */ | ||
602 | }; | ||
603 | typedef struct if_stack IF_STACK_FRAME; | ||
604 | |||
605 | extern void cpp_buf_line_and_col(cpp_buffer *, long *, long *); | ||
606 | extern cpp_buffer *cpp_file_buffer(cpp_reader *); | ||
607 | extern void cpp_define(cpp_reader *, unsigned char *); | ||
608 | |||
609 | extern void cpp_error(cpp_reader * pfile, const char *msg, ...); | ||
610 | extern void cpp_warning(cpp_reader * pfile, const char *msg, ...); | ||
611 | extern void cpp_pedwarn(cpp_reader * pfile, const char *msg, ...); | ||
612 | extern void cpp_fatal(const char *msg, ...); | ||
613 | extern void cpp_file_line_for_message(cpp_reader * pfile, | ||
614 | const char *filename, int line, | ||
615 | int column); | ||
616 | extern void cpp_perror_with_name(cpp_reader * pfile, const char *name); | ||
617 | extern void cpp_pfatal_with_name(cpp_reader * pfile, const char *name); | ||
618 | extern void cpp_message(cpp_reader * pfile, int is_error, | ||
619 | const char *msg, ...); | ||
620 | extern void cpp_message_v(cpp_reader * pfile, int is_error, | ||
621 | const char *msg, va_list args); | ||
622 | |||
623 | extern void cpp_grow_buffer(cpp_reader * pfile, long n); | ||
624 | extern int cpp_parse_escape(cpp_reader * pfile, char **string_ptr); | ||
625 | |||
626 | void cpp_print_containing_files(cpp_reader * pfile); | ||
627 | HOST_WIDE_INT cpp_parse_expr(cpp_reader * pfile); | ||
628 | void skip_rest_of_line(cpp_reader * pfile); | ||
629 | void init_parse_file(cpp_reader * pfile); | ||
630 | void init_parse_options(struct cpp_options *opts); | ||
631 | int push_parse_file(cpp_reader * pfile, const char *fname); | ||
632 | void cpp_finish(cpp_reader * pfile); | ||
633 | int cpp_read_check_assertion(cpp_reader * pfile); | ||
634 | |||
635 | void *xmalloc(unsigned size); | ||
636 | void *xrealloc(void *old, unsigned size); | ||
637 | void *xcalloc(unsigned number, unsigned size); | ||
638 | |||
639 | #ifdef __EMX__ | ||
640 | #define PATH_SEPARATOR ';' | ||
641 | #endif | ||
diff --git a/libraries/edje/src/bin/epp/cppmain.c b/libraries/edje/src/bin/epp/cppmain.c new file mode 100644 index 0000000..45b67b5 --- /dev/null +++ b/libraries/edje/src/bin/epp/cppmain.c | |||
@@ -0,0 +1,142 @@ | |||
1 | /* CPP main program, using CPP Library. | ||
2 | * Copyright (C) 1995 Free Software Foundation, Inc. | ||
3 | * Written by Per Bothner, 1994-95. | ||
4 | * Copyright (C) 2003-2011 Kim Woelders | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2, or (at your option) any | ||
9 | * later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | * | ||
20 | * In other words, you are welcome to use, share and improve this program. | ||
21 | * You are forbidden to forbid anyone else to use, share and improve | ||
22 | * what you give them. Help stamp out software-hoarding! */ | ||
23 | |||
24 | #ifdef HAVE_CONFIG_H | ||
25 | # include <config.h> | ||
26 | #endif | ||
27 | |||
28 | #include <stdio.h> | ||
29 | #include <string.h> | ||
30 | #include <stdlib.h> | ||
31 | |||
32 | #include "cpplib.h" | ||
33 | |||
34 | #define EPP_DEBUG 0 | ||
35 | |||
36 | cpp_reader parse_in; | ||
37 | cpp_options options; | ||
38 | |||
39 | int | ||
40 | main(int argc, char **argv) | ||
41 | { | ||
42 | char *p; | ||
43 | int i; | ||
44 | int argi = 1; /* Next argument to handle. */ | ||
45 | struct cpp_options *opts = &options; | ||
46 | enum cpp_token kind; | ||
47 | int got_text; | ||
48 | |||
49 | p = argv[0] + strlen(argv[0]); | ||
50 | #ifndef __EMX__ | ||
51 | while (p != argv[0] && p[-1] != '/') | ||
52 | #else | ||
53 | while (p != argv[0] && p[-1] != '/' && p[-1] != '\\') | ||
54 | #endif | ||
55 | --p; | ||
56 | progname = p; | ||
57 | |||
58 | init_parse_file(&parse_in); | ||
59 | parse_in.data = opts; | ||
60 | |||
61 | init_parse_options(opts); | ||
62 | |||
63 | argi += cpp_handle_options(&parse_in, argc - argi, argv + argi); | ||
64 | if (argi < argc) | ||
65 | cpp_fatal("Invalid option `%s'", argv[argi]); | ||
66 | parse_in.show_column = 1; | ||
67 | |||
68 | i = push_parse_file(&parse_in, opts->in_fname); | ||
69 | if (i != SUCCESS_EXIT_CODE) | ||
70 | return i; | ||
71 | |||
72 | /* Now that we know the input file is valid, open the output. */ | ||
73 | |||
74 | if (!opts->out_fname || !strcmp(opts->out_fname, "")) | ||
75 | opts->out_fname = "stdout"; | ||
76 | else if (!freopen(opts->out_fname, "w", stdout)) | ||
77 | cpp_pfatal_with_name(&parse_in, opts->out_fname); | ||
78 | |||
79 | got_text = 0; | ||
80 | for (i = 0;; i++) | ||
81 | { | ||
82 | kind = cpp_get_token(&parse_in); | ||
83 | #if EPP_DEBUG | ||
84 | fprintf(stderr, "%03d: kind=%d len=%d out=%d text=%d\n", i, | ||
85 | kind, CPP_WRITTEN(&parse_in), !opts->no_output, got_text); | ||
86 | #endif | ||
87 | switch (kind) | ||
88 | { | ||
89 | case CPP_EOF: | ||
90 | goto done; | ||
91 | |||
92 | case CPP_HSPACE: | ||
93 | continue; | ||
94 | |||
95 | case CPP_VSPACE: | ||
96 | break; | ||
97 | |||
98 | default: | ||
99 | case CPP_OTHER: | ||
100 | case CPP_NAME: | ||
101 | case CPP_NUMBER: | ||
102 | case CPP_CHAR: | ||
103 | case CPP_STRING: | ||
104 | case CPP_LPAREN: | ||
105 | case CPP_RPAREN: | ||
106 | case CPP_LBRACE: | ||
107 | case CPP_RBRACE: | ||
108 | case CPP_COMMA: | ||
109 | case CPP_SEMICOLON: | ||
110 | case CPP_3DOTS: | ||
111 | got_text = 1; | ||
112 | continue; | ||
113 | |||
114 | case CPP_COMMENT: | ||
115 | case CPP_DIRECTIVE: | ||
116 | case CPP_POP: | ||
117 | continue; | ||
118 | } | ||
119 | #if EPP_DEBUG | ||
120 | fprintf(stderr, "'"); | ||
121 | fwrite(parse_in.token_buffer, 1, CPP_WRITTEN(&parse_in), stderr); | ||
122 | fprintf(stderr, "'\n"); | ||
123 | #endif | ||
124 | if (!opts->no_output) | ||
125 | { | ||
126 | size_t n; | ||
127 | |||
128 | n = CPP_WRITTEN(&parse_in); | ||
129 | if (fwrite(parse_in.token_buffer, 1, n, stdout) != n) | ||
130 | exit(FATAL_EXIT_CODE); | ||
131 | } | ||
132 | parse_in.limit = parse_in.token_buffer; | ||
133 | got_text = 0; | ||
134 | } | ||
135 | |||
136 | done: | ||
137 | cpp_finish(&parse_in); | ||
138 | |||
139 | if (parse_in.errors) | ||
140 | exit(FATAL_EXIT_CODE); | ||
141 | exit(SUCCESS_EXIT_CODE); | ||
142 | } | ||