Compare commits

...

1 Commits

Author SHA1 Message Date
dholland b55a0f6c5c Import tradcpp 0.5.3 2022-08-27 21:46:47 +00:00
112 changed files with 7469 additions and 0 deletions

View File

@ -0,0 +1,4 @@
repo: 67fa1db0651cd970068d0660e1b695e30b04f904
node: 9aa91d3fe3a39cb8af08f231ba22a3aa1bbd57eb
branch: default
tag: release-0.5.3

9
external/bsd/tradcpp/dist/.hgtags vendored Normal file
View File

@ -0,0 +1,9 @@
8a955e3dda2ce67fd729944f4e19316d005c0731 posted-20101220
1e4eef5bf88d70a98396b175cd0891a41d79388e release-0.1
3ad1cd80f5a07b0ce19131f3e58f2560e4a30d9d release-0.2
31fc4251ec3bd624af9d00592b7a9ec9d22a611a release-0.3
85b66cc0344e6222c92b8dd324542ec6f64239e9 release-0.3.1
281317d304782fe3d60f4786a1480fe5ce485ebd release-0.4
557824449ec7df3d63b491efbf53c9b73589346d release-0.5
ab06d46bf5cc46cdacba18d82a6b380bfe09d81e release-0.5.1
18b872f362175fd78ddf1f12ee24f85ef19b6254 release-0.5.2

91
external/bsd/tradcpp/dist/CHANGES vendored Normal file
View File

@ -0,0 +1,91 @@
release 0.5.3 (20190121)
- Fix markup typo in the man page.
- Abort on line numbering or column numbering overflow. Line
numbers are limited to values that fit in "unsigned int". Also
reject input lines longer than 2^32-1 characters. It seems
reasonable to presume that any input that violates these
constraints is someone screwing around and not a serious attempt
to compile or preprocess anything useful. Done in response to
n2129, but without getting into any of the silliness found there.
- Recognize __ia64__ for IA64 builds.
- Recognize __aarch64__ for 64-bit ARM builds, as sent in by
various people.
- Recognize __riscv__ and __riscv64__ for risc-v builds.
release 0.5.2 (20160904)
- Fix typo in -U usage message, noticed by Joerg.
- Add a -debuglog option to send an execution trace to a file.
Intended to be used when debugging imake templates and other
complex input, not for debugging tradcpp itself.
release 0.5.1 (20150612)
- Fix a stupid regression in 0.5 that causes it to not recognize a
pile of options.
- Fix output corruption caused by mishandling which macros are
currently in use. In particular, "curmacro" is only valid while
we're parsing a macro name and arguments, and can change once we
start expanding, so don't use it to clear the in-use flag. This
problem has been around all along but was only just exposed.
- Also don't set curmacro to null after calling expand_domacro as
that can cause us to think a macro name we just read is defined().
This one was introduced in 0.5.
- Don't use "remove" as a local variable as gcc 4.1 gets upset
about it vs. remove(3) in stdio.h.
release 0.5 (20150612)
- Don't report unclosed comments as "No newline at end of file".
- Don't rely on <stdbool.h> existing, as (predictably) it doesn't
work on Solaris.
- Similarly, don't rely on C11 anonymous unions as the Solaris
compiler vomits on them.
- Typo fix in man page from Jason McIntyre; and change "Usage" to
"usage" in usage for pedantic reasons, from Igor Sobrado.
- Accept "-" as either input or output file name to mean stdin or
stdout respectively. Suggested by Jonathan Gray.
- Fix output spacing behavior to match gcc when newlines appear in or
while looking for macro arguments. Partly from Joerg Sonnenberger.
- Implement __FILE__ and __LINE__ macros. Mostly from Joerg Sonnenberger.
- Implement #line. Partly from Joerg Sonnenberger.
- Declare usage() with PF(). From wiz.
release 0.4 (20130713)
- Fix stupid build problem introduced in 0.3.1.
- Accept and ignore -m32, which imake issues willy-nilly on a bunch
of platforms. I thought this had already been done, but apparently
not.
- Don't use the <err.h> functions. There are still people out there
using legacy systems missing them.
- Sort out some more issues pertaining to handling quoted strings.
- Add some more tests.
release 0.3.1 (20130709)
- Don't leak memory and assert if a bad command-line option comes
after a -D or a -include foo.
- Since imake is a principal application for tradcpp and imake carefully
hides what it's doing when you run it, when rejecting an invalid option
be sure to report *what* that option is.
release 0.3 (20130616)
- Don't eval the control expression of the first #if of a block when
already in a false block; it might not be valid. Reported by
Baptiste Daroussin.
- Don't recognize comments within character constants.
- Don't recognize macro argument parentheses or commas within strings,
or within character constants either.
release 0.2 (20130611)
- auto-recognize more builtin PowerPC and mips macros
- pass -Wunused (partly from Baptiste Daroussin)
- allow absolute paths in include files (partly from Baptiste Daroussin)
- don't use getprogname() in the name of portability
- add tests arising from December 2010 tech-toolchain thread (one
from der Mouse, one of mine)
- clean out usage of sys/cdefs.h macros and don't use the implementation
namespace
- make -Wcomment work again
- fix handling of relative includes
- provide a man page
- other minor improvements
release 0.1 (20130610)
- first release, works with at least some imake templates

11
external/bsd/tradcpp/dist/Makefile vendored Normal file
View File

@ -0,0 +1,11 @@
# $NetBSD: Makefile,v 1.1.1.1 2022/08/27 21:46:47 dholland Exp $
PROG= tradcpp
SRCS= main.c \
files.c directive.c eval.c macro.c output.c \
place.c array.c utils.c
WARNS= 5
#DBG=-g
.include <bsd.prog.mk>

37
external/bsd/tradcpp/dist/TODO vendored Normal file
View File

