The Android Open Source Project | cea198a | 2009-03-03 19:29:17 -0800 | [diff] [blame] | 1 | # Bison Parser Headers. -*- Autotest -*- |
The Android Open Source Project | cea198a | 2009-03-03 19:29:17 -0800 | [diff] [blame] | 2 | |
Ying Wang | 0543663 | 2013-04-05 16:01:00 -0700 | [diff] [blame] | 3 | # Copyright (C) 2001-2002, 2006-2007, 2009-2012 Free Software |
| 4 | # Foundation, Inc. |
| 5 | |
| 6 | # This program is free software: you can redistribute it and/or modify |
The Android Open Source Project | cea198a | 2009-03-03 19:29:17 -0800 | [diff] [blame] | 7 | # it under the terms of the GNU General Public License as published by |
Ying Wang | 0543663 | 2013-04-05 16:01:00 -0700 | [diff] [blame] | 8 | # the Free Software Foundation, either version 3 of the License, or |
| 9 | # (at your option) any later version. |
| 10 | # |
The Android Open Source Project | cea198a | 2009-03-03 19:29:17 -0800 | [diff] [blame] | 11 | # This program is distributed in the hope that it will be useful, |
| 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | # GNU General Public License for more details. |
Ying Wang | 0543663 | 2013-04-05 16:01:00 -0700 | [diff] [blame] | 15 | # |
The Android Open Source Project | cea198a | 2009-03-03 19:29:17 -0800 | [diff] [blame] | 16 | # You should have received a copy of the GNU General Public License |
Ying Wang | 0543663 | 2013-04-05 16:01:00 -0700 | [diff] [blame] | 17 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
The Android Open Source Project | cea198a | 2009-03-03 19:29:17 -0800 | [diff] [blame] | 18 | |
| 19 | AT_BANNER([[Parser Headers.]]) |
| 20 | |
| 21 | |
The Android Open Source Project | cea198a | 2009-03-03 19:29:17 -0800 | [diff] [blame] | 22 | ## --------------------- ## |
| 23 | ## Invalid CPP headers. ## |
| 24 | ## --------------------- ## |
| 25 | |
Ying Wang | 0543663 | 2013-04-05 16:01:00 -0700 | [diff] [blame] | 26 | # AT_TEST_CPP_GUARD_H(BASE-NAME, [DIRECTIVES]) |
| 27 | # -------------------------------------------- |
| 28 | # FIXME: Much of this can be covered by calc.at. |
The Android Open Source Project | cea198a | 2009-03-03 19:29:17 -0800 | [diff] [blame] | 29 | m4_define([AT_TEST_CPP_GUARD_H], |
Ying Wang | 0543663 | 2013-04-05 16:01:00 -0700 | [diff] [blame] | 30 | [AT_SETUP([Invalid CPP guards: $2 --defines=$1.h]) |
| 31 | AT_BISON_OPTION_PUSHDEFS([$2]) |
The Android Open Source Project | cea198a | 2009-03-03 19:29:17 -0800 | [diff] [blame] | 32 | # Possibly create inner directories. |
| 33 | dirname=`AS_DIRNAME([$1])` |
| 34 | AS_MKDIR_P([$dirname]) |
| 35 | |
| 36 | AT_DATA_GRAMMAR([$1.y], |
Ying Wang | 0543663 | 2013-04-05 16:01:00 -0700 | [diff] [blame] | 37 | [$2 |
| 38 | %{ |
The Android Open Source Project | cea198a | 2009-03-03 19:29:17 -0800 | [diff] [blame] | 39 | #include <$1.h> |
Ying Wang | 0543663 | 2013-04-05 16:01:00 -0700 | [diff] [blame] | 40 | ]AT_YYERROR_DECLARE_EXTERN[ |
| 41 | ]AT_YYLEX_DECLARE_EXTERN[ |
The Android Open Source Project | cea198a | 2009-03-03 19:29:17 -0800 | [diff] [blame] | 42 | %} |
| 43 | %% |
| 44 | dummy:; |
| 45 | %% |
| 46 | #include <$1.h> |
| 47 | ]) |
| 48 | |
Ying Wang | 0543663 | 2013-04-05 16:01:00 -0700 | [diff] [blame] | 49 | AT_BISON_CHECK([--defines=$1.h --output=$1.c $1.y]) |
The Android Open Source Project | cea198a | 2009-03-03 19:29:17 -0800 | [diff] [blame] | 50 | |
Ying Wang | 0543663 | 2013-04-05 16:01:00 -0700 | [diff] [blame] | 51 | AT_COMPILE([$1.o], [-I. -c $1.c]) |
The Android Open Source Project | cea198a | 2009-03-03 19:29:17 -0800 | [diff] [blame] | 52 | |
Ying Wang | 0543663 | 2013-04-05 16:01:00 -0700 | [diff] [blame] | 53 | AT_BISON_OPTION_POPDEFS |
The Android Open Source Project | cea198a | 2009-03-03 19:29:17 -0800 | [diff] [blame] | 54 | AT_CLEANUP |
| 55 | ]) |
| 56 | |
| 57 | AT_TEST_CPP_GUARD_H([input/input]) |
| 58 | AT_TEST_CPP_GUARD_H([9foo]) |
Ying Wang | 0543663 | 2013-04-05 16:01:00 -0700 | [diff] [blame] | 59 | AT_TEST_CPP_GUARD_H([input/input], [%glr-parser]) |
| 60 | AT_TEST_CPP_GUARD_H([9foo], [%glr-parser]) |
The Android Open Source Project | cea198a | 2009-03-03 19:29:17 -0800 | [diff] [blame] | 61 | |
| 62 | |
| 63 | |
| 64 | ## ---------------- ## |
| 65 | ## export YYLTYPE. ## |
| 66 | ## ---------------- ## |
| 67 | |
| 68 | |
| 69 | AT_SETUP([export YYLTYPE]) |
| 70 | |
| 71 | AT_DATA_GRAMMAR([input.y], |
| 72 | [%locations |
| 73 | |
Ying Wang | 0543663 | 2013-04-05 16:01:00 -0700 | [diff] [blame] | 74 | %name-prefix "my_" |
The Android Open Source Project | cea198a | 2009-03-03 19:29:17 -0800 | [diff] [blame] | 75 | %{ |
| 76 | #include <stdio.h> |
| 77 | #include <stdlib.h> |
| 78 | |
| 79 | static int |
| 80 | my_lex (void) |
| 81 | { |
| 82 | return EOF; |
| 83 | } |
| 84 | |
| 85 | static void |
| 86 | my_error (const char *msg) |
| 87 | { |
| 88 | fprintf (stderr, "%s\n", msg); |
| 89 | } |
| 90 | |
| 91 | %} |
| 92 | %% |
| 93 | exp:; |
| 94 | ]) |
| 95 | |
Ying Wang | 0543663 | 2013-04-05 16:01:00 -0700 | [diff] [blame] | 96 | AT_BISON_CHECK([--defines -o input.c input.y]) |
The Android Open Source Project | cea198a | 2009-03-03 19:29:17 -0800 | [diff] [blame] | 97 | |
| 98 | # YYLTYPE should be defined, and MY_LLOC declared. |
| 99 | AT_DATA([caller.c], |
| 100 | [[#include "input.h" |
| 101 | YYLTYPE *my_llocp = &my_lloc; |
| 102 | |
| 103 | int my_parse (void); |
| 104 | |
| 105 | int |
| 106 | main (void) |
| 107 | { |
| 108 | return my_parse (); |
| 109 | } |
| 110 | ]]) |
| 111 | |
| 112 | # Link and execute, just to make sure everything is fine (and in |
| 113 | # particular, that MY_LLOC is indeed defined somewhere). |
Ying Wang | 0543663 | 2013-04-05 16:01:00 -0700 | [diff] [blame] | 114 | AT_COMPILE([caller.o]) |
| 115 | AT_COMPILE([input.o]) |
The Android Open Source Project | cea198a | 2009-03-03 19:29:17 -0800 | [diff] [blame] | 116 | AT_COMPILE([caller], [caller.o input.o]) |
| 117 | AT_PARSER_CHECK([./caller]) |
| 118 | |
| 119 | AT_CLEANUP |
Ying Wang | 0543663 | 2013-04-05 16:01:00 -0700 | [diff] [blame] | 120 | |
| 121 | ## ----------------- ## |
| 122 | ## Several parsers. ## |
| 123 | ## ----------------- ## |
| 124 | |
| 125 | AT_SETUP([Several parsers]) |
| 126 | |
| 127 | # AT_TEST([PREFIX], [DIRECTIVES]) |
| 128 | # ------------------------------- |
| 129 | # Generate and compile to *.o. Make sure there is no (allowed) YY* |
| 130 | # nor yy* identifiers in the header. Check that headers are |
| 131 | # self-contained, and can be compiled by a C++ compiler. |
| 132 | m4_pushdef([AT_TEST], |
| 133 | [AT_BISON_OPTION_PUSHDEFS([%define api.prefix "$1_" $2]) |
| 134 | AT_DATA_GRAMMAR([$1.y], |
| 135 | [[%define api.prefix "$1_" |
| 136 | $2 |
| 137 | %error-verbose |
| 138 | %union |
| 139 | { |
| 140 | int integer; |
| 141 | } |
| 142 | %{ |
| 143 | #include <stdio.h> |
| 144 | ]AT_YYERROR_DECLARE[ |
| 145 | ]AT_YYLEX_DECLARE[ |
| 146 | %} |
| 147 | %% |
| 148 | exp: |
| 149 | 'x' '1' { printf ("x1\n"); } |
| 150 | | 'x' '2' { printf ("x2\n"); } |
| 151 | | 'x' '3' { printf ("x3\n"); } |
| 152 | | 'x' '4' { printf ("x4\n"); } |
| 153 | | 'x' '5' { printf ("x5\n"); } |
| 154 | | 'x' '6' { printf ("x6\n"); } |
| 155 | | 'x' '7' { printf ("x7\n"); } |
| 156 | | 'x' '8' { printf ("x8\n"); } |
| 157 | ; |
| 158 | |
| 159 | %% |
| 160 | ]AT_YYERROR_DEFINE[ |
| 161 | ]AT_YYLEX_DEFINE(["$1"])[ |
| 162 | ]]) |
| 163 | |
| 164 | AT_BISON_CHECK([-d -o $1.AT_SKEL_CC_IF([cc], [c]) $1.y]) |
| 165 | |
| 166 | AT_LANG_COMPILE([$1.o]) |
| 167 | AT_CHECK([[echo "$1" >>expout]]) |
| 168 | |
| 169 | AT_BISON_OPTION_POPDEFS |
| 170 | ])# AT_TEST |
| 171 | |
| 172 | AT_DATA([main.cc], |
| 173 | [AT_DATA_SOURCE_PROLOGUE |
| 174 | [// If we are compiling with CC=$CXX, then do not load the C headers |
| 175 | // inside extern "C", since they were _not_ compiled this way. |
| 176 | #if ! CC_IS_CXX |
| 177 | extern "C" |
| 178 | { |
| 179 | #endif |
| 180 | #include "x1.h" |
| 181 | #include "x2.h" |
| 182 | #include "x3.h" |
| 183 | #include "x4.h" |
| 184 | #include "x6.h" |
| 185 | #include "x7.h" |
| 186 | #include "x8.h" |
| 187 | #if ! CC_IS_CXX |
| 188 | } |
| 189 | #endif |
| 190 | #include "x5.hh" |
| 191 | //#include "x6.hh" |
| 192 | |
| 193 | #define RUN(S) \ |
| 194 | do { \ |
| 195 | int res = S; \ |
| 196 | if (res) \ |
| 197 | std::cerr << #S": " << res << std::endl; \ |
| 198 | } while (false) |
| 199 | |
| 200 | int |
| 201 | main (void) |
| 202 | { |
| 203 | RUN(x1_parse()); |
| 204 | RUN(x2_parse()); |
| 205 | RUN(x3_parse()); |
| 206 | RUN(x4_parse()); |
| 207 | x5_::parser p5; |
| 208 | RUN(p5.parse()); |
| 209 | RUN(x6_parse()); |
| 210 | RUN(x7_parse()); |
| 211 | RUN(x8_parse()); |
| 212 | // x6_::parser p6; |
| 213 | // RUN(p6.parse()); |
| 214 | return 0; |
| 215 | } |
| 216 | ]])# main.cc |
| 217 | |
| 218 | AT_TEST([x1], []) |
| 219 | AT_TEST([x2], [%locations %debug]) |
| 220 | AT_TEST([x3], [%glr-parser]) |
| 221 | AT_TEST([x4], [%locations %debug %glr-parser]) |
| 222 | AT_TEST([x5], [%locations %debug %language "c++"]) |
| 223 | AT_TEST([x6], [%define api.pure]) |
| 224 | AT_TEST([x7], [%define api.push-pull both]) |
| 225 | AT_TEST([x8], [%define api.pure %define api.push-pull both]) |
| 226 | #AT_TEST([x5], [%locations %language "c++" %glr-parser]) |
| 227 | |
| 228 | # Check there is no 'yy' left. |
| 229 | # C++ output relies on namespaces and still uses yy a lot. |
| 230 | # |
| 231 | # Check there is no 'YY' left. |
| 232 | # Ignore comments, YYChar (template parameter), YYPARSE_PARAM |
| 233 | # (obsolete), YYPUSH_MORE(_DEFINED)? (constant definition), |
| 234 | # YY_\w+_INCLUDED (header guards). |
| 235 | # |
| 236 | # YYDEBUG (not renamed) can be read, but not changed. |
| 237 | AT_CHECK([[$PERL -n -0777 -e ' |
| 238 | s{/\*.*?\*/}{}gs; |
| 239 | s{//.*}{}g; |
| 240 | s{\b(YYChar |
| 241 | |YYPARSE_PARAM |
| 242 | |YYPUSH_MORE(_DEFINED)? |
| 243 | |YY_\w+_INCLUDED |
| 244 | |YY_NULL |
| 245 | |(defined|if)\ YYDEBUG |
| 246 | )\b}{}gx; |
| 247 | while (/^(.*YY.*)$/gm) |
| 248 | { |
| 249 | print "$ARGV: invalid exported YY: $1\n"; |
| 250 | } |
| 251 | if ($ARGV =~ /\.h$/) |
| 252 | { |
| 253 | while (/^(.*yy.*)$/gm) |
| 254 | { |
| 255 | print "$ARGV: invalid exported yy: $1\n"; |
| 256 | } |
| 257 | } |
| 258 | ' -- *.hh *.h]]) |
| 259 | |
| 260 | # Check that the headers are self-contained, and protected against |
| 261 | # multiple inclusions. While at it, check they are sane for C++. |
| 262 | for h in *.h *.hh |
| 263 | do |
| 264 | # No shell expansion with AT_DATA. |
| 265 | cat >$h.cc <<EOF |
| 266 | AT_DATA_SOURCE_PROLOGUE |
| 267 | #include "$h" |
| 268 | #include "$h" |
| 269 | EOF |
| 270 | AT_COMPILE_CXX([$h.o]) |
| 271 | done |
| 272 | |
| 273 | # Do this late, so that other checks have been performed. |
| 274 | AT_SKIP_IF_CANNOT_LINK_C_AND_CXX |
| 275 | |
| 276 | AT_COMPILE_CXX([parser], [[x[1-8].o -DCC_IS_CXX=$CC_IS_CXX main.cc]]) |
| 277 | AT_PARSER_CHECK([./parser], [0], [[expout]]) |
| 278 | |
| 279 | m4_popdef([AT_TEST]) |
| 280 | |
| 281 | AT_CLEANUP |