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