@ -0,0 +1,37 @@
not implemented:
- mode.input_allow_dollars.
- column counts do not take tabstops into account.
- mode.output_linenumbers.
- mode.do_depend.
- mode.do_macrolist.
- mode.do_trace.
- warns.endiflabels. (they cause errors)
- warns.unused.
- the -iremap option.
- $CPP_RESTRICTED
- other environment variables
tidy up:
- get rid of inlinedefs.h
- use of places in and below macro.c is pretty bogus.
- macro code should be reworked.
- place_changefile is manky and wastes memory. Also, in an ideal
world we'd remember the place #line changed the name and refer
to it when printing errors.
fix:
- "#if 0 && 1/0" should not crash; fix eval method.
- quote characters and comment delimiters that are emitted by
macros are not recognized. See:
t34 (should produce a quote and FOO Q)
t35 (similarly, this test may be redundant once it's fixed)
t36 (C(3) should produce nothing)
t37 (BC foo EC should produce nothing)
Joerg says comments like in t36 should be stripped exactly
twice, once when the macro is defined and again when it's
expanded. Note that gcc's cpp -traditional is getting t37
wrong, and it gets t36 wrong with -C.
- remove the intentionally undocumented -p option and generate
proper linenumber output. (also, in this code what happens if
a comment spans files? I bet currently it will emit the line
number into the comment.)

115
external/bsd/tradcpp/dist/array.c vendored Normal file
View File

@ -0,0 +1,115 @@
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David A. Holland.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <string.h>
#define ARRAYINLINE
#include "array.h"
struct array *
array_create(void)
{
struct array *a;
a = domalloc(sizeof(*a));
array_init(a);
return a;
}
void
array_destroy(struct array *a)
{
array_cleanup(a);
dofree(a, sizeof(*a));
}
void
array_init(struct array *a)
{
a->num = a->max = 0;
a->v = NULL;
}
void
array_cleanup(struct array *a)
{
arrayassert(a->num == 0);
dofree(a->v, a->max * sizeof(a->v[0]));
#ifdef ARRAYS_CHECKED
a->v = NULL;
#endif
}
void
array_setsize(struct array *a, unsigned num)
{
unsigned newmax;
void **newptr;
if (num > a->max) {
newmax = a->max;
while (num > newmax) {
newmax = newmax ? newmax*2 : 4;
}
newptr = dorealloc(a->v, a->max * sizeof(a->v[0]),
newmax * sizeof(a->v[0]));
a->v = newptr;
a->max = newmax;
}
a->num = num;
}
void
array_insert(struct array *a, unsigned index_)
{
unsigned movers;
arrayassert(a->num <= a->max);
arrayassert(index_ < a->num);
movers = a->num - index_;
array_setsize(a, a->num + 1);
memmove(a->v + index_+1, a->v + index_, movers*sizeof(*a->v));
}
void
array_remove(struct array *a, unsigned index_)
{
unsigned movers;
arrayassert(a->num <= a->max);
arrayassert(index_ < a->num);
movers = a->num - (index_ + 1);
memmove(a->v + index_, a->v + index_+1, movers*sizeof(*a->v));
a->num--;
}

279
external/bsd/tradcpp/dist/array.h vendored Normal file
View File

@ -0,0 +1,279 @@
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David A. Holland.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ARRAY_H
#define ARRAY_H
#include "inlinedefs.h" // XXX
#include "utils.h"
#define ARRAYS_CHECKED
#ifdef ARRAYS_CHECKED
#include <assert.h>
#define arrayassert assert
#else
#define arrayassert(x) ((void)(x))
#endif
#ifndef ARRAYINLINE
#define ARRAYINLINE C99INLINE
#endif
////////////////////////////////////////////////////////////
// type and base operations
struct array {
void **v;
unsigned num, max;
};
struct array *array_create(void);
void array_destroy(struct array *);
void array_init(struct array *);
void array_cleanup(struct array *);
ARRAYINLINE unsigned array_num(const struct array *);
ARRAYINLINE void *array_get(const struct array *, unsigned index_);
ARRAYINLINE void array_set(const struct array *, unsigned index_, void *val);
void array_setsize(struct array *, unsigned num);
ARRAYINLINE void array_add(struct array *, void *val, unsigned *index_ret);
void array_insert(struct array *a, unsigned index_);
void array_remove(struct array *a, unsigned index_);
////////////////////////////////////////////////////////////
// inlining for base operations
ARRAYINLINE unsigned
array_num(const struct array *a)
{
return a->num;
}
ARRAYINLINE void *
array_get(const struct array *a, unsigned index_)
{
arrayassert(index_ < a->num);
return a->v[index_];
}
ARRAYINLINE void
array_set(const struct array *a, unsigned index_, void *val)
{
arrayassert(index_ < a->num);
a->v[index_] = val;
}
ARRAYINLINE void
array_add(struct array *a, void *val, unsigned *index_ret)
{
unsigned index_ = a->num;
array_setsize(a, index_+1);
a->v[index_] = val;
if (index_ret != NULL) {
*index_ret = index_;
}
}
////////////////////////////////////////////////////////////
// bits for declaring and defining typed arrays
/*
* Usage:
*
* DECLARRAY_BYTYPE(foo, bar, INLINE) declares "struct foo", which is
* an array of pointers to "bar", plus the operations on it.
*
* DECLARRAY(foo, INLINE) is equivalent to
* DECLARRAY_BYTYPE(fooarray, struct foo, INLINE).
*
* DEFARRAY_BYTYPE and DEFARRAY are the same as DECLARRAY except that
* they define the operations.
*
* The argument INLINE can be used as follows:
*
* 1. For no inlining:
* In foo.h:
* DECLARRAY(foo, );
* In foo.c:
* DEFARRAY(foo, );
*
* 2. To be file-static:
* In foo.c:
* DECLARRAY(foo, static);
* DEFARRAY(foo, static);
*
* 3. To inline using C99:
* In foo.h:
* DECLARRAY(foo, inline);
* DEFARRAY(foo, inline);
*
* 4. To inline with old gcc:
* In foo.h:
* #ifndef FOO_INLINE
* #define FOO_INLINE extern inline
* #endif
* DECLARRAY(foo, );
* DEFARRAY(foo, FOO_INLINE);
* In foo.c:
* #define FOO_INLINE
* #include "foo.h"
*
* 5. To inline such that it works both with old gcc and C99:
* In foo.h:
* #ifndef FOO_INLINE
* #define FOO_INLINE extern inline
* #endif
* DECLARRAY(foo, FOO_INLINE);
* DEFARRAY(foo, FOO_INLINE);
* In foo.c:
* #define FOO_INLINE
* #include "foo.h"
*
* The mechanism in case (4) ensures that an externally linkable
* definition exists.
*/
#define DECLARRAY_BYTYPE(ARRAY, T, INLINE) \
struct ARRAY { \
struct array arr; \
}; \
\
INLINE struct ARRAY *ARRAY##_create(void); \
INLINE void ARRAY##_destroy(struct ARRAY *a); \
INLINE void ARRAY##_init(struct ARRAY *a); \
INLINE void ARRAY##_cleanup(struct ARRAY *a); \
INLINE unsigned ARRAY##_num(const struct ARRAY *a); \
INLINE T *ARRAY##_get(const struct ARRAY *a, unsigned index_); \
INLINE void ARRAY##_set(struct ARRAY *a, unsigned index_, T *val); \
INLINE void ARRAY##_setsize(struct ARRAY *a, unsigned num); \
INLINE void ARRAY##_add(struct ARRAY *a, T *val, unsigned *index_ret);\
INLINE void ARRAY##_insert(struct ARRAY *a, unsigned index_); \
INLINE void ARRAY##_remove(struct ARRAY *a, unsigned index_)
#define DEFARRAY_BYTYPE(ARRAY, T, INLINE) \
INLINE void \
ARRAY##_init(struct ARRAY *a) \
{ \
array_init(&a->arr); \
} \
\
INLINE void \
ARRAY##_cleanup(struct ARRAY *a) \
{ \
array_cleanup(&a->arr); \
} \
\
INLINE struct \
ARRAY *ARRAY##_create(void) \
{ \
struct ARRAY *a; \
\
a = domalloc(sizeof(*a)); \
ARRAY##_init(a); \
return a; \
} \
\
INLINE void \
ARRAY##_destroy(struct ARRAY *a) \
{ \
ARRAY##_cleanup(a); \
dofree(a, sizeof(*a)); \
} \
\
INLINE unsigned \
ARRAY##_num(const struct ARRAY *a) \
{ \
return array_num(&a->arr); \
} \
\
INLINE T * \
ARRAY##_get(const struct ARRAY *a, unsigned index_) \
{ \
return (T *)array_get(&a->arr, index_); \
} \
\
INLINE void \
ARRAY##_set(struct ARRAY *a, unsigned index_, T *val) \
{ \
array_set(&a->arr, index_, (void *)val); \
} \
\
INLINE void \
ARRAY##_setsize(struct ARRAY *a, unsigned num) \
{ \
array_setsize(&a->arr, num); \
} \
\
INLINE void \
ARRAY##_add(struct ARRAY *a, T *val, unsigned *ret) \
{ \
array_add(&a->arr, (void *)val, ret); \
} \
\
INLINE void \
ARRAY##_insert(struct ARRAY *a, unsigned index_) \
{ \
array_insert(&a->arr, index_); \
} \
\
INLINE void \
ARRAY##_remove(struct ARRAY *a, unsigned index_) \
{ \
array_remove(&a->arr, index_); \
}
#define DECLARRAY(T, INLINE) DECLARRAY_BYTYPE(T##array, struct T, INLINE)
#define DEFARRAY(T, INLINE) DEFARRAY_BYTYPE(T##array, struct T, INLINE)
#define DESTROYALL_ARRAY(T, INLINE) \
INLINE void T##array_destroyall(struct T##array *arr); \
\
INLINE void \
T##array_destroyall(struct T##array *arr) \
{ \
unsigned i, num; \
struct T *t; \
\
num = T##array_num(arr); \
for (i=0; i<num; i++) { \
t = T##array_get(arr, i); \
T##_destroy(t); \
} \
T##array_setsize(arr, 0); \
}
////////////////////////////////////////////////////////////
// basic array types
DECLARRAY_BYTYPE(stringarray, char, ARRAYINLINE);
DEFARRAY_BYTYPE(stringarray, char, ARRAYINLINE);
#endif /* ARRAY_H */

41
external/bsd/tradcpp/dist/bool.h vendored Normal file
View File

@ -0,0 +1,41 @@
/*-
* Copyright (c) 2015 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David A. Holland.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BOOL_H
#define BOOL_H
#if __STDC__ > 199901
#include <stdbool.h>
#else
typedef int bool;
#define true 1
#define false 0
#endif
#endif /* BOOL_H */

174
external/bsd/tradcpp/dist/config.h vendored Normal file
View File

@ -0,0 +1,174 @@
/*-
* Copyright (c) 2010, 2013 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David A. Holland.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Config for predefined macros. If this doesn't do what you want you
* can set any or all of the CONFIG_ defines from the compiler command
* line; or patch the list in main.c; or both.
*/
/*
* Paths
*/
#ifndef CONFIG_LOCALINCLUDE
#define CONFIG_LOCALINCLUDE "/usr/local/include"
#endif
#ifndef CONFIG_SYSTEMINCLUDE
#define CONFIG_SYSTEMINCLUDE "/usr/include"
#endif
/*
* Operating system
*/
#ifndef CONFIG_OS
#if defined(__NetBSD__)
#define CONFIG_OS "__NetBSD__"
#define CONFIG_OS_2 "__unix__"
#elif defined(__FreeBSD__)
#define CONFIG_OS "__FreeBSD__"
#define CONFIG_OS_2 "__unix__"
#elif defined(__OpenBSD__)
#define CONFIG_OS "__OpenBSD__"
#define CONFIG_OS_2 "__unix__"
#elif defined(__DragonFly__)
#define CONFIG_OS "__DragonFly__"
#define CONFIG_OS_2 "__unix__"
#elif defined(__bsdi__)
#define CONFIG_OS "__bsdi__"
#define CONFIG_OS_2 "__unix__"
#elif defined(__sun)
#define CONFIG_OS "__sun"
#define CONFIG_OS_2 "__unix__"
#elif defined(__sgi)
#define CONFIG_OS "__sgi"
#define CONFIG_OS_2 "__unix__"
#elif defined(__SVR4)
#define CONFIG_OS "__SVR4"
#define CONFIG_OS_2 "__unix__"
#elif defined(__APPLE__)
#define CONFIG_OS "__APPLE__"
#define CONFIG_OS_2 "__unix__"
#elif defined(__linux__)
#define CONFIG_OS "__linux__"
#elif defined(__CYGWIN__)
#define CONFIG_OS "__CYGWIN__"
#elif defined(__INTERIX)
#define CONFIG_OS "__INTERIX"
#elif defined(__MINGW32)
#define CONFIG_OS "__MINGW32"
#else
/* we could error... but let's instead assume generic unix */
#define CONFIG_OS "__unix__"
#endif
#endif
/*
* CPU
*/
#ifndef CONFIG_CPU
#if defined(__x86_64__)
#define CONFIG_CPU "__x86_64__"
#define CONFIG_CPU_2 "__amd64__"
#elif defined(__i386__) || defined(__i386)
#define CONFIG_CPU "__i386__"
#define CONFIG_CPU_2 "__i386"
#elif defined(__sparc)
#define CONFIG_CPU "__sparc"
#elif defined(__mips)
#define CONFIG_CPU "__mips"
#elif defined(__mips__)
#define CONFIG_CPU "__mips__"
#elif defined(__mipsel__)
#define CONFIG_CPU "__mipsel__"
#elif defined(__POWERPC__)
#define CONFIG_CPU "__POWERPC__"
#elif defined(__POWERPC__)
#define CONFIG_CPU "__powerpc__"
#elif defined(__PPC__)
#define CONFIG_CPU "__PPC__"
#elif defined(__ppc__)
#define CONFIG_CPU "__ppc__"
#elif defined(__PPC64__)
#define CONFIG_CPU "__PPC64__"
#elif defined(__ppc64__)
#define CONFIG_CPU "__ppc64__"
#elif defined(__ARM__)
#define CONFIG_CPU "__ARM__"
#elif defined(__AARCH64__)
#define CONFIG_CPU "__AARCH64__"
#elif defined(__aarch64__)
#define CONFIG_CPU "__aarch64__"
#elif defined(__RISCV__)
#define CONFIG_CPU "__RISCV__"
#elif defined(__riscv__)
#define CONFIG_CPU "__riscv__"
#elif defined(__RISCV64__)
#define CONFIG_CPU "__RISCV64__"
#elif defined(__riscv64__)
#define CONFIG_CPU "__riscv64__"
#elif defined(__riscv64)
#define CONFIG_CPU "__riscv64"
#elif defined(__ia64__)
#define CONFIG_CPU "__ia64__"
#else
/* let it go */
#endif
#endif
/*
* Other stuff
*/
#ifndef CONFIG_SIZE
#ifdef __LP64__
#define CONFIG_SIZE "__LP64__"
#else
#define CONFIG_SIZE "__ILP32__"
#endif
#endif
#ifndef CONFIG_BINFMT
#ifdef __ELF__
#define CONFIG_BINFMT "__ELF__"
#endif
#endif
/*
* We are __TRADCPP__ by default, but if you want to masquerade as
* some other compiler this is a convenient place to change it.
*/
#ifndef CONFIG_COMPILER
#define CONFIG_COMPILER "__TRADCPP__"
#define CONFIG_COMPILER_MINOR "__TRADCPP_MINOR__"
#endif

733
external/bsd/tradcpp/dist/directive.c vendored Normal file
View File

@ -0,0 +1,733 @@
/*-
* Copyright (c) 2010, 2013 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David A. Holland.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
#include "bool.h"
#include "utils.h"
#include "mode.h"
#include "place.h"
#include "files.h"
#include "directive.h"
#include "macro.h"
#include "eval.h"
#include "output.h"
struct ifstate {
struct ifstate *prev;
struct place startplace;
bool curtrue;
bool evertrue;
bool seenelse;
};
static struct ifstate *ifstate;
////////////////////////////////////////////////////////////
// common parsing bits
static
void
uncomment(char *buf)
{
char *s, *t, *u = NULL;
bool incomment = false;
bool inesc = false;
bool inquote = false;
char quote = '\0';
for (s = t = buf; *s; s++) {
if (incomment) {
if (s[0] == '*' && s[1] == '/') {
s++;
incomment = false;
}
} else {
if (!inquote && s[0] == '/' && s[1] == '*') {
incomment = true;
} else {
if (inesc) {
inesc = false;
} else if (s[0] == '\\') {
inesc = true;
} else if (!inquote &&
(s[0] == '"' || s[0] == '\'')) {
inquote = true;
quote = s[0];
} else if (inquote && s[0] == quote) {
inquote = false;
}
if (t != s) {
*t = *s;
}
if (!strchr(ws, *t)) {
u = t;
}
t++;
}
}
}
if (u) {
/* end string after last non-whitespace char */
u[1] = '\0';
} else {
*t = '\0';
}
}
static
void
oneword(const char *what, struct place *p2, char *line)
{
size_t pos;
pos = strcspn(line, ws);
if (line[pos] != '\0') {
place_addcolumns(p2, pos);
complain(p2, "Garbage after %s argument", what);
complain_fail();
line[pos] = '\0';
}
}
////////////////////////////////////////////////////////////
// if handling
static
struct ifstate *
ifstate_create(struct ifstate *prev, struct place *p, bool startstate)
{
struct ifstate *is;
is = domalloc(sizeof(*is));
is->prev = prev;
if (p != NULL) {
is->startplace = *p;
} else {
place_setbuiltin(&is->startplace, 1);
}
is->curtrue = startstate;
is->evertrue = is->curtrue;
is->seenelse = false;
return is;
}
static
void
ifstate_destroy(struct ifstate *is)
{
dofree(is, sizeof(*is));
}
static
void
ifstate_push(struct place *p, bool startstate)
{
struct ifstate *newstate;
newstate = ifstate_create(ifstate, p, startstate);
if (!ifstate->curtrue) {
newstate->curtrue = false;
newstate->evertrue = true;
}
ifstate = newstate;
}
static
void
ifstate_pop(void)
{
struct ifstate *is;
is = ifstate;
ifstate = ifstate->prev;
ifstate_destroy(is);
}
static
void
d_if(struct lineplace *lp, struct place *p2, char *line)
{
bool doprint;
char *expr;
bool val;
struct place p3 = *p2;
size_t oldlen;
doprint = ifstate->curtrue;
expr = macroexpand(p2, line, strlen(line), true);
oldlen = strlen(expr);
uncomment(expr);
/* trim to fit, so the malloc debugging won't complain */
expr = dorealloc(expr, oldlen + 1, strlen(expr) + 1);
if (ifstate->curtrue) {
val = eval(&p3, expr);
} else {
val = 0;
}
ifstate_push(&lp->current, val);
dostrfree(expr);
if (doprint) {
debuglog(&lp->current, "#if: %s",
ifstate->curtrue ? "taken" : "not taken");
}
}
static
void
d_ifdef(struct lineplace *lp, struct place *p2, char *line)
{
bool doprint;
doprint = ifstate->curtrue;
uncomment(line);
oneword("#ifdef", p2, line);
ifstate_push(&lp->current, macro_isdefined(line));
if (doprint) {
debuglog(&lp->current, "#ifdef %s: %s",
line, ifstate->curtrue ? "taken" : "not taken");
}
}
static
void
d_ifndef(struct lineplace *lp, struct place *p2, char *line)
{
bool doprint;
doprint = ifstate->curtrue;
uncomment(line);
oneword("#ifndef", p2, line);
ifstate_push(&lp->current, !macro_isdefined(line));
if (doprint) {
debuglog(&lp->current, "#ifndef %s: %s",
line, ifstate->curtrue ? "taken" : "not taken");
}
}
static
void
d_elif(struct lineplace *lp, struct place *p2, char *line)
{
bool doprint;
char *expr;
struct place p3 = *p2;
size_t oldlen;
if (ifstate->seenelse) {
complain(&lp->current, "#elif after #else");
complain_fail();
}
doprint = ifstate->curtrue;
if (ifstate->evertrue) {
ifstate->curtrue = false;
} else {
expr = macroexpand(p2, line, strlen(line), true);
oldlen = strlen(expr);
uncomment(expr);
/* trim to fit, so the malloc debugging won't complain */
expr = dorealloc(expr, oldlen + 1, strlen(expr) + 1);
ifstate->curtrue = eval(&p3, expr);
ifstate->evertrue = ifstate->curtrue;
dostrfree(expr);
}
if (doprint) {
debuglog2(&lp->current, &ifstate->startplace, "#elif: %s",
ifstate->curtrue ? "taken" : "not taken");
}
}
static
void
d_else(struct lineplace *lp, struct place *p2, char *line)
{
bool doprint;
(void)p2;
(void)line;
if (ifstate->seenelse) {
complain(&lp->current,
"Multiple #else directives in one conditional");
complain_fail();
}
doprint = ifstate->curtrue;
ifstate->curtrue = !ifstate->evertrue;
ifstate->evertrue = true;
ifstate->seenelse = true;
if (doprint) {
debuglog2(&lp->current, &ifstate->startplace, "#else: %s",
ifstate->curtrue ? "taken" : "not taken");
}
}
static
void
d_endif(struct lineplace *lp, struct place *p2, char *line)
{
(void)p2;
(void)line;
if (ifstate->prev == NULL) {
complain(&lp->current, "Unmatched #endif");
complain_fail();
} else {
debuglog2(&lp->current, &ifstate->startplace, "#endif");
ifstate_pop();
}
}
////////////////////////////////////////////////////////////
// macros
static
void
d_define(struct lineplace *lp, struct place *p2, char *line)
{
size_t pos, argpos;
struct place p3, p4;
(void)lp;
/*
* line may be:
* macro expansion
* macro(arg, arg, ...) expansion
*/
pos = strcspn(line, " \t\f\v(");
if (line[pos] == '(') {
line[pos++] = '\0';
argpos = pos;
pos = pos + strcspn(line+pos, "()");
if (line[pos] == '(') {
place_addcolumns(p2, pos);
complain(p2, "Left parenthesis in macro parameters");
complain_fail();
return;
}
if (line[pos] != ')') {
place_addcolumns(p2, pos);
complain(p2, "Unclosed macro parameter list");
complain_fail();
return;
}
line[pos++] = '\0';
#if 0
if (!strchr(ws, line[pos])) {
p2->column += pos;
complain(p2, "Trash after macro parameter list");
complain_fail();
return;
}
#endif
} else if (line[pos] == '\0') {
argpos = 0;
} else {
line[pos++] = '\0';
argpos = 0;
}
pos += strspn(line+pos, ws);
p3 = *p2;
place_addcolumns(&p3, argpos);
p4 = *p2;
place_addcolumns(&p4, pos);
if (argpos) {
debuglog(&lp->current, "Defining %s()", line);
macro_define_params(p2, line, &p3,
line + argpos, &p4,
line + pos);
} else {
debuglog(&lp->current, "Defining %s", line);
macro_define_plain(p2, line, &p4, line + pos);
}
}
static
void
d_undef(struct lineplace *lp, struct place *p2, char *line)
{
(void)lp;
uncomment(line);
oneword("#undef", p2, line);
debuglog(&lp->current, "Undef %s", line);
macro_undef(line);
}
////////////////////////////////////////////////////////////
// includes
static
bool
tryinclude(struct place *p, char *line)
{
size_t len;
len = strlen(line);
if (len > 2 && line[0] == '"' && line[len-1] == '"') {
line[len-1] = '\0';
debuglog(p, "Entering include file \"%s\"", line+1);
file_readquote(p, line+1);
debuglog(p, "Leaving include file \"%s\"", line+1);
line[len-1] = '"';
return true;
}
if (len > 2 && line[0] == '<' && line[len-1] == '>') {
line[len-1] = '\0';
debuglog(p, "Entering include file <%s>", line+1);
file_readbracket(p, line+1);
debuglog(p, "Leaving include file <%s>", line+1);
line[len-1] = '>';
return true;
}
return false;
}
static
void
d_include(struct lineplace *lp, struct place *p2, char *line)
{
char *text;
size_t oldlen;
uncomment(line);
if (tryinclude(&lp->current, line)) {
return;
}
text = macroexpand(p2, line, strlen(line), false);
oldlen = strlen(text);
uncomment(text);
/* trim to fit, so the malloc debugging won't complain */
text = dorealloc(text, oldlen + 1, strlen(text) + 1);
if (tryinclude(&lp->current, text)) {
dostrfree(text);
return;
}
complain(&lp->current, "Illegal #include directive");
complain(&lp->current, "Before macro expansion: #include %s", line);
complain(&lp->current, "After macro expansion: #include %s", text);
dostrfree(text);
complain_fail();
}
static
void
d_line(struct lineplace *lp, struct place *p2, char *line)
{
char *text;
size_t oldlen;
unsigned long val;
char *moretext;
size_t moretextlen;
char *filename;
text = macroexpand(p2, line, strlen(line), true);
oldlen = strlen(text);
uncomment(text);
/* trim to fit, so the malloc debugging won't complain */
text = dorealloc(text, oldlen + 1, strlen(text) + 1);
/*
* What we should have here: either 1234 "file.c",
* or just 1234.
*/
errno = 0;
val = strtoul(text, &moretext, 10);
if (errno) {
complain(&lp->current,
"Invalid line number in #line directive");
goto fail;
}
#if UINT_MAX < ULONG_MAX
if (val > UINT_MAX) {
complain(&lp->current,
"Line number in #line directive too large");
goto fail;
}
#endif
moretext += strspn(moretext, ws);
moretextlen = strlen(moretext);
place_addcolumns(&lp->current, moretext - text);
if (moretextlen > 2 &&
moretext[0] == '"' && moretext[moretextlen-1] == '"') {
filename = dostrndup(moretext+1, moretextlen-2);
place_changefile(&lp->nextline, filename);
dostrfree(filename);
}
else if (moretextlen > 0) {
complain(&lp->current,
"Invalid file name in #line directive");
goto fail;
}
lp->nextline.line = val;
dostrfree(text);
return;
fail:
complain(&lp->current, "Before macro expansion: #line %s", line);
complain(&lp->current, "After macro expansion: #line %s", text);
complain_fail();
dostrfree(text);
}
////////////////////////////////////////////////////////////
// messages
static
void
d_warning(struct lineplace *lp, struct place *p2, char *line)
{
char *msg;
msg = macroexpand(p2, line, strlen(line), false);
complain(&lp->current, "#warning: %s", msg);
if (mode.werror) {
complain_fail();
}
dostrfree(msg);
}
static
void
d_error(struct lineplace *lp, struct place *p2, char *line)
{
char *msg;
msg = macroexpand(p2, line, strlen(line), false);
complain(&lp->current, "#error: %s", msg);
complain_fail();
dostrfree(msg);
}
////////////////////////////////////////////////////////////
// other
static
void
d_pragma(struct lineplace *lp, struct place *p2, char *line)
{
(void)p2;
complain(&lp->current, "#pragma %s", line);
complain_fail();
}
////////////////////////////////////////////////////////////
// directive table
static const struct {
const char *name;
bool ifskip;
void (*func)(struct lineplace *, struct place *, char *line);
} directives[] = {
{ "define", true, d_define },
{ "elif", false, d_elif },
{ "else", false, d_else },
{ "endif", false, d_endif },
{ "error", true, d_error },
{ "if", false, d_if },
{ "ifdef", false, d_ifdef },
{ "ifndef", false, d_ifndef },
{ "include", true, d_include },
{ "line", true, d_line },
{ "pragma", true, d_pragma },
{ "undef", true, d_undef },
{ "warning", true, d_warning },
};
static const unsigned numdirectives = HOWMANY(directives);
static
void
directive_gotdirective(struct lineplace *lp, char *line)
{
struct place p2;
size_t len, skip;
unsigned i;
p2 = lp->current;
for (i=0; i<numdirectives; i++) {
len = strlen(directives[i].name);
if (!strncmp(line, directives[i].name, len) &&
strchr(ws, line[len])) {
if (directives[i].ifskip && !ifstate->curtrue) {
return;
}
skip = len + strspn(line+len, ws);
place_addcolumns(&p2, skip);
line += skip;
len = strlen(line);
len = notrailingws(line, len);
if (len < strlen(line)) {
line[len] = '\0';
}
directives[i].func(lp, &p2, line);
return;
}
}
/* ugh. allow # by itself, including with a comment after it */
uncomment(line);
if (line[0] == '\0') {
return;
}
skip = strcspn(line, ws);
complain(&lp->current, "Unknown directive #%.*s", (int)skip, line);
complain_fail();
}
/*
* Check for nested comment delimiters in LINE.
*/
static
size_t
directive_scancomments(const struct lineplace *lp, char *line, size_t len)
{
size_t pos;
bool incomment;
struct place p2;
p2 = lp->current;
incomment = 0;
for (pos = 0; pos+1 < len; pos++) {
if (line[pos] == '/' && line[pos+1] == '*') {
if (incomment) {
complain(&p2, "Warning: %c%c within comment",
'/', '*');
if (mode.werror) {
complain_failed();
}
} else {
incomment = true;
}
pos++;
} else if (line[pos] == '*' && line[pos+1] == '/') {
if (incomment) {
incomment = false;
} else {
/* stray end-comment; should we care? */
}
pos++;
}
if (line[pos] == '\n') {
place_addlines(&p2, 1);
p2.column = 0;
} else {
place_addcolumns(&p2, 1);
}
}
/* multiline comments are supposed to arrive in a single buffer */
assert(!incomment);
return len;
}
void
directive_gotline(struct lineplace *lp, char *line, size_t len)
{
size_t skip;
if (warns.nestcomment) {
directive_scancomments(lp, line, len);
}
/* check if we have a directive line (# exactly in column 0) */
if (len > 0 && line[0] == '#') {
skip = 1 + strspn(line + 1, ws);
assert(skip <= len);
place_addcolumns(&lp->current, skip);
assert(line[len] == '\0');
directive_gotdirective(lp, line+skip /*, length = len-skip */);
place_addcolumns(&lp->current, len-skip);
} else if (ifstate->curtrue) {
macro_sendline(&lp->current, line, len);
place_addcolumns(&lp->current, len);
}
}
void
directive_goteof(struct place *p)
{
while (ifstate->prev != NULL) {
complain(p, "Missing #endif");
complain(&ifstate->startplace, "...opened at this point");
complain_failed();
ifstate_pop();
}
macro_sendeof(p);
}
////////////////////////////////////////////////////////////
// module initialization
void
directive_init(void)
{
ifstate = ifstate_create(NULL, NULL, true);
}
void
directive_cleanup(void)
{
assert(ifstate->prev == NULL);
ifstate_destroy(ifstate);
ifstate = NULL;
}

