xref: /openbsd-src/gnu/usr.bin/perl/t/porting/header_parser.t (revision f2a19305cfc49ea4d1a5feb55cd6c283c6f1e031)
1*f2a19305Safresh1#!./perl -w
2*f2a19305Safresh1
3*f2a19305Safresh1# Verify that all files generated by perl scripts are up to date.
4*f2a19305Safresh1
5*f2a19305Safresh1BEGIN {
6*f2a19305Safresh1    if (-f "./TestInit.pm") {
7*f2a19305Safresh1        push @INC, ".";
8*f2a19305Safresh1    } elsif (-f '../TestInit.pm') {
9*f2a19305Safresh1        push @INC, "..";
10*f2a19305Safresh1    }
11*f2a19305Safresh1}
12*f2a19305Safresh1use TestInit qw(T A); # T is chdir to the top level, A makes paths absolute
13*f2a19305Safresh1use strict;
14*f2a19305Safresh1
15*f2a19305Safresh1# this tests the functions in HeaderParser.pm which we use for make regen.
16*f2a19305Safresh1
17*f2a19305Safresh1require './t/test.pl';
18*f2a19305Safresh1require './regen/HeaderParser.pm';
19*f2a19305Safresh1
20*f2a19305Safresh1skip_all_if_miniperl("needs Data::Dumper");
21*f2a19305Safresh1
22*f2a19305Safresh1require Data::Dumper;
23*f2a19305Safresh1
24*f2a19305Safresh1sub show_text {
25*f2a19305Safresh1    my ($as_text)= @_;
26*f2a19305Safresh1    print STDERR $as_text=~s/^/" " x 8/mger;
27*f2a19305Safresh1}
28*f2a19305Safresh1
29*f2a19305Safresh1my $hp= HeaderParser->new();
30*f2a19305Safresh1$hp->parse_text(<<~'EOF');
31*f2a19305Safresh1    #ifdef A
32*f2a19305Safresh1    #ifdef B
33*f2a19305Safresh1    #define AB
34*f2a19305Safresh1    content 1
35*f2a19305Safresh1    #endif
36*f2a19305Safresh1    content 2
37*f2a19305Safresh1    #define A
38*f2a19305Safresh1    #endif
39*f2a19305Safresh1    /*comment
40*f2a19305Safresh1      line */
41*f2a19305Safresh1    #define C /* this is
42*f2a19305Safresh1                 a hidden line continuation */ D
43*f2a19305Safresh1    EOF
44*f2a19305Safresh1my $normal= $hp->lines_as_str();
45*f2a19305Safresh1my $lines= $hp->lines();
46*f2a19305Safresh1my $lines_as_str= Data::Dumper->new([$lines])->Sortkeys(1)->Useqq(1)->Indent(1)->Dump();
47*f2a19305Safresh1is($lines_as_str,<<~'DUMP_EOF', "Simple data structure as expected") or show_text($lines_as_str);
48*f2a19305Safresh1        $VAR1 = [
49*f2a19305Safresh1          bless( {
50*f2a19305Safresh1            "cond" => [
51*f2a19305Safresh1              [
52*f2a19305Safresh1                "defined(A)"
53*f2a19305Safresh1              ]
54*f2a19305Safresh1            ],
55*f2a19305Safresh1            "flat" => "#if defined(A)",
56*f2a19305Safresh1            "level" => 0,
57*f2a19305Safresh1            "line" => "#if defined(A)\n",
58*f2a19305Safresh1            "n_lines" => 1,
59*f2a19305Safresh1            "raw" => "#ifdef A\n",
60*f2a19305Safresh1            "source" => "(buffer)",
61*f2a19305Safresh1            "start_line_num" => 1,
62*f2a19305Safresh1            "sub_type" => "#if",
63*f2a19305Safresh1            "type" => "cond"
64*f2a19305Safresh1          }, 'HeaderLine' ),
65*f2a19305Safresh1          bless( {
66*f2a19305Safresh1            "cond" => [
67*f2a19305Safresh1              [
68*f2a19305Safresh1                "defined(A)"
69*f2a19305Safresh1              ],
70*f2a19305Safresh1              [
71*f2a19305Safresh1                "defined(B)"
72*f2a19305Safresh1              ]
73*f2a19305Safresh1            ],
74*f2a19305Safresh1            "flat" => "#if defined(B)",
75*f2a19305Safresh1            "level" => 1,
76*f2a19305Safresh1            "line" => "# if defined(B)\n",
77*f2a19305Safresh1            "n_lines" => 1,
78*f2a19305Safresh1            "raw" => "#ifdef B\n",
79*f2a19305Safresh1            "source" => "(buffer)",
80*f2a19305Safresh1            "start_line_num" => 2,
81*f2a19305Safresh1            "sub_type" => "#if",
82*f2a19305Safresh1            "type" => "cond"
83*f2a19305Safresh1          }, 'HeaderLine' ),
84*f2a19305Safresh1          bless( {
85*f2a19305Safresh1            "cond" => [
86*f2a19305Safresh1              [
87*f2a19305Safresh1                "defined(A)"
88*f2a19305Safresh1              ],
89*f2a19305Safresh1              [
90*f2a19305Safresh1                "defined(B)"
91*f2a19305Safresh1              ]
92*f2a19305Safresh1            ],
93*f2a19305Safresh1            "flat" => "#define AB",
94*f2a19305Safresh1            "level" => 2,
95*f2a19305Safresh1            "line" => "#   define AB\n",
96*f2a19305Safresh1            "n_lines" => 1,
97*f2a19305Safresh1            "raw" => "#define AB\n",
98*f2a19305Safresh1            "source" => "(buffer)",
99*f2a19305Safresh1            "start_line_num" => 3,
100*f2a19305Safresh1            "sub_type" => "#define",
101*f2a19305Safresh1            "type" => "content"
102*f2a19305Safresh1          }, 'HeaderLine' ),
103*f2a19305Safresh1          bless( {
104*f2a19305Safresh1            "cond" => [
105*f2a19305Safresh1              [
106*f2a19305Safresh1                "defined(A)"
107*f2a19305Safresh1              ],
108*f2a19305Safresh1              [
109*f2a19305Safresh1                "defined(B)"
110*f2a19305Safresh1              ]
111*f2a19305Safresh1            ],
112*f2a19305Safresh1            "flat" => "content 1",
113*f2a19305Safresh1            "level" => 2,
114*f2a19305Safresh1            "line" => "content 1\n",
115*f2a19305Safresh1            "n_lines" => 1,
116*f2a19305Safresh1            "raw" => "content 1\n",
117*f2a19305Safresh1            "source" => "(buffer)",
118*f2a19305Safresh1            "start_line_num" => 4,
119*f2a19305Safresh1            "sub_type" => "text",
120*f2a19305Safresh1            "type" => "content"
121*f2a19305Safresh1          }, 'HeaderLine' ),
122*f2a19305Safresh1          bless( {
123*f2a19305Safresh1            "cond" => [
124*f2a19305Safresh1              [
125*f2a19305Safresh1                "defined(A)"
126*f2a19305Safresh1              ],
127*f2a19305Safresh1              [
128*f2a19305Safresh1                "defined(B)"
129*f2a19305Safresh1              ]
130*f2a19305Safresh1            ],
131*f2a19305Safresh1            "flat" => "#endif",
132*f2a19305Safresh1            "inner_lines" => 3,
133*f2a19305Safresh1            "level" => 1,
134*f2a19305Safresh1            "line" => "# endif\n",
135*f2a19305Safresh1            "n_lines" => 1,
136*f2a19305Safresh1            "raw" => "#endif\n",
137*f2a19305Safresh1            "source" => "(buffer)",
138*f2a19305Safresh1            "start_line_num" => 5,
139*f2a19305Safresh1            "sub_type" => "#endif",
140*f2a19305Safresh1            "type" => "cond"
141*f2a19305Safresh1          }, 'HeaderLine' ),
142*f2a19305Safresh1          bless( {
143*f2a19305Safresh1            "cond" => [
144*f2a19305Safresh1              [
145*f2a19305Safresh1                "defined(A)"
146*f2a19305Safresh1              ]
147*f2a19305Safresh1            ],
148*f2a19305Safresh1            "flat" => "content 2",
149*f2a19305Safresh1            "level" => 1,
150*f2a19305Safresh1            "line" => "content 2\n",
151*f2a19305Safresh1            "n_lines" => 1,
152*f2a19305Safresh1            "raw" => "content 2\n",
153*f2a19305Safresh1            "source" => "(buffer)",
154*f2a19305Safresh1            "start_line_num" => 6,
155*f2a19305Safresh1            "sub_type" => "text",
156*f2a19305Safresh1            "type" => "content"
157*f2a19305Safresh1          }, 'HeaderLine' ),
158*f2a19305Safresh1          bless( {
159*f2a19305Safresh1            "cond" => [
160*f2a19305Safresh1              [
161*f2a19305Safresh1                "defined(A)"
162*f2a19305Safresh1              ]
163*f2a19305Safresh1            ],
164*f2a19305Safresh1            "flat" => "#define A",
165*f2a19305Safresh1            "level" => 1,
166*f2a19305Safresh1            "line" => "# define A\n",
167*f2a19305Safresh1            "n_lines" => 1,
168*f2a19305Safresh1            "raw" => "#define A\n",
169*f2a19305Safresh1            "source" => "(buffer)",
170*f2a19305Safresh1            "start_line_num" => 7,
171*f2a19305Safresh1            "sub_type" => "#define",
172*f2a19305Safresh1            "type" => "content"
173*f2a19305Safresh1          }, 'HeaderLine' ),
174*f2a19305Safresh1          bless( {
175*f2a19305Safresh1            "cond" => [
176*f2a19305Safresh1              [
177*f2a19305Safresh1                "defined(A)"
178*f2a19305Safresh1              ]
179*f2a19305Safresh1            ],
180*f2a19305Safresh1            "flat" => "#endif",
181*f2a19305Safresh1            "inner_lines" => 7,
182*f2a19305Safresh1            "level" => 0,
183*f2a19305Safresh1            "line" => "#endif\n",
184*f2a19305Safresh1            "n_lines" => 1,
185*f2a19305Safresh1            "raw" => "#endif\n",
186*f2a19305Safresh1            "source" => "(buffer)",
187*f2a19305Safresh1            "start_line_num" => 8,
188*f2a19305Safresh1            "sub_type" => "#endif",
189*f2a19305Safresh1            "type" => "cond"
190*f2a19305Safresh1          }, 'HeaderLine' ),
191*f2a19305Safresh1          bless( {
192*f2a19305Safresh1            "cond" => [],
193*f2a19305Safresh1            "flat" => "",
194*f2a19305Safresh1            "level" => 0,
195*f2a19305Safresh1            "line" => "/*comment\n  line */\n",
196*f2a19305Safresh1            "n_lines" => 2,
197*f2a19305Safresh1            "raw" => "/*comment\n  line */\n",
198*f2a19305Safresh1            "source" => "(buffer)",
199*f2a19305Safresh1            "start_line_num" => 9,
200*f2a19305Safresh1            "sub_type" => "text",
201*f2a19305Safresh1            "type" => "content"
202*f2a19305Safresh1          }, 'HeaderLine' ),
203*f2a19305Safresh1          bless( {
204*f2a19305Safresh1            "cond" => [],
205*f2a19305Safresh1            "flat" => "#define C D",
206*f2a19305Safresh1            "level" => 0,
207*f2a19305Safresh1            "line" => "#define C /* this is\n             a hidden line continuation */ D\n",
208*f2a19305Safresh1            "n_lines" => 2,
209*f2a19305Safresh1            "raw" => "#define C /* this is\n             a hidden line continuation */ D\n",
210*f2a19305Safresh1            "source" => "(buffer)",
211*f2a19305Safresh1            "start_line_num" => 11,
212*f2a19305Safresh1            "sub_type" => "#define",
213*f2a19305Safresh1            "type" => "content"
214*f2a19305Safresh1          }, 'HeaderLine' )
215*f2a19305Safresh1        ];
216*f2a19305Safresh1        DUMP_EOF
217*f2a19305Safresh1
218*f2a19305Safresh1is($normal,<<~'EOF',"Normalized text as expected");
219*f2a19305Safresh1    #if defined(A)
220*f2a19305Safresh1    # if defined(B)
221*f2a19305Safresh1    #   define AB
222*f2a19305Safresh1    content 1
223*f2a19305Safresh1    # endif
224*f2a19305Safresh1    content 2
225*f2a19305Safresh1    # define A
226*f2a19305Safresh1    #endif
227*f2a19305Safresh1    /*comment
228*f2a19305Safresh1      line */
229*f2a19305Safresh1    #define C /* this is
230*f2a19305Safresh1                 a hidden line continuation */ D
231*f2a19305Safresh1    EOF
232*f2a19305Safresh1
233*f2a19305Safresh1{
234*f2a19305Safresh1    my @warn;
235*f2a19305Safresh1    local $SIG{__WARN__}= sub { push @warn, $_[0]; warn $_[0] };
236*f2a19305Safresh1    my $ok= eval {
237*f2a19305Safresh1        HeaderParser->new(add_commented_expr_after=>0)->parse_text(<<~'EOF'); 1
238*f2a19305Safresh1        #ifdef A
239*f2a19305Safresh1        #ifdef B
240*f2a19305Safresh1        #endif
241*f2a19305Safresh1        EOF
242*f2a19305Safresh1    };
243*f2a19305Safresh1    my $err= !$ok ? $@ : "";
244*f2a19305Safresh1    ok(!$ok,"Should throw an error");
245*f2a19305Safresh1    like($err,qr/Unterminated conditional block starting line 1 with last conditional operation at line 3/,
246*f2a19305Safresh1         "Got expected error message");
247*f2a19305Safresh1}
248*f2a19305Safresh1{
249*f2a19305Safresh1    my @warn;
250*f2a19305Safresh1    local $SIG{__WARN__}= sub { push @warn, $_[0]; warn $_[0] };
251*f2a19305Safresh1    my $ok= eval {
252*f2a19305Safresh1        HeaderParser->new(add_commented_expr_after=>0)->parse_text(<<~'EOF'); 1
253*f2a19305Safresh1        #ifdef A
254*f2a19305Safresh1        #ifdef B
255*f2a19305Safresh1        #elif C
256*f2a19305Safresh1        EOF
257*f2a19305Safresh1    };
258*f2a19305Safresh1    my $err= !$ok ? $@ : "";
259*f2a19305Safresh1    ok(!$ok,"Should throw an error");
260*f2a19305Safresh1    like($err,qr/Unterminated conditional block starting line 3/,
261*f2a19305Safresh1         "Unterminated block detected");
262*f2a19305Safresh1}
263*f2a19305Safresh1{
264*f2a19305Safresh1    my @warn;
265*f2a19305Safresh1    local $SIG{__WARN__}= sub { push @warn, $_[0]; warn $_[0] };
266*f2a19305Safresh1    my $ok= eval {
267*f2a19305Safresh1        HeaderParser->new(add_commented_expr_after=>0)->parse_text(<<~'EOF'); 1
268*f2a19305Safresh1        #if 1 * * 10 > 5
269*f2a19305Safresh1        #elifdef C
270*f2a19305Safresh1        EOF
271*f2a19305Safresh1    };
272*f2a19305Safresh1    my $err= !$ok ? $@ : "";
273*f2a19305Safresh1    ok(!$ok,"Should throw an error");
274*f2a19305Safresh1    is($err,
275*f2a19305Safresh1       "Error at line 1\n" .
276*f2a19305Safresh1       "Line 1: #if 1 * * 10 > 5\n" .
277*f2a19305Safresh1       "Error in multiplication expression: " .
278*f2a19305Safresh1       "Unexpected token '*', expecting literal, unary, or expression.\n",
279*f2a19305Safresh1         "Expected token error") or warn $err;
280*f2a19305Safresh1}
281*f2a19305Safresh1{
282*f2a19305Safresh1    my $hp= HeaderParser->new(debug=>0,add_commented_expr_after=>0);
283*f2a19305Safresh1
284*f2a19305Safresh1    $hp->parse_text(<<~'EOF');
285*f2a19305Safresh1        #ifdef A
286*f2a19305Safresh1        # ifdef B
287*f2a19305Safresh1        #   define P
288*f2a19305Safresh1        # else
289*f2a19305Safresh1        #   define Q
290*f2a19305Safresh1        # endif
291*f2a19305Safresh1        # if !defined B
292*f2a19305Safresh1        #   define R
293*f2a19305Safresh1        # else
294*f2a19305Safresh1        #   define S
295*f2a19305Safresh1        # endif
296*f2a19305Safresh1        #endif
297*f2a19305Safresh1        EOF
298*f2a19305Safresh1    my $grouped= $hp->group_content();
299*f2a19305Safresh1    my $as_text= $hp->lines_as_str($grouped);
300*f2a19305Safresh1    is($as_text,<<~'EOF',"inverted simple clauses get merged properly") or show_text($as_text);
301*f2a19305Safresh1        #if defined(A)
302*f2a19305Safresh1        # if defined(B)
303*f2a19305Safresh1        #   define P
304*f2a19305Safresh1        #   define S
305*f2a19305Safresh1        # else /* if !defined(B) */
306*f2a19305Safresh1        #   define Q
307*f2a19305Safresh1        #   define R
308*f2a19305Safresh1        # endif /* !defined(B) */
309*f2a19305Safresh1        #endif /* defined(A) */
310*f2a19305Safresh1        EOF
311*f2a19305Safresh1}
312*f2a19305Safresh1{
313*f2a19305Safresh1    my $hp= HeaderParser->new(debug=>0,add_commented_expr_after=>0);
314*f2a19305Safresh1    $hp->parse_text(<<~'EOF');
315*f2a19305Safresh1        #if defined(A) && defined(B)
316*f2a19305Safresh1        # if (defined(C) && defined(D))
317*f2a19305Safresh1        #   define P
318*f2a19305Safresh1        # else
319*f2a19305Safresh1        #   define Q
320*f2a19305Safresh1        # endif
321*f2a19305Safresh1        # if !(defined C && defined D)
322*f2a19305Safresh1        #   define R
323*f2a19305Safresh1        # else
324*f2a19305Safresh1        #   define S
325*f2a19305Safresh1        # endif
326*f2a19305Safresh1        #endif
327*f2a19305Safresh1        EOF
328*f2a19305Safresh1    my $grouped= $hp->group_content();
329*f2a19305Safresh1    my $as_text= $hp->lines_as_str($grouped);
330*f2a19305Safresh1    is($as_text,<<~'EOF',"inverted complex clauses get merged properly") or show_text($as_text);
331*f2a19305Safresh1        #if defined(A) && defined(B)
332*f2a19305Safresh1        # if defined(C) && defined(D)
333*f2a19305Safresh1        #   define P
334*f2a19305Safresh1        #   define S
335*f2a19305Safresh1        # else /* if !( defined(C) && defined(D) ) */
336*f2a19305Safresh1        #   define Q
337*f2a19305Safresh1        #   define R
338*f2a19305Safresh1        # endif /* !( defined(C) && defined(D) ) */
339*f2a19305Safresh1        #endif /* defined(A) && defined(B) */
340*f2a19305Safresh1        EOF
341*f2a19305Safresh1}
342*f2a19305Safresh1{
343*f2a19305Safresh1    my $hp= HeaderParser->new(debug=>0,add_commented_expr_after=>0);
344*f2a19305Safresh1    $hp->parse_text(<<~'EOF');
345*f2a19305Safresh1        #if defined(A)
346*f2a19305Safresh1        #define HAS_A
347*f2a19305Safresh1        #elif defined(B)
348*f2a19305Safresh1        #define HAS_B
349*f2a19305Safresh1        #elif defined(C)
350*f2a19305Safresh1        #define HAS_C
351*f2a19305Safresh1        #else
352*f2a19305Safresh1        #define HAS_D
353*f2a19305Safresh1        #endif
354*f2a19305Safresh1        EOF
355*f2a19305Safresh1    my $grouped= $hp->group_content();
356*f2a19305Safresh1    my $as_text= $hp->lines_as_str($grouped);
357*f2a19305Safresh1    is($as_text,<<~'EOF',"test nested elif round trip") or show_text($as_text);
358*f2a19305Safresh1        #if defined(A)
359*f2a19305Safresh1        # define HAS_A
360*f2a19305Safresh1        #elif defined(B) /* && !defined(A) */
361*f2a19305Safresh1        # define HAS_B
362*f2a19305Safresh1        #elif defined(C) /* && !defined(A) && !defined(B) */
363*f2a19305Safresh1        # define HAS_C
364*f2a19305Safresh1        #else /* if !defined(A) && !defined(B) && !defined(C) */
365*f2a19305Safresh1        # define HAS_D
366*f2a19305Safresh1        #endif /* !defined(A) && !defined(B) && !defined(C) */
367*f2a19305Safresh1        EOF
368*f2a19305Safresh1}
369*f2a19305Safresh1{
370*f2a19305Safresh1    my $hp= HeaderParser->new(debug=>0,add_commented_expr_after=>0);
371*f2a19305Safresh1    $hp->parse_text(<<~'EOF');
372*f2a19305Safresh1        #if defined(A)
373*f2a19305Safresh1        #define HAS_A
374*f2a19305Safresh1        #endif
375*f2a19305Safresh1        #if !defined(A) && defined(B)
376*f2a19305Safresh1        #define HAS_B
377*f2a19305Safresh1        #endif
378*f2a19305Safresh1        #if defined(C)
379*f2a19305Safresh1        #if !defined(A)
380*f2a19305Safresh1        #if !defined(B)
381*f2a19305Safresh1        #define HAS_C
382*f2a19305Safresh1        #endif
383*f2a19305Safresh1        #endif
384*f2a19305Safresh1        #endif
385*f2a19305Safresh1        #if !defined(B) && !defined(A) && !defined(C)
386*f2a19305Safresh1        #define HAS_D
387*f2a19305Safresh1        #endif
388*f2a19305Safresh1        EOF
389*f2a19305Safresh1    my $grouped= $hp->group_content();
390*f2a19305Safresh1    my $as_text= $hp->lines_as_str($grouped);
391*f2a19305Safresh1    is($as_text,<<~'EOF',"test elif composition from disparate statements") or show_text($as_text);
392*f2a19305Safresh1        #if defined(A)
393*f2a19305Safresh1        # define HAS_A
394*f2a19305Safresh1        #elif defined(B) /* && !defined(A) */
395*f2a19305Safresh1        # define HAS_B
396*f2a19305Safresh1        #elif defined(C) /* && !defined(A) && !defined(B) */
397*f2a19305Safresh1        # define HAS_C
398*f2a19305Safresh1        #else /* if !defined(A) && !defined(B) && !defined(C) */
399*f2a19305Safresh1        # define HAS_D
400*f2a19305Safresh1        #endif /* !defined(A) && !defined(B) && !defined(C) */
401*f2a19305Safresh1        EOF
402*f2a19305Safresh1}
403*f2a19305Safresh1{
404*f2a19305Safresh1    my $hp= HeaderParser->new(debug=>0,add_commented_expr_after=>0);
405*f2a19305Safresh1    $hp->parse_text(<<~'EOF');
406*f2a19305Safresh1        #if defined(A)
407*f2a19305Safresh1        #define HAS_A
408*f2a19305Safresh1        #endif
409*f2a19305Safresh1        #if !defined(A)
410*f2a19305Safresh1        #define HAS_NOT_A
411*f2a19305Safresh1        #if !defined(C)
412*f2a19305Safresh1        #define HAS_A_NOT_C
413*f2a19305Safresh1        #endif
414*f2a19305Safresh1        #endif
415*f2a19305Safresh1        #if defined(C)
416*f2a19305Safresh1        #define HAS_C
417*f2a19305Safresh1        #if defined(A)
418*f2a19305Safresh1        #define HAS_A_C
419*f2a19305Safresh1        #endif
420*f2a19305Safresh1        #else
421*f2a19305Safresh1        #if defined(A)
422*f2a19305Safresh1        #define HAS_NOT_C_A
423*f2a19305Safresh1        #endif
424*f2a19305Safresh1        #endif
425*f2a19305Safresh1        EOF
426*f2a19305Safresh1    my $grouped= $hp->group_content();
427*f2a19305Safresh1    my $as_text= $hp->lines_as_str($grouped);
428*f2a19305Safresh1    is($as_text,<<~'EOF',"test else composition") or show_text($as_text);
429*f2a19305Safresh1        #if defined(A)
430*f2a19305Safresh1        # define HAS_A
431*f2a19305Safresh1        # if defined(C)
432*f2a19305Safresh1        #   define HAS_A_C
433*f2a19305Safresh1        # else /* if !defined(C) */
434*f2a19305Safresh1        #   define HAS_NOT_C_A
435*f2a19305Safresh1        # endif /* !defined(C) */
436*f2a19305Safresh1        #else /* if !defined(A) */
437*f2a19305Safresh1        # define HAS_NOT_A
438*f2a19305Safresh1        # if !defined(C)
439*f2a19305Safresh1        #   define HAS_A_NOT_C
440*f2a19305Safresh1        # endif /* !defined(C) */
441*f2a19305Safresh1        #endif /* !defined(A) */
442*f2a19305Safresh1        #if defined(C)
443*f2a19305Safresh1        # define HAS_C
444*f2a19305Safresh1        #endif /* defined(C) */
445*f2a19305Safresh1        EOF
446*f2a19305Safresh1}
447*f2a19305Safresh1{
448*f2a19305Safresh1    my $hp= HeaderParser->new(debug=>0,add_commented_expr_after=>0);
449*f2a19305Safresh1    $hp->parse_text(<<~'EOF');
450*f2a19305Safresh1        #if !defined(A)
451*f2a19305Safresh1        #define NOT_A1
452*f2a19305Safresh1        #else
453*f2a19305Safresh1        #define A1
454*f2a19305Safresh1        #endif
455*f2a19305Safresh1        #if !!!!defined(A)
456*f2a19305Safresh1        #define A2
457*f2a19305Safresh1        #else
458*f2a19305Safresh1        #define NOT_A2
459*f2a19305Safresh1        #endif
460*f2a19305Safresh1        EOF
461*f2a19305Safresh1    my $grouped= $hp->group_content();
462*f2a19305Safresh1    my $as_text= $hp->lines_as_str($grouped);
463*f2a19305Safresh1    is($as_text,<<~'EOF',"normalization into if/else") or show_text($as_text);
464*f2a19305Safresh1        #if defined(A)
465*f2a19305Safresh1        # define A1
466*f2a19305Safresh1        # define A2
467*f2a19305Safresh1        #else /* if !defined(A) */
468*f2a19305Safresh1        # define NOT_A1
469*f2a19305Safresh1        # define NOT_A2
470*f2a19305Safresh1        #endif /* !defined(A) */
471*f2a19305Safresh1        EOF
472*f2a19305Safresh1}
473*f2a19305Safresh1{
474*f2a19305Safresh1    my $hp= HeaderParser->new(debug=>0,add_commented_expr_after=>0);
475*f2a19305Safresh1    $hp->parse_text(<<~'EOF');
476*f2a19305Safresh1        #if !!!(defined(A) && defined(B))
477*f2a19305Safresh1        #define NOT_A_AND_B
478*f2a19305Safresh1        #endif
479*f2a19305Safresh1        #if defined(A)
480*f2a19305Safresh1        #if defined(B)
481*f2a19305Safresh1        #define A_AND_B
482*f2a19305Safresh1        #endif
483*f2a19305Safresh1        #endif
484*f2a19305Safresh1        EOF
485*f2a19305Safresh1    my $grouped= $hp->group_content();
486*f2a19305Safresh1    my $as_text= $hp->lines_as_str($grouped);
487*f2a19305Safresh1    is($as_text,<<~'EOF',"normalization with complex else") or show_text($as_text);
488*f2a19305Safresh1        #if defined(A) && defined(B)
489*f2a19305Safresh1        # define A_AND_B
490*f2a19305Safresh1        #else /* if !( defined(A) && defined(B) ) */
491*f2a19305Safresh1        # define NOT_A_AND_B
492*f2a19305Safresh1        #endif /* !( defined(A) && defined(B) ) */
493*f2a19305Safresh1        EOF
494*f2a19305Safresh1}
495*f2a19305Safresh1{
496*f2a19305Safresh1    my $hp= HeaderParser->new(debug=>0,add_commented_expr_after=>0);
497*f2a19305Safresh1    $hp->parse_text(<<~'EOF');
498*f2a19305Safresh1        #if defined(A) && !!defined(A) && !!!!defined(A)
499*f2a19305Safresh1        #define HAS_A
500*f2a19305Safresh1        #endif
501*f2a19305Safresh1        EOF
502*f2a19305Safresh1    my $grouped= $hp->group_content();
503*f2a19305Safresh1    my $as_text= $hp->lines_as_str($grouped);
504*f2a19305Safresh1    is($as_text,<<~'EOF',"simplification") or show_text($as_text);
505*f2a19305Safresh1        #if defined(A)
506*f2a19305Safresh1        # define HAS_A
507*f2a19305Safresh1        #endif /* defined(A) */
508*f2a19305Safresh1        EOF
509*f2a19305Safresh1}
510*f2a19305Safresh1{
511*f2a19305Safresh1    local $::TODO;
512*f2a19305Safresh1    $::TODO= "Absorbtion not implemented yet";
513*f2a19305Safresh1    # currently we don't handle absorbtion: (A && (A || B || C ...)) == A
514*f2a19305Safresh1    my $hp= HeaderParser->new(debug=>0,add_commented_expr_after=>0);
515*f2a19305Safresh1    $hp->parse_text(<<~'EOF');
516*f2a19305Safresh1        #if defined(X) && (defined(X) || defined(Y))
517*f2a19305Safresh1        #define HAS_X
518*f2a19305Safresh1        #endif
519*f2a19305Safresh1        EOF
520*f2a19305Safresh1    my $grouped= $hp->group_content();
521*f2a19305Safresh1    my $as_text= $hp->lines_as_str($grouped);
522*f2a19305Safresh1    is($as_text,<<~'EOF',"simplification by absorbtion"); # or show_text($as_text);
523*f2a19305Safresh1        #if defined(X)
524*f2a19305Safresh1        # define HAS_X
525*f2a19305Safresh1        #endif /* defined(X) */
526*f2a19305Safresh1        EOF
527*f2a19305Safresh1}
528*f2a19305Safresh1{
529*f2a19305Safresh1    my $hp= HeaderParser->new(debug=>0,add_commented_expr_after=>0);
530*f2a19305Safresh1    $hp->parse_text(<<~'EOF');
531*f2a19305Safresh1        #if defined(A) && (defined(B) && defined(C))
532*f2a19305Safresh1        #define HAS_A
533*f2a19305Safresh1        #endif
534*f2a19305Safresh1        EOF
535*f2a19305Safresh1    my $grouped= $hp->group_content();
536*f2a19305Safresh1    my $as_text= $hp->lines_as_str($grouped);
537*f2a19305Safresh1    is($as_text,<<~'EOF',"expression flattening") or show_text($as_text);
538*f2a19305Safresh1        #if defined(A) && defined(B) && defined(C)
539*f2a19305Safresh1        # define HAS_A
540*f2a19305Safresh1        #endif /* defined(A) && defined(B) && defined(C) */
541*f2a19305Safresh1        EOF
542*f2a19305Safresh1}
543*f2a19305Safresh1{
544*f2a19305Safresh1    my $hp= HeaderParser->new(debug=>0,add_commented_expr_after=>3);
545*f2a19305Safresh1    $hp->parse_text(<<~'EOF');
546*f2a19305Safresh1        #if defined(A)
547*f2a19305Safresh1        #define HAS_A1
548*f2a19305Safresh1        #define HAS_A2
549*f2a19305Safresh1        #define HAS_A3
550*f2a19305Safresh1        #endif
551*f2a19305Safresh1        #if defined(B)
552*f2a19305Safresh1        #define HAS_B1
553*f2a19305Safresh1        #else
554*f2a19305Safresh1        #define HAS_B1e
555*f2a19305Safresh1        #define HAS_B2e
556*f2a19305Safresh1        #define HAS_B3e
557*f2a19305Safresh1        #endif
558*f2a19305Safresh1        #if defined(C)
559*f2a19305Safresh1        #if defined(D)
560*f2a19305Safresh1        #define HAS_D1
561*f2a19305Safresh1        #endif
562*f2a19305Safresh1        #elif defined(CC)
563*f2a19305Safresh1        #define HAS_CC1
564*f2a19305Safresh1        #define HAS_CC2
565*f2a19305Safresh1        #define HAS_CC3
566*f2a19305Safresh1        #endif
567*f2a19305Safresh1        EOF
568*f2a19305Safresh1    my $grouped= $hp->group_content();
569*f2a19305Safresh1    my $as_text= $hp->lines_as_str($grouped);
570*f2a19305Safresh1    is($as_text,<<~'EOF',"auto-comments") or show_text($as_text);
571*f2a19305Safresh1        #if defined(A)
572*f2a19305Safresh1        # define HAS_A1
573*f2a19305Safresh1        # define HAS_A2
574*f2a19305Safresh1        # define HAS_A3
575*f2a19305Safresh1        #endif /* defined(A) */
576*f2a19305Safresh1        #if defined(B)
577*f2a19305Safresh1        # define HAS_B1
578*f2a19305Safresh1        #else
579*f2a19305Safresh1        # define HAS_B1e
580*f2a19305Safresh1        # define HAS_B2e
581*f2a19305Safresh1        # define HAS_B3e
582*f2a19305Safresh1        #endif /* !defined(B) */
583*f2a19305Safresh1        #if defined(C)
584*f2a19305Safresh1        # if defined(D)
585*f2a19305Safresh1        #   define HAS_D1
586*f2a19305Safresh1        # endif
587*f2a19305Safresh1        #elif defined(CC) /* && !defined(C) */
588*f2a19305Safresh1        # define HAS_CC1
589*f2a19305Safresh1        # define HAS_CC2
590*f2a19305Safresh1        # define HAS_CC3
591*f2a19305Safresh1        #endif /* !defined(C) && defined(CC) */
592*f2a19305Safresh1        EOF
593*f2a19305Safresh1}
594*f2a19305Safresh1{
595*f2a19305Safresh1    my $hp= HeaderParser->new(debug=>0,add_commented_expr_after=>0);
596*f2a19305Safresh1    $hp->parse_text(<<~'EOF');
597*f2a19305Safresh1        #if  defined(DEBUGGING)                                                    \
598*f2a19305Safresh1             || (defined(USE_LOCALE) && (    defined(USE_THREADS)                  \
599*f2a19305Safresh1                                        ||   defined(HAS_IGNORED_LOCALE_CATEGORIES)\
600*f2a19305Safresh1                                        ||   defined(USE_POSIX_2008_LOCALE)        \
601*f2a19305Safresh1                                        || ! defined(LC_ALL)))
602*f2a19305Safresh1        # define X
603*f2a19305Safresh1        #endif
604*f2a19305Safresh1        EOF
605*f2a19305Safresh1    my $grouped= $hp->group_content();
606*f2a19305Safresh1    my $as_text= $hp->lines_as_str($grouped);
607*f2a19305Safresh1    is($as_text,<<~'EOF',"Karls example") or show_text($as_text);
608*f2a19305Safresh1        #if   defined(DEBUGGING) ||                                         \
609*f2a19305Safresh1            ( defined(USE_LOCALE) &&                                        \
610*f2a19305Safresh1            ( defined(HAS_IGNORED_LOCALE_CATEGORIES) || !defined(LC_ALL) || \
611*f2a19305Safresh1              defined(USE_POSIX_2008_LOCALE) || defined(USE_THREADS) ) )
612*f2a19305Safresh1        # define X
613*f2a19305Safresh1        #endif /*   defined(DEBUGGING) ||
614*f2a19305Safresh1                  ( defined(USE_LOCALE) &&
615*f2a19305Safresh1                  ( defined(HAS_IGNORED_LOCALE_CATEGORIES) || !defined(LC_ALL) ||
616*f2a19305Safresh1                    defined(USE_POSIX_2008_LOCALE) || defined(USE_THREADS) ) ) */
617*f2a19305Safresh1        EOF
618*f2a19305Safresh1}
619*f2a19305Safresh1
620*f2a19305Safresh1done_testing();
621