49
external/bsd/tradcpp/dist/directive.h vendored Normal file
View File

@ -0,0 +1,49 @@
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David A. Holland.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <stddef.h>
#include "place.h"
/*
* Relevant places while we're processing a line:
* the place in the current line
* the beginning of the next line
*/
struct lineplace {
struct place current;
struct place nextline;
};
void directive_init(void);
void directive_cleanup(void);
void directive_gotline(struct lineplace *lp, char *line, size_t len);
void directive_goteof(struct place *p);

767
external/bsd/tradcpp/dist/eval.c vendored Normal file
View File

@ -0,0 +1,767 @@
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David A. Holland.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
//#define DEBUG
#ifdef DEBUG
#include <stdio.h>
#endif
#include "utils.h"
#include "array.h"
#include "mode.h"
#include "place.h"
#include "eval.h"
/*
* e ::=
* e1 ? e2 : e3
* e1 || e2
* e1 && e2
* e1 | e2
* e1 ^ e2
* e1 & e2
* e1 == e2 | e1 != e2
* e1 < e2 | e1 <= e2 | e1 > e2 | e1 >= e2
* e1 << e2 | e1 >> e2
* e1 + e2 | e1 - e2
* e1 * e2 | e1 / e2 | e1 % e2
* !e | ~e | -e | +e
* ( e ) | ident
*/
enum tokens {
T_EOF, /* end of input */
T_VAL, /* value */
T_LPAREN, /* parens */
T_RPAREN,
T_PIPEPIPE, /* operators */
T_AMPAMP,
T_EQEQ,
T_BANGEQ,
T_LTEQ,
T_GTEQ,
T_LTLT,
T_GTGT,
T_QUES,
T_COLON,
T_PIPE,
T_CARET,
T_AMP,
T_LT,
T_GT,
T_PLUS,
T_MINUS,
T_STAR,
T_SLASH,
T_PCT,
T_BANG,
T_TILDE,
};
static const struct {
char c1, c2;
enum tokens tok;
} tokens_2[] = {
{ '|', '|', T_PIPEPIPE },
{ '&', '&', T_AMPAMP },
{ '=', '=', T_EQEQ },
{ '!', '=', T_BANGEQ },
{ '<', '=', T_LTEQ },
{ '>', '=', T_GTEQ },
{ '<', '<', T_LTLT },
{ '>', '>', T_GTGT },
};
static const unsigned num_tokens_2 = HOWMANY(tokens_2);
static const struct {
char c1;
enum tokens tok;
} tokens_1[] = {
{ '?', T_QUES },
{ ':', T_COLON },
{ '|', T_PIPE },
{ '^', T_CARET },
{ '&', T_AMP },
{ '<', T_LT },
{ '>', T_GT },
{ '+', T_PLUS },
{ '-', T_MINUS },
{ '*', T_STAR },
{ '/', T_SLASH },
{ '%', T_PCT },
{ '!', T_BANG },
{ '~', T_TILDE },
{ '(', T_LPAREN },
{ ')', T_RPAREN },
};
static const unsigned num_tokens_1 = HOWMANY(tokens_1);
struct token {
struct place place;
enum tokens tok;
int val;
};
DECLARRAY(token, static UNUSED);
DEFARRAY(token, static);
static struct tokenarray tokens;
static
struct token *
token_create(const struct place *p, enum tokens tok, int val)
{
struct token *t;
t = domalloc(sizeof(*t));
t->place = *p;
t->tok = tok;
t->val = val;
return t;
}
static
void
token_destroy(struct token *t)
{
dofree(t, sizeof(*t));
}
DESTROYALL_ARRAY(token, );
#ifdef DEBUG
static
void
printtokens(void)
{
unsigned i, num;
struct token *t;
fprintf(stderr, "tokens:");
num = tokenarray_num(&tokens);
for (i=0; i<num; i++) {
t = tokenarray_get(&tokens, i);
switch (t->tok) {
case T_EOF: fprintf(stderr, " <eof>"); break;
case T_VAL: fprintf(stderr, " %d", t->val); break;
case T_LPAREN: fprintf(stderr, " ("); break;
case T_RPAREN: fprintf(stderr, " )"); break;
case T_PIPEPIPE: fprintf(stderr, " ||"); break;
case T_AMPAMP: fprintf(stderr, " &&"); break;
case T_EQEQ: fprintf(stderr, " =="); break;
case T_BANGEQ: fprintf(stderr, " !="); break;
case T_LTEQ: fprintf(stderr, " <="); break;
case T_GTEQ: fprintf(stderr, " >="); break;
case T_LTLT: fprintf(stderr, " <<"); break;
case T_GTGT: fprintf(stderr, " >>"); break;
case T_QUES: fprintf(stderr, " ?"); break;
case T_COLON: fprintf(stderr, " :"); break;
case T_PIPE: fprintf(stderr, " |"); break;
case T_CARET: fprintf(stderr, " ^"); break;
case T_AMP: fprintf(stderr, " &"); break;
case T_LT: fprintf(stderr, " <"); break;
case T_GT: fprintf(stderr, " >"); break;
case T_PLUS: fprintf(stderr, " +"); break;
case T_MINUS: fprintf(stderr, " -"); break;
case T_STAR: fprintf(stderr, " *"); break;
case T_SLASH: fprintf(stderr, " /"); break;
case T_PCT: fprintf(stderr, " %%"); break;
case T_BANG: fprintf(stderr, " !"); break;
case T_TILDE: fprintf(stderr, " ~"); break;
}
}
fprintf(stderr, "\n");
}
#endif
static
bool
isuop(enum tokens tok)
{
switch (tok) {
case T_BANG:
case T_TILDE:
case T_MINUS:
case T_PLUS:
return true;
default:
break;
}
return false;
}
static
bool
isbop(enum tokens tok)
{
switch (tok) {
case T_EOF:
case T_VAL:
case T_LPAREN:
case T_RPAREN:
case T_COLON:
case T_QUES:
case T_BANG:
case T_TILDE:
return false;
default:
break;
}
return true;
}
static
bool
isop(enum tokens tok)
{
switch (tok) {
case T_EOF:
case T_VAL:
case T_LPAREN:
case T_RPAREN:
return false;
default:
break;
}
return true;
}
static
int
getprec(enum tokens tok)
{
switch (tok) {
case T_BANG: case T_TILDE: return -1;
case T_STAR: case T_SLASH: case T_PCT: return 0;
case T_PLUS: case T_MINUS: return 1;
case T_LTLT: case T_GTGT: return 2;
case T_LT: case T_LTEQ: case T_GT: case T_GTEQ: return 3;
case T_EQEQ: case T_BANGEQ: return 4;
case T_AMP: return 5;
case T_CARET: return 6;
case T_PIPE: return 7;
case T_AMPAMP: return 8;
case T_PIPEPIPE: return 9;
default: break;
}
return 10;
}
static
bool
looser(enum tokens t1, enum tokens t2)
{
return getprec(t1) >= getprec(t2);
}
static
int
eval_uop(enum tokens op, int val)
{
switch (op) {
case T_BANG: val = !val; break;
case T_TILDE: val = (int)~(unsigned)val; break;
case T_MINUS: val = -val; break;
case T_PLUS: break;
default: assert(0); break;
}
return val;
}
static
int
eval_bop(struct place *p, int lv, enum tokens op, int rv)
{
unsigned mask;
switch (op) {
case T_PIPEPIPE: return lv || rv;
case T_AMPAMP: return lv && rv;
case T_PIPE: return (int)((unsigned)lv | (unsigned)rv);
case T_CARET: return (int)((unsigned)lv ^ (unsigned)rv);
case T_AMP: return (int)((unsigned)lv & (unsigned)rv);
case T_EQEQ: return lv == rv;
case T_BANGEQ: return lv != rv;
case T_LT: return lv < rv;
case T_GT: return lv > rv;
case T_LTEQ: return lv <= rv;
case T_GTEQ: return lv >= rv;
case T_LTLT:
case T_GTGT:
if (rv < 0) {
complain(p, "Negative bit-shift");
complain_fail();
rv = 0;
}
if ((unsigned)rv >= CHAR_BIT * sizeof(unsigned)) {
complain(p, "Bit-shift farther than type width");
complain_fail();
rv = 0;
}
if (op == T_LTLT) {
return (int)((unsigned)lv << (unsigned)rv);
}
mask = ((unsigned)-1) << (CHAR_BIT * sizeof(unsigned) - rv);
lv = (int)(((unsigned)lv >> (unsigned)rv) | mask);
return lv;
case T_MINUS:
if (rv == INT_MIN) {
if (lv == INT_MIN) {
return 0;
}
lv--;
rv++;
}
rv = -rv;
/* FALLTHROUGH */
case T_PLUS:
if (rv > 0 && lv > (INT_MAX - rv)) {
complain(p, "Integer overflow");
complain_fail();
return INT_MAX;
}
if (rv < 0 && lv < (INT_MIN - rv)) {
complain(p, "Integer underflow");
complain_fail();
return INT_MIN;
}
return lv + rv;
case T_STAR:
if (rv == 0) {
return 0;
}
if (rv == 1) {
return lv;
}
if (rv == -1 && lv == INT_MIN) {
lv++;
lv = -lv;
if (lv == INT_MAX) {
complain(p, "Integer overflow");
complain_fail();
return INT_MAX;
}
lv++;
return lv;
}
if (lv == INT_MIN && rv < 0) {
complain(p, "Integer overflow");
complain_fail();
return INT_MAX;
}
if (lv == INT_MIN && rv > 0) {
complain(p, "Integer underflow");
complain_fail();
return INT_MIN;
}
if (rv < 0) {
rv = -rv;
lv = -lv;
}
if (lv > 0 && lv > INT_MAX / rv) {
complain(p, "Integer overflow");
complain_fail();
return INT_MAX;
}
if (lv < 0 && lv < INT_MIN / rv) {
complain(p, "Integer underflow");
complain_fail();
return INT_MIN;
}
return lv * rv;
case T_SLASH:
if (rv == 0) {
complain(p, "Division by zero");
complain_fail();
return 0;
}
return lv / rv;
case T_PCT:
if (rv == 0) {
complain(p, "Modulus by zero");
complain_fail();
return 0;
}
return lv % rv;
default: assert(0); break;
}
return 0;
}
static
void
tryreduce(void)
{
unsigned num;
struct token *t1, *t2, *t3, *t4, *t5, *t6;
while (1) {
#ifdef DEBUG
printtokens();
#endif
num = tokenarray_num(&tokens);
t1 = (num >= 1) ? tokenarray_get(&tokens, num-1) : NULL;
t2 = (num >= 2) ? tokenarray_get(&tokens, num-2) : NULL;
t3 = (num >= 3) ? tokenarray_get(&tokens, num-3) : NULL;
if (num >= 3 &&
t3->tok == T_LPAREN &&
t2->tok == T_VAL &&
t1->tok == T_RPAREN) {
/* (x) -> x */
t2->place = t3->place;
token_destroy(t1);
token_destroy(t3);
tokenarray_remove(&tokens, num-1);
tokenarray_remove(&tokens, num-3);
continue;
}
if (num >= 2 &&
(num == 2 || isop(t3->tok) || t3->tok == T_LPAREN) &&
isuop(t2->tok) &&
t1->tok == T_VAL) {
/* unary operator */
t1->val = eval_uop(t2->tok, t1->val);
t1->place = t2->place;
token_destroy(t2);
tokenarray_remove(&tokens, num-2);
continue;
}
if (num >= 2 &&
(num == 2 || isop(t3->tok) || t3->tok == T_LPAREN) &&
t2->tok != T_LPAREN && t2->tok != T_VAL &&
t1->tok == T_VAL) {
complain(&t2->place, "Invalid unary operator");
complain_fail();
token_destroy(t2);
tokenarray_remove(&tokens, num-2);
continue;
}
t4 = (num >= 4) ? tokenarray_get(&tokens, num-4) : NULL;
if (num >= 4 &&
t4->tok == T_VAL &&
isbop(t3->tok) &&
t2->tok == T_VAL) {
/* binary operator */
if (looser(t1->tok, t3->tok)) {
t4->val = eval_bop(&t3->place,
t4->val, t3->tok, t2->val);
token_destroy(t2);
token_destroy(t3);
tokenarray_remove(&tokens, num-2);
tokenarray_remove(&tokens, num-3);
continue;
}
break;
}
t5 = (num >= 5) ? tokenarray_get(&tokens, num-5) : NULL;
t6 = (num >= 6) ? tokenarray_get(&tokens, num-6) : NULL;
if (num >= 6 &&
t6->tok == T_VAL &&
t5->tok == T_QUES &&
t4->tok == T_VAL &&
t3->tok == T_COLON &&
t2->tok == T_VAL &&
!isop(t1->tok)) {
/* conditional expression */
t6->val = t6->val ? t4->val : t2->val;
token_destroy(t2);
token_destroy(t3);
token_destroy(t4);
token_destroy(t5);
tokenarray_remove(&tokens, num-2);
tokenarray_remove(&tokens, num-3);
tokenarray_remove(&tokens, num-4);
tokenarray_remove(&tokens, num-5);
continue;
}
if (num >= 2 &&
t2->tok == T_LPAREN &&
t1->tok == T_RPAREN) {
complain(&t1->place, "Value expected within ()");
complain_fail();
t1->tok = T_VAL;
t1->val = 0;
token_destroy(t1);
tokenarray_remove(&tokens, num-1);
continue;
}
if (num >= 2 &&
t2->tok == T_VAL &&
t1->tok == T_VAL) {
complain(&t1->place, "Operator expected");
complain_fail();
token_destroy(t1);
tokenarray_remove(&tokens, num-1);
continue;
}
if (num >= 2 &&
isop(t2->tok) &&
t1->tok == T_EOF) {
complain(&t1->place, "Value expected after operator");
complain_fail();
token_destroy(t2);
tokenarray_remove(&tokens, num-2);
continue;
}
if (num == 2 &&
t2->tok == T_VAL &&
t1->tok == T_RPAREN) {
complain(&t1->place, "Excess right parenthesis");
complain_fail();
token_destroy(t1);
tokenarray_remove(&tokens, num-1);
continue;
}
if (num == 3 &&
t3->tok == T_LPAREN &&
t2->tok == T_VAL &&
t1->tok == T_EOF) {
complain(&t1->place, "Unclosed left parenthesis");
complain_fail();
token_destroy(t3);
tokenarray_remove(&tokens, num-3);
continue;
}
if (num == 2 &&
t2->tok == T_VAL &&
t1->tok == T_EOF) {
/* accepting state */
break;
}
if (num >= 1 &&
t1->tok == T_EOF) {
/* any other configuration at eof is an error */
complain(&t1->place, "Parse error");
complain_fail();
break;
}
/* otherwise, wait for more input */
break;
}
}
static
void
token(struct place *p, enum tokens tok, int val)
{
struct token *t;
t = token_create(p, tok, val);
tokenarray_add(&tokens, t, NULL);
tryreduce();
}
static
int
wordval(struct place *p, char *word)
{
unsigned long val;
char *t;
if (word[0] >= '0' && word[0] <= '9') {
errno = 0;
val = strtoul(word, &t, 0);
if (errno) {
complain(p, "Invalid integer constant");
complain_fail();
return 0;
}
while (*t == 'U' || *t == 'L') {
t++;
}
if (*t != '\0') {
complain(p, "Trailing garbage after integer constant");
complain_fail();
return 0;
}
if (val > INT_MAX) {
complain(p, "Integer constant too large");
complain_fail();
return INT_MAX;
}
return val;
}
/* if it's a symbol, warn and substitute 0. */
if (warns.undef) {
complain(p, "Warning: value of undefined symbol %s is 0",
word);
if (mode.werror) {
complain_fail();
}
}
debuglog(p, "Undefined symbol %s; substituting 0", word);
return 0;
}
static
bool
check_word(struct place *p, char *expr, size_t pos, size_t *len_ret)
{
size_t len;
int val;
char tmp;
if (!strchr(alnum, expr[pos])) {
return false;
}
len = strspn(expr + pos, alnum);
tmp = expr[pos + len];
expr[pos + len] = '\0';
val = wordval(p, expr + pos);
expr[pos + len] = tmp;
token(p, T_VAL, val);
*len_ret = len;
return true;
}
static
bool
check_tokens_2(struct place *p, char *expr, size_t pos)
{
unsigned i;
for (i=0; i<num_tokens_2; i++) {
if (expr[pos] == tokens_2[i].c1 &&
expr[pos+1] == tokens_2[i].c2) {
token(p, tokens_2[i].tok, 0);
return true;
}
}
return false;
}
static
bool
check_tokens_1(struct place *p, char *expr, size_t pos)
{
unsigned i;
for (i=0; i<num_tokens_1; i++) {
if (expr[pos] == tokens_1[i].c1) {
token(p, tokens_1[i].tok, 0);
return true;
}
}
return false;
}
static
void
tokenize(struct place *p, char *expr)
{
size_t pos, len;
pos = 0;
while (expr[pos] != '\0') {
len = strspn(expr+pos, ws);
pos += len;
place_addcolumns(p, len);
/* trailing whitespace is supposed to have been pruned */
assert(expr[pos] != '\0');
if (check_word(p, expr, pos, &len)) {
pos += len;
place_addcolumns(p, len);
continue;
}
if (check_tokens_2(p, expr, pos)) {
pos += 2;
place_addcolumns(p, 2);
continue;
}
if (check_tokens_1(p, expr, pos)) {
pos++;
place_addcolumns(p, 1);
continue;
}
complain(p, "Invalid character %u in #if-expression",
(unsigned char)expr[pos]);
complain_fail();
pos++;
place_addcolumns(p, 1);
}
token(p, T_EOF, 0);
}
bool
eval(struct place *p, char *expr)
{
struct token *t1, *t2;
unsigned num;
bool result;
#ifdef DEBUG
fprintf(stderr, "eval: %s\n", expr);
#endif
debuglog(p, "eval: %s", expr);
tokenarray_init(&tokens);
tokenize(p, expr);
result = false;
num = tokenarray_num(&tokens);
if (num == 2) {
t1 = tokenarray_get(&tokens, num-1);
t2 = tokenarray_get(&tokens, num-2);
if (t2->tok == T_VAL &&
t1->tok == T_EOF) {
result = t2->val != 0;
}
}
tokenarray_destroyall(&tokens);
tokenarray_cleanup(&tokens);
return result;
}

32
external/bsd/tradcpp/dist/eval.h vendored Normal file
View File

@ -0,0 +1,32 @@
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David A. Holland.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "bool.h"
bool eval(struct place *p, char *expr);

441
external/bsd/tradcpp/dist/files.c vendored Normal file
View File

@ -0,0 +1,441 @@
/*-
* Copyright (c) 2010, 2013 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David A. Holland.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include "bool.h"
#include "array.h"
#include "mode.h"
#include "place.h"
#include "files.h"
#include "directive.h"
struct incdir {
const char *name;
bool issystem;
};
DECLARRAY(incdir, static UNUSED);
DEFARRAY(incdir, static);
static struct incdirarray quotepath, bracketpath;
////////////////////////////////////////////////////////////
// management
static
struct incdir *
incdir_create(const char *name, bool issystem)
{
struct incdir *id;
id = domalloc(sizeof(*id));
id->name = name;
id->issystem = issystem;
return id;
}
static
void
incdir_destroy(struct incdir *id)
{
dofree(id, sizeof(*id));
}
void
files_init(void)
{
incdirarray_init(&quotepath);
incdirarray_init(&bracketpath);
}
DESTROYALL_ARRAY(incdir, );
void
files_cleanup(void)
{
incdirarray_destroyall(&quotepath);
incdirarray_cleanup(&quotepath);
incdirarray_destroyall(&bracketpath);
incdirarray_cleanup(&bracketpath);
}
////////////////////////////////////////////////////////////
// path setup
void
files_addquotepath(const char *dir, bool issystem)
{
struct incdir *id;
id = incdir_create(dir, issystem);
incdirarray_add(&quotepath, id, NULL);
}
void
files_addbracketpath(const char *dir, bool issystem)
{
struct incdir *id;
id = incdir_create(dir, issystem);
incdirarray_add(&bracketpath, id, NULL);
}
////////////////////////////////////////////////////////////
// parsing
/*
* Find the end of the logical line. End of line characters that are
* commented out do not count.
*/
static
size_t
findeol(const char *buf, size_t start, size_t limit)
{
size_t i;
int incomment = 0;
bool inquote = false;
char quote = '\0';
for (i=start; i<limit; i++) {
if (incomment) {
if (i+1 < limit && buf[i] == '*' && buf[i+1] == '/') {
i++;
incomment = 0;
}
} else if (!inquote && i+1 < limit &&
buf[i] == '/' && buf[i+1] == '*') {
i++;
incomment = 1;
} else if (i+1 < limit &&
buf[i] == '\\' && buf[i+1] != '\n') {
i++;
} else if (!inquote && (buf[i] == '"' || buf[i] == '\'')) {
inquote = true;
quote = buf[i];
} else if (inquote && buf[i] == quote) {
inquote = false;
} else if (buf[i] == '\n') {
return i;
}
}
return limit;
}
static
unsigned
countnls(const char *buf, size_t start, size_t limit)
{
size_t i;
unsigned count = 0;
for (i=start; i<limit; i++) {
if (buf[i] == '\n') {
count++;
if (count == 0) {
/* just return the max and error downstream */
return count - 1;
}
}
}
return count;
}
static
void
file_read(const struct placefile *pf, int fd, const char *name, bool toplevel)
{
struct lineplace places;
struct place ptmp;
size_t bufend, bufmax, linestart, lineend, nextlinestart, tmp;
ssize_t result;
bool ateof = false;
char *buf;
place_setfilestart(&places.current, pf);
places.nextline = places.current;
if (name) {
debuglog(&places.current, "Reading file %s", name);
} else {
debuglog(&places.current, "Reading standard input");
}
bufmax = 128;
bufend = 0;
linestart = 0;
lineend = 0;
buf = domalloc(bufmax);
while (1) {
if (lineend >= bufend) {
/* do not have a whole line in the buffer; read more */
assert(bufend >= linestart);
if (linestart > 0 && bufend > linestart) {
/* slide to beginning of buffer */
memmove(buf, buf+linestart, bufend-linestart);
bufend -= linestart;
lineend -= linestart;
linestart = 0;
}
if (bufend >= bufmax) {
/* need bigger buffer */
buf = dorealloc(buf, bufmax, bufmax*2);
bufmax = bufmax*2;
/* just in case someone's screwing around */
if (bufmax > 0xffffffff) {
complain(&places.current,
"Input line too long");
die();
}
}
if (ateof) {
/* don't read again, in case it's a socket */
result = 0;
} else {
result = read(fd, buf+bufend, bufmax - bufend);
}
if (result == -1) {
/* read error */
complain(NULL, "%s: %s",
name, strerror(errno));
complain_fail();
} else if (result == 0 && bufend == linestart) {
/* eof */
ateof = true;
break;
} else if (result == 0) {
/* eof in middle of line */
ateof = true;
ptmp = places.current;
place_addcolumns(&ptmp, bufend - linestart);
if (buf[bufend - 1] == '\n') {
complain(&ptmp, "Unclosed comment");
complain_fail();
} else {
complain(&ptmp,
"No newline at end of file");
}
if (mode.werror) {
complain_fail();
}
assert(bufend < bufmax);
lineend = bufend++;
buf[lineend] = '\n';
} else {
bufend += (size_t)result;
lineend = findeol(buf, linestart, bufend);
}
/* loop in case we still don't have a whole line */
continue;
}
/* have a line */
assert(buf[lineend] == '\n');
buf[lineend] = '\0';
nextlinestart = lineend+1;
place_addlines(&places.nextline, 1);
/* check for CR/NL */
if (lineend > 0 && buf[lineend-1] == '\r') {
buf[lineend-1] = '\0';
lineend--;
}
/* check for continuation line */
if (lineend > 0 && buf[lineend-1]=='\\') {
lineend--;
tmp = nextlinestart - lineend;
if (bufend > nextlinestart) {
memmove(buf+lineend, buf+nextlinestart,
bufend - nextlinestart);
}
bufend -= tmp;
nextlinestart -= tmp;
lineend = findeol(buf, linestart, bufend);
/* might not have a whole line, so loop */
continue;
}
/* line now goes from linestart to lineend */
assert(buf[lineend] == '\0');
/* count how many commented-out newlines we swallowed */
place_addlines(&places.nextline,
countnls(buf, linestart, lineend));
/* process the line (even if it's empty) */
directive_gotline(&places, buf+linestart, lineend-linestart);
linestart = nextlinestart;
lineend = findeol(buf, linestart, bufend);
places.current = places.nextline;
}
if (toplevel) {
directive_goteof(&places.current);
}
dofree(buf, bufmax);
}
////////////////////////////////////////////////////////////
// path search
static
char *
mkfilename(struct place *place, const char *dir, const char *file)
{
size_t dlen, flen, rlen;
char *ret;
bool needslash = false;
if (dir == NULL) {
dir = place_getparsedir(place);
}
dlen = strlen(dir);
flen = strlen(file);
if (dlen > 0 && dir[dlen-1] != '/') {
needslash = true;
}
rlen = dlen + (needslash ? 1 : 0) + flen;
ret = domalloc(rlen + 1);
strcpy(ret, dir);
if (needslash) {
strcat(ret, "/");
}
strcat(ret, file);
return ret;
}
static
int
file_tryopen(const char *file)
{
int fd;
/* XXX check for non-regular files */
fd = open(file, O_RDONLY);
if (fd < 0) {
if (errno != ENOENT && errno != ENOTDIR) {
complain(NULL, "%s: %s", file, strerror(errno));
}
return -1;
}
return fd;
}
static
void
file_search(struct place *place, struct incdirarray *path, const char *name)
{
unsigned i, num;
struct incdir *id;
const struct placefile *pf;
char *file;
int fd;
assert(place != NULL);
if (name[0] == '/') {
fd = file_tryopen(name);
if (fd >= 0) {
pf = place_addfile(place, name, true);
file_read(pf, fd, name, false);
close(fd);
return;
}
} else {
num = incdirarray_num(path);
for (i=0; i<num; i++) {
id = incdirarray_get(path, i);
file = mkfilename(place, id->name, name);
fd = file_tryopen(file);
if (fd >= 0) {
pf = place_addfile(place, file, id->issystem);
file_read(pf, fd, file, false);
dostrfree(file);
close(fd);
return;
}
dostrfree(file);
}
}
complain(place, "Include file %s not found", name);
complain_fail();
}
void
file_readquote(struct place *place, const char *name)
{
file_search(place, &quotepath, name);
}
void
file_readbracket(struct place *place, const char *name)
{
file_search(place, &bracketpath, name);
}
void
file_readabsolute(struct place *place, const char *name)
{
const struct placefile *pf;
int fd;
assert(place != NULL);
if (name == NULL) {
fd = STDIN_FILENO;
pf = place_addfile(place, "<standard-input>", false);
} else {
fd = file_tryopen(name);
if (fd < 0) {
complain(NULL, "%s: %s", name, strerror(errno));
die();
}
pf = place_addfile(place, name, false);
}
file_read(pf, fd, name, true);
if (name != NULL) {
close(fd);
}
}

40
external/bsd/tradcpp/dist/files.h vendored Normal file
View File

@ -0,0 +1,40 @@
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David A. Holland.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
struct place;
void files_init(void);
void files_cleanup(void);
void files_addquotepath(const char *dir, bool issystem);
void files_addbracketpath(const char *dir, bool issystem);
void file_readquote(struct place *, const char *name);
void file_readbracket(struct place *, const char *name);
void file_readabsolute(struct place *, const char *name);

39
external/bsd/tradcpp/dist/inlinedefs.h vendored Normal file
View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2009 David A. Holland.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Author nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(__GNUC__) && !defined(__GNUC_STDC_INLINE__)
/* gcc's non-C99 inline semantics */
#define C99INLINE extern inline
#elif defined(__STDC__) && __STDC_VERSION__ >= 199901L
/* C99 */
#define C99INLINE inline
#else
/* something else; static inline is safest */
#define C99INLINE static inline
#endif

1313
external/bsd/tradcpp/dist/macro.c vendored Normal file

File diff suppressed because it is too large Load Diff

51
external/bsd/tradcpp/dist/macro.h vendored Normal file
View File

@ -0,0 +1,51 @@
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David A. Holland.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <stddef.h>
#include "bool.h"
struct place;
void macros_init(void);
void macros_cleanup(void);
void macro_define_plain(struct place *, const char *macro,
struct place *, const char *expansion);
void macro_define_params(struct place *, const char *macro,
struct place *, const char *params,
struct place *, const char *expansion);
void macro_define_magic(struct place *, const char *macro);
void macro_undef(const char *macro);
bool macro_isdefined(const char *macro);
char *macroexpand(struct place *, const char *buf, size_t len,
bool honordefined);
void macro_sendline(struct place *, const char *buf, size_t len);
void macro_sendeof(struct place *);

1113
external/bsd/tradcpp/dist/main.c vendored Normal file

File diff suppressed because it is too large Load Diff

66
external/bsd/tradcpp/dist/mode.h vendored Normal file
View File

@ -0,0 +1,66 @@
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David A. Holland.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "bool.h"
struct mode {
bool werror;
bool input_allow_dollars;
unsigned input_tabstop;
bool do_stdinc;
bool do_stddef;
bool do_output;
bool output_linenumbers;
bool output_cheaplinenumbers;
bool output_retain_comments;
const char *output_file;
bool do_depend;
bool depend_report_system;
bool depend_assume_generated;
bool depend_issue_fakerules;
bool depend_quote_target;
const char *depend_target;
const char *depend_file;
bool do_macrolist;
bool macrolist_include_stddef;
bool macrolist_include_expansions;
bool do_trace;
bool trace_namesonly;
bool trace_indented;
};
struct warns {
bool endiflabels;
bool nestcomment;
bool undef;
bool unused;
};
extern struct mode mode;
extern struct warns warns;

203
external/bsd/tradcpp/dist/output.c vendored Normal file
View File

@ -0,0 +1,203 @@
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David A. Holland.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include "utils.h"
#include "mode.h"
#include "place.h"
#include "output.h"
static int outputfd = -1;
static bool incomment = false;
static char *linebuf;
static size_t linebufpos, linebufmax;
static struct place linebufplace;
static
void
output_open(void)
{
if (mode.output_file == NULL) {
outputfd = STDOUT_FILENO;
} else {
outputfd = open(mode.output_file, O_WRONLY|O_CREAT|O_TRUNC,
0664);
if (outputfd < 0) {
complain(NULL, "%s: %s",
mode.output_file, strerror(errno));
die();
}
}
}
static
void
dowrite(const char *buf, size_t len)
{
size_t done;
ssize_t result;
static unsigned write_errors = 0;
if (!mode.do_output) {
return;
}
if (outputfd < 0) {
output_open();
}
done = 0;
while (done < len) {
result = write(outputfd, buf+done, len-done);
if (result == -1) {
complain(NULL, "%s: write: %s",
mode.output_file, strerror(errno));
complain_failed();
write_errors++;
if (write_errors > 5) {
complain(NULL, "%s: giving up",
mode.output_file);
die();
}
/* XXX is this really a good idea? */
sleep(1);
}
done += (size_t)result;
}
}
static
void
filter_output(const char *buf, size_t len)
{
size_t pos, start;
bool inesc = false;
bool inquote = false;
char quote = '\0';
start = 0;
for (pos = 0; pos < len - 1; pos++) {
if (!inquote && buf[pos] == '/' && buf[pos+1] == '*') {
if (!incomment) {
if (pos > start) {
dowrite(buf + start, pos - start);
}
start = pos;
pos += 2;
incomment = true;
/* cancel out the loop's pos++ */
pos--;
continue;
}
} else if (buf[pos] == '*' && buf[pos+1] == '/') {
if (incomment) {
pos += 2;
if (mode.output_retain_comments) {
dowrite(buf + start, pos - start);
}
start = pos;
incomment = false;
/* cancel out the loop's pos++ */
pos--;
continue;
}
}
if (incomment) {
/* nothing */
} else if (inesc) {
inesc = false;
} else if (buf[pos] == '\\') {
inesc = true;
} else if (!inquote && (buf[pos] == '"' || buf[pos] == '\'')) {
inquote = true;
quote = buf[pos];
} else if (inquote && buf[pos] == quote) {
inquote = false;
}
}
pos++;
if (pos > start) {
if (!incomment || mode.output_retain_comments) {
dowrite(buf + start, pos - start);
}
}
}
void
output(const struct place *p, const char *buf, size_t len)
{
size_t oldmax;
if (linebufpos + len > linebufmax) {
oldmax = linebufmax;
if (linebufmax == 0) {
linebufmax = 64;
}
while (linebufpos + len > linebufmax) {
linebufmax *= 2;
}
linebuf = dorealloc(linebuf, oldmax, linebufmax);
}
if (linebufpos == 0) {
if (!place_samefile(&linebufplace, p)) {
if (mode.output_cheaplinenumbers) {
char str[256];
snprintf(str, sizeof(str), "# %u \"%s\"\n",
p->line, place_getname(p));
dowrite(str, strlen(str));
}
}
linebufplace = *p;
}
memcpy(linebuf + linebufpos, buf, len);
linebufpos += len;
if (len == 1 && buf[0] == '\n') {
filter_output(linebuf, linebufpos);
linebufpos = 0;
}
}
void
output_eof(void)
{
if (mode.output_file != NULL && outputfd >= 0) {
close(outputfd);
}
outputfd = -1;
}

31
external/bsd/tradcpp/dist/output.h vendored Normal file
View File

@ -0,0 +1,31 @@
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David A. Holland.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
void output(const struct place *p, const char *buf, size_t len);
void output_eof(void);

395
external/bsd/tradcpp/dist/place.c vendored Normal file
View File

@ -0,0 +1,395 @@
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David A. Holland.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "utils.h"
#include "array.h"
#include "place.h"
struct placefile {
struct place includedfrom;
char *dir;
char *name;
int depth;
bool fromsystemdir;
};
DECLARRAY(placefile, static UNUSED);
DEFARRAY(placefile, static);
static struct placefilearray placefiles;
static bool overall_failure;
static const char *myprogname;
static FILE *debuglogfile;
////////////////////////////////////////////////////////////
// placefiles
static
struct placefile *
placefile_create(const struct place *from, const char *name,
bool fromsystemdir)
{
struct placefile *pf;
const char *s;
size_t len;
pf = domalloc(sizeof(*pf));
pf->includedfrom = *from;
s = strrchr(name, '/');
len = (s == NULL) ? 0 : s - name;
pf->dir = dostrndup(name, len);
pf->name = dostrdup(name);
pf->fromsystemdir = fromsystemdir;
if (from->file != NULL) {
pf->depth = from->file->depth + 1;
} else {
pf->depth = 1;
}
return pf;
}
static
void
placefile_destroy(struct placefile *pf)
{
dostrfree(pf->name);
dofree(pf, sizeof(*pf));
}
DESTROYALL_ARRAY(placefile, );
const char *
place_getparsedir(const struct place *place)
{
if (place->file == NULL) {
return ".";
}
return place->file->dir;
}
static
struct placefile *
placefile_find(const struct place *incfrom, const char *name)
{
unsigned i, num;
struct placefile *pf;
num = placefilearray_num(&placefiles);
for (i=0; i<num; i++) {
pf = placefilearray_get(&placefiles, i);
if (place_eq(incfrom, &pf->includedfrom) &&
!strcmp(name, pf->name)) {
return pf;
}
}
return NULL;
}
void
place_changefile(struct place *p, const char *name)
{
struct placefile *pf;
assert(p->type == P_FILE);
if (!strcmp(name, p->file->name)) {
return;
}
pf = placefile_find(&p->file->includedfrom, name);
if (pf == NULL) {
pf = placefile_create(&p->file->includedfrom, name,
p->file->fromsystemdir);
placefilearray_add(&placefiles, pf, NULL);
}
p->file = pf;
}
const struct placefile *
place_addfile(const struct place *place, const char *file, bool issystem)
{
struct placefile *pf;
pf = placefile_create(place, file, issystem);
placefilearray_add(&placefiles, pf, NULL);
if (pf->depth > 120) {
complain(place, "Maximum include nesting depth exceeded");
die();
}
return pf;
}
////////////////////////////////////////////////////////////
// places
void
place_setnowhere(struct place *p)
{
p->type = P_NOWHERE;
p->file = NULL;
p->line = 0;
p->column = 0;
}
void
place_setbuiltin(struct place *p, unsigned num)
{
p->type = P_BUILTIN;
p->file = NULL;
p->line = num;
p->column = 1;
}
void
place_setcommandline(struct place *p, unsigned line, unsigned column)
{
p->type = P_COMMANDLINE;
p->file = NULL;
p->line = line;
p->column = column;
}
void
place_setfilestart(struct place *p, const struct placefile *pf)
{
p->type = P_FILE;
p->file = pf;
p->line = 1;
p->column = 1;
}
void
place_addcolumns(struct place *p, unsigned cols)
{
unsigned newcol;
newcol = p->column + cols;
if (newcol < p->column) {
/* overflow (use the old place to complain) */
complain(p, "Column numbering overflow");
die();
}
p->column = newcol;
}
void
place_addlines(struct place *p, unsigned lines)
{
unsigned nextline;
nextline = p->line + lines;
if (nextline < p->line) {
/* overflow (use the old place to complain) */
complain(p, "Line numbering overflow");
die();
}
p->line = nextline;
}
const char *
place_getname(const struct place *p)
{
switch (p->type) {
case P_NOWHERE: return "<nowhere>";
case P_BUILTIN: return "<built-in>";
case P_COMMANDLINE: return "<command-line>";
case P_FILE: return p->file->name;
}
assert(0);
return NULL;
}
bool
place_samefile(const struct place *a, const struct place *b)
{
if (a->type != b->type) {
return false;
}
if (a->file != b->file) {
return false;
}
return true;
}
bool
place_eq(const struct place *a, const struct place *b)
{
if (!place_samefile(a, b)) {
return false;
}
if (a->line != b->line || a->column != b->column) {
return false;
}
return true;
}
static
void
place_printfrom(const struct place *p)
{
const struct place *from;
if (p->file == NULL) {
return;
}
from = &p->file->includedfrom;
if (from->type != P_NOWHERE) {
place_printfrom(from);
fprintf(stderr, "In file included from %s:%u:%u:\n",
place_getname(from), from->line, from->column);
}
}
////////////////////////////////////////////////////////////
// complaints
void
complain_init(const char *pn)
{
myprogname = pn;
}
void
complain(const struct place *p, const char *fmt, ...)
{
va_list ap;
if (p != NULL) {
place_printfrom(p);
fprintf(stderr, "%s:%u:%u: ", place_getname(p),
p->line, p->column);
} else {
fprintf(stderr, "%s: ", myprogname);
}
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
fprintf(stderr, "\n");
}
void
complain_fail(void)
{
overall_failure = true;
}
bool
complain_failed(void)
{
return overall_failure;
}
////////////////////////////////////////////////////////////
// debug logging
void
debuglog_open(const struct place *p, /*const*/ char *file)
{
assert(debuglogfile == NULL);
debuglogfile = fopen(file, "w");
if (debuglogfile == NULL) {
complain(p, "%s: %s", file, strerror(errno));
die();
}
}
void
debuglog_close(void)
{
if (debuglogfile != NULL) {
fclose(debuglogfile);
debuglogfile = NULL;
}
}
PF(2, 3) void
debuglog(const struct place *p, const char *fmt, ...)
{
va_list ap;
if (debuglogfile == NULL) {
return;
}
fprintf(debuglogfile, "%s:%u: ", place_getname(p), p->line);
va_start(ap, fmt);
vfprintf(debuglogfile, fmt, ap);
va_end(ap);
fprintf(debuglogfile, "\n");
fflush(debuglogfile);
}
PF(3, 4) void
debuglog2(const struct place *p, const struct place *p2, const char *fmt, ...)
{
va_list ap;
if (debuglogfile == NULL) {
return;
}
fprintf(debuglogfile, "%s:%u: ", place_getname(p), p->line);
if (place_samefile(p, p2)) {
fprintf(debuglogfile, "(block began at line %u) ",
p2->line);
} else {
fprintf(debuglogfile, "(block began at %s:%u)",
place_getname(p2), p2->line);
}
va_start(ap, fmt);
vfprintf(debuglogfile, fmt, ap);
va_end(ap);
fprintf(debuglogfile, "\n");
fflush(debuglogfile);
}
////////////////////////////////////////////////////////////
// module init and cleanup
void
place_init(void)
{
placefilearray_init(&placefiles);
}
void
place_cleanup(void)
{
placefilearray_destroyall(&placefiles);
placefilearray_cleanup(&placefiles);
}

69
external/bsd/tradcpp/dist/place.h vendored Normal file
View File

@ -0,0 +1,69 @@
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David A. Holland.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PLACE_H
#define PLACE_H
#include "bool.h"
enum places {
P_NOWHERE,
P_BUILTIN,
P_COMMANDLINE,
P_FILE,
};
struct place {
enum places type;
const struct placefile *file;
unsigned line;
unsigned column;
};
void place_init(void);
void place_cleanup(void);
void place_setnowhere(struct place *p);
void place_setbuiltin(struct place *p, unsigned num);
void place_setcommandline(struct place *p, unsigned word, unsigned column);
void place_setfilestart(struct place *p, const struct placefile *pf);
void place_addcolumns(struct place *, unsigned cols);
void place_addlines(struct place *, unsigned lines);
const char *place_getname(const struct place *);
const char *place_getparsedir(const struct place *incplace);
bool place_eq(const struct place *, const struct place *);
bool place_samefile(const struct place *, const struct place *);
void place_changefile(struct place *p, const char *name);
const struct placefile *place_addfile(const struct place *incplace,
const char *name, bool fromsystemdir);
#endif /* PLACE_H */

View File

@ -0,0 +1,45 @@
TRADCPP_OBJDIR!= ${MAKE} -C ${.CURDIR}/.. -V .OBJDIR
TRADCPP= ${TRADCPP_OBJDIR}/tradcpp
TESTS=\
t01 t02 t03 t04 t05 t06 t07 t08 t09 t10 t11 t12 t13 t14 t15 t16 \
t17 t18 t19 t20 t21 t22 t23 t24 t25 t26 t27 t28 t29 t30 t31 t32 \
t33 t34 t35 t36 t37 t38 t39 t40
all: run-tests .WAIT show-diffs
.for T in $(TESTS)
run-tests: $(T).diff
$(T).diff: $(T).run $(T).good $(TRADCPP)
-diff -u $(T).good $(T).run > $(T).diff
$(T).run: $(TRADCPP) $(T).c
$(TRADCPP) $(T).c > $(T).run 2>&1 || echo FAILED >> $(T).run
.endfor
show-diffs:
@echo '*** Test diffs ***'
.for T in $(TESTS)
@cat $(T).diff
.endfor
clean:
.for T in $(TESTS)
rm -f $(T).run $(T).diff
.endfor
good:
.for T in $(TESTS)
cp $(T).run $(T).good
.endfor
.PHONY: all run-tests show-diffs clean good
############################################################
.if defined(ALLOW_BROKEN_ATF_POLLUTION)
TESTDIR= ${TESTSBASE}/usr.bin/tradcpp
TESTS_SH+= tradcpp
.include <bsd.test.mk>
.endif

View File

@ -0,0 +1 @@
hello

1
external/bsd/tradcpp/dist/tests/t01.c vendored Normal file
View File

@ -0,0 +1 @@
glop.

View File

@ -0,0 +1 @@
glop.

2
external/bsd/tradcpp/dist/tests/t02.c vendored Normal file
View File

@ -0,0 +1,2 @@
#define glop flop
glop

View File

@ -0,0 +1 @@
flop

2
external/bsd/tradcpp/dist/tests/t03.c vendored Normal file
View File

@ -0,0 +1,2 @@
#define glop(x) flop x
glop(boo)

View File

@ -0,0 +1 @@
flop boo

2
external/bsd/tradcpp/dist/tests/t04.c vendored Normal file
View File

@ -0,0 +1,2 @@
#define string(x) "x"
string(abc)

View File

@ -0,0 +1 @@
"abc"

2
external/bsd/tradcpp/dist/tests/t05.c vendored Normal file
View File

@ -0,0 +1,2 @@
#define concat(a, b) a/**/b
concat(abc,def)

View File

@ -0,0 +1 @@
abcdef

2
external/bsd/tradcpp/dist/tests/t06.c vendored Normal file
View File

@ -0,0 +1,2 @@
/*glop*/

View File

@ -0,0 +1 @@

3
external/bsd/tradcpp/dist/tests/t07.c vendored Normal file
View File

@ -0,0 +1,3 @@
/*
* gloop
*/

View File

@ -0,0 +1 @@

41
external/bsd/tradcpp/dist/tests/t08.c vendored Normal file
View File

@ -0,0 +1,41 @@
/*#include <stdio.h>*/
int d =
#if 2 > 1 ? 0 : 0 ? 1 : 1
1
#else
0
#endif
;
int e =
#if (2 > 1 ? 0 : 0) ? 1 : 1
1
#else
0
#endif
;
int f =
#if 2 > 1 ? 0 : (0 ? 1 : 1)
1
#else
0
#endif
;
int
main()
{
int a, b, c;
a = 2 > 1 ? 0 : 0 ? 1 : 1;
b = (2 > 1 ? 0 : 0) ? 1 : 1;
c = 2 > 1 ? 0 : (0 ? 1 : 1);
printf("%d %d %d\n", a, b, c);
printf("%d %d %d\n", d, e, f);
return 0;
}

View File

@ -0,0 +1,21 @@
int d =
0
;
int e =
1
;
int f =
0
;
int
main()
{
int a, b, c;
a = 2 > 1 ? 0 : 0 ? 1 : 1;
b = (2 > 1 ? 0 : 0) ? 1 : 1;
c = 2 > 1 ? 0 : (0 ? 1 : 1);
printf("%d %d %d\n", a, b, c);
printf("%d %d %d\n", d, e, f);
return 0;
}

6
external/bsd/tradcpp/dist/tests/t09.c vendored Normal file
View File

@ -0,0 +1,6 @@
#define STOP */
#define START /*
/*
* blah blah blah STOP fnord START goop moop
*/

View File

3
external/bsd/tradcpp/dist/tests/t10.c vendored Normal file
View File

@ -0,0 +1,3 @@
#define mac(r)o
mac(3)
mac()

View File

@ -0,0 +1,2 @@
o
o

2
external/bsd/tradcpp/dist/tests/t11.c vendored Normal file
View File

@ -0,0 +1,2 @@
#define BOO BOO
BOO

View File

@ -0,0 +1 @@
BOO

2
external/bsd/tradcpp/dist/tests/t12.c vendored Normal file
View File

@ -0,0 +1,2 @@
#define BOO(yah) BOO(yah)
BOO(yah)

View File

@ -0,0 +1 @@
BOO(yah)

4
external/bsd/tradcpp/dist/tests/t13.c vendored Normal file
View File

@ -0,0 +1,4 @@
/*
#define FOO BAR
*/
FOO

View File

@ -0,0 +1,2 @@
FOO

4
external/bsd/tradcpp/dist/tests/t14.c vendored Normal file
View File

@ -0,0 +1,4 @@
/*
#define FOO BAR */
FOO
FOO

View File

@ -0,0 +1,3 @@
FOO
FOO

3
external/bsd/tradcpp/dist/tests/t15.c vendored Normal file
View File

@ -0,0 +1,3 @@
#define FOO /* BAR */ BAZ
FOO
FOO

View File

@ -0,0 +1,2 @@
BAZ
BAZ

11
external/bsd/tradcpp/dist/tests/t16.c vendored Normal file
View File

@ -0,0 +1,11 @@
#define a() x
a()
a ()
#define b(p) p
x/**/b(1)/**/x
x/**/b (1)/**/x
x/**/b()/**/x
#define c(p,q) p/**/q
x/**/c(1,2)/**/x
x/**/c(1)/**/x
x/**/c()/**/x

View File

@ -0,0 +1,11 @@
x
x
x1x
x1x
xx
x12x
t16.c:10:1: Wrong number of arguments for macro c; found 1, expected 2
x1x
t16.c:11:1: Wrong number of arguments for macro c; found 0, expected 2
xx
FAILED

2
external/bsd/tradcpp/dist/tests/t17.c vendored Normal file
View File

@ -0,0 +1,2 @@
#define file "subdir/test.h"
#include file

View File

@ -0,0 +1 @@
hello

2
external/bsd/tradcpp/dist/tests/t18.c vendored Normal file
View File

@ -0,0 +1,2 @@
#if FOO /* ignore me */
#endif

View File

3
external/bsd/tradcpp/dist/tests/t19.c vendored Normal file
View File

@ -0,0 +1,3 @@
#define foo /* comment continues
into the next line */ baz
baz

View File

@ -0,0 +1 @@
baz

1
external/bsd/tradcpp/dist/tests/t20.c vendored Normal file
View File

@ -0,0 +1 @@
#undef foo /* blah */

View File

3
external/bsd/tradcpp/dist/tests/t21.c vendored Normal file
View File

@ -0,0 +1,3 @@
# define FOO BAR
#undef FOO /* would be wrong */
FOO

View File

@ -0,0 +1,2 @@
#undef BAR
BAR

2
external/bsd/tradcpp/dist/tests/t22.c vendored Normal file
View File

@ -0,0 +1,2 @@
pa/*
*/ste

View File

@ -0,0 +1 @@
paste

8
external/bsd/tradcpp/dist/tests/t23.c vendored Normal file
View File

@ -0,0 +1,8 @@
/*
fnord1
/*
fnord2
*/
foo
*/
bar

View File

@ -0,0 +1,4 @@
foo
*/
bar

67
external/bsd/tradcpp/dist/tests/t24.c vendored Normal file
View File

@ -0,0 +1,67 @@
#if 0
wrong
#endif
#if 1
right
#endif
#if -1
right
#endif
#if 0 + 0
wrong
#endif
#if 1 + 1
right
#endif
#if 1 - 1
wrong
#endif
#if -1 + 1
wrong
#endif
#if 3 - 2 - 1
wrong
#endif
#if 3 * 2 - 6
wrong
#endif
#if 6 - 2 * 3
wrong
#endif
#if 3 - 3 && 1
wrong
#endif
#if 3 - 3 || 0
wrong
#endif
#if 1 && 0
wrong
#endif
#if 0 && 1
wrong
#endif
#if 1 || 0
right
#endif
#if 0 || 1
right
#endif
#if (0 || 1) && (0 || 0)
wrong
#endif

View File

@ -0,0 +1,5 @@
right
right
right
right
right

4
external/bsd/tradcpp/dist/tests/t25.c vendored Normal file
View File

@ -0,0 +1,4 @@
#define FOO foo /*
#undef FOO
#define FOO bar */
FOO

View File

@ -0,0 +1 @@
foo

4
external/bsd/tradcpp/dist/tests/t26.c vendored Normal file
View File

@ -0,0 +1,4 @@
#define FOO foo
FOO
"FOO"
'FOO'

View File

@ -0,0 +1,3 @@
foo
"FOO"
'FOO'

29
external/bsd/tradcpp/dist/tests/t27.c vendored Normal file
View File

@ -0,0 +1,29 @@
1.
#define A(a) a
A();
2.
#define B(a, b) (a,b)
B(a, );
B(, b);
B( , );
B(a,);
B(,b);
B(,);
3.
#define C(a, b, c) (a,b,c)
C(a, b, );
C(a, , c);
C(, , c);
C(a, , );
C(, b, );
C(, , c);
C(, , )
C(a,b,);
C(a,,c);
C(,,c);
C(a,,);
C(,b,);
C(,,c);
C(,,)

View File

@ -0,0 +1,24 @@
1.
;
2.
(a, );
(, b);
( , );
(a,);
(,b);
(,);
3.
(a, b, );
(a, , c);
(, , c);
(a, , );
(, b, );
(, , c);
(, , )
(a,b,);
(a,,c);
(,,c);
(a,,);
(,b,);
(,,c);
(,,)

53
external/bsd/tradcpp/dist/tests/t28.c vendored Normal file
View File

@ -0,0 +1,53 @@
#if 1
. right
# if 1
.. right
# elif 1
.. wrong
# elif 0
.. wrong
# else
.. wrong
# endif
#elif 1
. wrong
# if 1
.. wrong
# elif 1
.. wrong
# elif 0
.. wrong
# else
.. wrong
# endif
#elif 0
. wrong
# if 1
.. wrong
# elif 1
.. wrong
# elif 0
.. wrong
# else
.. wrong
# endif
#else
. wrong
# if 1
.. wrong
# elif 1
.. wrong
# elif 0
.. wrong
# else
.. wrong
# endif
#endif

View File

@ -0,0 +1,2 @@
. right
.. right

4
external/bsd/tradcpp/dist/tests/t29.c vendored Normal file
View File

@ -0,0 +1,4 @@
#if 0
# if this is a syntax error
# endif
#endif

View File

2
external/bsd/tradcpp/dist/tests/t30.c vendored Normal file
View File

@ -0,0 +1,2 @@
#define x(a,b,c) a;b;c;
x((,),x,",")

View File

@ -0,0 +1 @@
(,);x;",";

6
external/bsd/tradcpp/dist/tests/t31.c vendored Normal file
View File

@ -0,0 +1,6 @@
this line 'has /* no' comment */ in it
#define BELCH(x) 'x'
"BELCH(123)": BELCH(123)
'BELCH(123)': BELCH(123)

View File

@ -0,0 +1,3 @@
this line 'has /* no' comment */ in it
"BELCH(123)": '123'
'BELCH(123)': '123'

21
external/bsd/tradcpp/dist/tests/t32.c vendored Normal file
View File

@ -0,0 +1,21 @@
#define foo(x) "x"
#define bar(x) 'x'
#define baz frob
foo(3)
bar(3)
foo(baz)
bar(baz)
"baz"
'baz'
"foo(baz)"
"bar(baz)"
#define foo2(x) foo(x)
#define bar2(x) bar(x)
foo2(baz)
bar2(baz)
#define foo3(x) foo2(x)
#define bar3(x) bar2(x)
foo3(baz)
bar3(baz)

View File

@ -0,0 +1,12 @@
"3"
'3'
"baz"
'baz'
"baz"
'baz'
"foo(baz)"
"bar(baz)"
"baz"
'baz'
"baz"
'baz'

6
external/bsd/tradcpp/dist/tests/t33.c vendored Normal file
View File

@ -0,0 +1,6 @@
/* make sure that R gets defined and doesn't end up part of a string */
#define Q "
#define R r
#define S "
R
Q

View File

@ -0,0 +1,3 @@
r
"

5
external/bsd/tradcpp/dist/tests/t34.c vendored Normal file
View File

@ -0,0 +1,5 @@
#define Q "
#define FOO foo
Q FOO Q

View File

@ -0,0 +1 @@
" foo "

6
external/bsd/tradcpp/dist/tests/t35.c vendored Normal file
View File

@ -0,0 +1,6 @@
#define Q "
#define FOO foo
Q FOO Q 'I like "FOO" and "BAR"'

View File

@ -0,0 +1 @@
" foo " 'I like "FOO" and "BAR"'

7
external/bsd/tradcpp/dist/tests/t36.c vendored Normal file
View File

@ -0,0 +1,7 @@
#define C(x) //**/* x */**//
C(3)
C(abc /* def */ ghi)
#define D(x) ///**/**/**///**/* x */**///**/**/**///
D(3)
D(abc /* def */ ghi)

View File

@ -0,0 +1,4 @@
/* 3 */
/* abc ghi */
//**/* 3 */**//
//**/* abc ghi */**//

19
external/bsd/tradcpp/dist/tests/t37.c vendored Normal file
View File

@ -0,0 +1,19 @@
#define BC //**/*
#define EC */**//
BC
comment?
EC
BC comment? EC
#define FOO(x) x
FOO(abc BC def EC ghi)
#define BAR(x, y) x y
BAR(abc BC def, ghi EC jkl)
BC
#define BAZ baz
EC
BAZ

View File

@ -0,0 +1,9 @@
/*
comment?
*/
/* comment? */
abc /* def */ ghi
abc /* def ghi */ jkl
/*
*/
baz

Some files were not shown because too many files have changed in this diff Show More