1 /****************************************************************************** 2 * 3 * Module Name: asremove - Source conversion - removal functions 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2018, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include "acpisrc.h" 45 46 /* Local prototypes */ 47 48 void 49 AsRemoveStatement ( 50 char *Buffer, 51 char *Keyword, 52 UINT32 Type); 53 54 55 /****************************************************************************** 56 * 57 * FUNCTION: AsRemoveStatement 58 * 59 * DESCRIPTION: Remove all statements that contain the given keyword. 60 * Limitations: Removes text from the start of the line that 61 * contains the keyword to the next semicolon. Currently 62 * doesn't ignore comments. 63 * 64 ******************************************************************************/ 65 66 void 67 AsRemoveStatement ( 68 char *Buffer, 69 char *Keyword, 70 UINT32 Type) 71 { 72 char *SubString; 73 char *SubBuffer; 74 int KeywordLength; 75 76 77 KeywordLength = strlen (Keyword); 78 SubBuffer = Buffer; 79 SubString = Buffer; 80 81 while (SubString) 82 { 83 SubString = strstr (SubBuffer, Keyword); 84 85 if (SubString) 86 { 87 SubBuffer = SubString; 88 89 if ((Type == REPLACE_WHOLE_WORD) && 90 (!AsMatchExactWord (SubString, KeywordLength))) 91 { 92 SubBuffer++; 93 continue; 94 } 95 96 /* Find start of this line */ 97 98 while (*SubString != '\n') 99 { 100 SubString--; 101 } 102 SubString++; 103 104 /* Find end of this statement */ 105 106 SubBuffer = AsSkipPastChar (SubBuffer, ';'); 107 if (!SubBuffer) 108 { 109 return; 110 } 111 112 /* Find end of this line */ 113 114 SubBuffer = AsSkipPastChar (SubBuffer, '\n'); 115 if (!SubBuffer) 116 { 117 return; 118 } 119 120 /* If next line is blank, remove it too */ 121 122 if (*SubBuffer == '\n') 123 { 124 SubBuffer++; 125 } 126 127 /* Remove the lines */ 128 129 SubBuffer = AsRemoveData (SubString, SubBuffer); 130 } 131 } 132 } 133 134 135 /****************************************************************************** 136 * 137 * FUNCTION: AsRemoveConditionalCompile 138 * 139 * DESCRIPTION: Remove a "#ifdef" statement, and all text that it encompasses. 140 * Limitations: cannot handle nested ifdefs. 141 * 142 ******************************************************************************/ 143 144 void 145 AsRemoveConditionalCompile ( 146 char *Buffer, 147 char *Keyword) 148 { 149 char *SubString; 150 char *SubBuffer; 151 char *IfPtr; 152 char *EndifPtr; 153 char *ElsePtr; 154 char *Comment; 155 int KeywordLength; 156 157 158 KeywordLength = strlen (Keyword); 159 SubBuffer = Buffer; 160 SubString = Buffer; 161 162 while (SubString) 163 { 164 SubBuffer = strstr (SubString, Keyword); 165 if (!SubBuffer) 166 { 167 return; 168 } 169 170 /* 171 * Check for translation escape string -- means to ignore 172 * blocks of code while replacing 173 */ 174 if (Gbl_IgnoreTranslationEscapes) 175 { 176 Comment = NULL; 177 } 178 else 179 { 180 Comment = strstr (SubString, AS_START_IGNORE); 181 } 182 183 if ((Comment) && 184 (Comment < SubBuffer)) 185 { 186 SubString = strstr (Comment, AS_STOP_IGNORE); 187 if (!SubString) 188 { 189 return; 190 } 191 192 SubString += 3; 193 continue; 194 } 195 196 /* Check for ordinary comment */ 197 198 Comment = strstr (SubString, "/*"); 199 200 if ((Comment) && 201 (Comment < SubBuffer)) 202 { 203 SubString = strstr (Comment, "*/"); 204 if (!SubString) 205 { 206 return; 207 } 208 209 SubString += 2; 210 continue; 211 } 212 213 SubString = SubBuffer; 214 if (!AsMatchExactWord (SubString, KeywordLength)) 215 { 216 SubString++; 217 continue; 218 } 219 220 /* Find start of this line */ 221 222 while (*SubString != '\n' && (SubString > Buffer)) 223 { 224 SubString--; 225 } 226 227 SubString++; 228 229 /* Find the "#ifxxxx" */ 230 231 IfPtr = strstr (SubString, "#if"); 232 if (!IfPtr) 233 { 234 return; 235 } 236 237 if (IfPtr > SubBuffer) 238 { 239 /* Not the right #if */ 240 241 SubString = SubBuffer + strlen (Keyword); 242 continue; 243 } 244 245 /* Find closing #endif or #else */ 246 247 EndifPtr = strstr (SubBuffer, "#endif"); 248 if (!EndifPtr) 249 { 250 /* There has to be an #endif */ 251 252 return; 253 } 254 255 ElsePtr = strstr (SubBuffer, "#else"); 256 if ((ElsePtr) && 257 (EndifPtr > ElsePtr)) 258 { 259 /* This #ifdef contains an #else clause */ 260 /* Find end of this line */ 261 262 SubBuffer = AsSkipPastChar (ElsePtr, '\n'); 263 if (!SubBuffer) 264 { 265 return; 266 } 267 268 /* Remove the #ifdef .... #else code */ 269 270 AsRemoveData (SubString, SubBuffer); 271 272 /* Next, we will remove the #endif statement */ 273 274 EndifPtr = strstr (SubString, "#endif"); 275 if (!EndifPtr) 276 { 277 /* There has to be an #endif */ 278 279 return; 280 } 281 282 SubString = EndifPtr; 283 } 284 285 /* Remove the ... #endif part */ 286 /* Find end of this line */ 287 288 SubBuffer = AsSkipPastChar (EndifPtr, '\n'); 289 if (!SubBuffer) 290 { 291 return; 292 } 293 294 /* Remove the lines */ 295 296 SubBuffer = AsRemoveData (SubString, SubBuffer); 297 } 298 } 299 300 301 #ifdef _OBSOLETE_FUNCTIONS 302 /****************************************************************************** 303 * 304 * FUNCTION: AsRemoveMacro 305 * 306 * DESCRIPTION: Remove every line that contains the keyword. Does not 307 * skip comments. 308 * 309 ******************************************************************************/ 310 311 NOTE: This function is no longer used and is commented out for now. 312 313 Also, it appears to have one or more bugs in it. It can incorrectly remove 314 lines of code, producing some garbage. 315 316 void 317 AsRemoveMacro ( 318 char *Buffer, 319 char *Keyword) 320 { 321 char *SubString; 322 char *SubBuffer; 323 int NestLevel; 324 325 326 SubBuffer = Buffer; 327 SubString = Buffer; 328 329 while (SubString) 330 { 331 SubString = strstr (SubBuffer, Keyword); 332 333 if (SubString) 334 { 335 SubBuffer = SubString; 336 337 /* Find start of the macro parameters */ 338 339 while (*SubString != '(') 340 { 341 SubString++; 342 } 343 SubString++; 344 345 /* Remove the macro name and opening paren */ 346 347 SubString = AsRemoveData (SubBuffer, SubString); 348 349 NestLevel = 1; 350 while (*SubString) 351 { 352 if (*SubString == '(') 353 { 354 NestLevel++; 355 } 356 else if (*SubString == ')') 357 { 358 NestLevel--; 359 } 360 361 SubString++; 362 363 if (NestLevel == 0) 364 { 365 break; 366 } 367 } 368 369 /* Remove the closing paren */ 370 371 SubBuffer = AsRemoveData (SubString-1, SubString); 372 } 373 } 374 } 375 #endif 376 377 /****************************************************************************** 378 * 379 * FUNCTION: AsRemoveLine 380 * 381 * DESCRIPTION: Remove every line that contains the keyword. Does not 382 * skip comments. 383 * 384 ******************************************************************************/ 385 386 void 387 AsRemoveLine ( 388 char *Buffer, 389 char *Keyword) 390 { 391 char *SubString; 392 char *SubBuffer; 393 394 395 SubBuffer = Buffer; 396 SubString = Buffer; 397 398 while (SubString) 399 { 400 SubString = strstr (SubBuffer, Keyword); 401 402 if (SubString) 403 { 404 SubBuffer = SubString; 405 406 /* Find start of this line */ 407 408 while (*SubString != '\n') 409 { 410 SubString--; 411 } 412 SubString++; 413 414 /* Find end of this line */ 415 416 SubBuffer = AsSkipPastChar (SubBuffer, '\n'); 417 if (!SubBuffer) 418 { 419 return; 420 } 421 422 /* Remove the line */ 423 424 SubBuffer = AsRemoveData (SubString, SubBuffer); 425 } 426 } 427 } 428 429 430 /****************************************************************************** 431 * 432 * FUNCTION: AsReduceTypedefs 433 * 434 * DESCRIPTION: Eliminate certain typedefs 435 * 436 ******************************************************************************/ 437 438 void 439 AsReduceTypedefs ( 440 char *Buffer, 441 char *Keyword) 442 { 443 char *SubString; 444 char *SubBuffer; 445 char *SubSubString; 446 int NestLevel; 447 448 449 SubBuffer = Buffer; 450 SubString = Buffer; 451 452 while (SubString) 453 { 454 SubString = strstr (SubBuffer, Keyword); 455 456 if (SubString) 457 { 458 SubSubString = SubString + strlen (Keyword); 459 460 /* skip spaces */ 461 462 while (strchr(" \t\r\n", *SubSubString)) 463 { 464 SubSubString++; 465 } 466 467 /* skip type name */ 468 469 while (!strchr(" \t\r\n", *SubSubString)) 470 { 471 SubSubString++; 472 } 473 474 /* skip spaces */ 475 476 while (strchr(" \t\r\n", *SubSubString)) 477 { 478 SubSubString++; 479 } 480 481 if (*SubSubString == '{') 482 { 483 /* Remove the typedef itself */ 484 485 SubBuffer = SubString + strlen ("typedef") + 1; 486 SubBuffer = AsRemoveData (SubString, SubBuffer); 487 488 /* Find the opening brace of the struct or union */ 489 490 while (*SubString != '{') 491 { 492 SubString++; 493 } 494 SubString++; 495 496 /* Find the closing brace. Handles nested braces */ 497 498 NestLevel = 1; 499 while (*SubString) 500 { 501 if (*SubString == '{') 502 { 503 NestLevel++; 504 } 505 else if (*SubString == '}') 506 { 507 NestLevel--; 508 } 509 510 SubString++; 511 512 if (NestLevel == 0) 513 { 514 break; 515 } 516 } 517 518 /* Remove an extra line feed if present */ 519 520 if (!strncmp (SubString - 3, "\n\n", 2)) 521 { 522 *(SubString -2) = '}'; 523 SubString--; 524 } 525 526 /* Find the end of the typedef name */ 527 528 SubBuffer = AsSkipUntilChar (SubString, ';'); 529 530 /* And remove the typedef name */ 531 532 SubBuffer = AsRemoveData (SubString, SubBuffer); 533 } 534 else 535 { 536 /* Skip the entire definition */ 537 538 SubString = strchr (SubString, ';') + 1; 539 SubBuffer = SubString; 540 } 541 } 542 } 543 } 544 545 546 /****************************************************************************** 547 * 548 * FUNCTION: AsRemoveEmptyBlocks 549 * 550 * DESCRIPTION: Remove any C blocks (e.g., if {}) that contain no code. This 551 * can happen as a result of removing lines such as DEBUG_PRINT. 552 * 553 ******************************************************************************/ 554 555 void 556 AsRemoveEmptyBlocks ( 557 char *Buffer, 558 char *Filename) 559 { 560 char *SubBuffer; 561 char *BlockStart; 562 BOOLEAN EmptyBlock = TRUE; 563 BOOLEAN AnotherPassRequired = TRUE; 564 UINT32 BlockCount = 0; 565 566 567 while (AnotherPassRequired) 568 { 569 SubBuffer = Buffer; 570 AnotherPassRequired = FALSE; 571 572 while (*SubBuffer) 573 { 574 if (*SubBuffer == '{') 575 { 576 BlockStart = SubBuffer; 577 EmptyBlock = TRUE; 578 579 SubBuffer++; 580 while (*SubBuffer != '}') 581 { 582 if ((*SubBuffer != ' ') && 583 (*SubBuffer != '\n')) 584 { 585 EmptyBlock = FALSE; 586 break; 587 } 588 589 SubBuffer++; 590 } 591 592 if (EmptyBlock) 593 { 594 /* Find start of the first line of the block */ 595 596 while (*BlockStart != '\n') 597 { 598 BlockStart--; 599 } 600 601 /* Find end of the last line of the block */ 602 603 SubBuffer = AsSkipUntilChar (SubBuffer, '\n'); 604 if (!SubBuffer) 605 { 606 break; 607 } 608 609 /* Remove the block */ 610 611 SubBuffer = AsRemoveData (BlockStart, SubBuffer); 612 BlockCount++; 613 AnotherPassRequired = TRUE; 614 continue; 615 } 616 } 617 618 SubBuffer++; 619 } 620 } 621 622 if (BlockCount) 623 { 624 Gbl_MadeChanges = TRUE; 625 AsPrint ("Code blocks deleted", BlockCount, Filename); 626 } 627 } 628 629 630 /****************************************************************************** 631 * 632 * FUNCTION: AsRemoveDebugMacros 633 * 634 * DESCRIPTION: Remove all "Debug" macros -- macros that produce debug output. 635 * 636 ******************************************************************************/ 637 638 void 639 AsRemoveDebugMacros ( 640 char *Buffer) 641 { 642 AsRemoveConditionalCompile (Buffer, "ACPI_DEBUG_OUTPUT"); 643 644 AsRemoveStatement (Buffer, "ACPI_DEBUG_PRINT", REPLACE_WHOLE_WORD); 645 AsRemoveStatement (Buffer, "ACPI_DEBUG_PRINT_RAW", REPLACE_WHOLE_WORD); 646 AsRemoveStatement (Buffer, "DEBUG_EXEC", REPLACE_WHOLE_WORD); 647 AsRemoveStatement (Buffer, "FUNCTION_ENTRY", REPLACE_WHOLE_WORD); 648 AsRemoveStatement (Buffer, "PROC_NAME", REPLACE_WHOLE_WORD); 649 AsRemoveStatement (Buffer, "FUNCTION_TRACE", REPLACE_SUBSTRINGS); 650 AsRemoveStatement (Buffer, "DUMP_", REPLACE_SUBSTRINGS); 651 652 AsReplaceString ("return_VOID", "return", REPLACE_WHOLE_WORD, Buffer); 653 AsReplaceString ("return_PTR", "return", REPLACE_WHOLE_WORD, Buffer); 654 AsReplaceString ("return_STR", "return", REPLACE_WHOLE_WORD, Buffer); 655 AsReplaceString ("return_ACPI_STATUS", "return", REPLACE_WHOLE_WORD, Buffer); 656 AsReplaceString ("return_acpi_status", "return", REPLACE_WHOLE_WORD, Buffer); 657 AsReplaceString ("return_VALUE", "return", REPLACE_WHOLE_WORD, Buffer); 658 } 659 660 661 /****************************************************************************** 662 * 663 * FUNCTION: AsCleanupSpecialMacro 664 * 665 * DESCRIPTION: For special macro invocations (invoked without ";" at the end 666 * of the lines), do the following: 667 * 1. Remove spaces appended by indent at the beginning of lines. 668 * 2. Add an empty line between two special macro invocations. 669 * 670 ******************************************************************************/ 671 672 void 673 AsCleanupSpecialMacro ( 674 char *Buffer, 675 char *Keyword) 676 { 677 char *SubString; 678 char *SubBuffer; 679 char *CommentEnd; 680 int NewLine; 681 int NestLevel; 682 683 684 SubBuffer = Buffer; 685 SubString = Buffer; 686 687 while (SubString) 688 { 689 SubString = strstr (SubBuffer, Keyword); 690 691 if (SubString) 692 { 693 /* Find start of the macro parameters */ 694 695 while (*SubString != '(') 696 { 697 SubString++; 698 } 699 700 SubString++; 701 702 NestLevel = 1; 703 while (*SubString) 704 { 705 if (*SubString == '(') 706 { 707 NestLevel++; 708 } 709 else if (*SubString == ')') 710 { 711 NestLevel--; 712 } 713 714 SubString++; 715 716 if (NestLevel == 0) 717 { 718 break; 719 } 720 } 721 722 SkipLine: 723 724 /* Find end of the line */ 725 726 NewLine = FALSE; 727 while (!NewLine && *SubString) 728 { 729 if (*SubString == '\n' && *(SubString - 1) != '\\') 730 { 731 NewLine = TRUE; 732 } 733 734 SubString++; 735 } 736 737 /* Find end of the line */ 738 739 if (*SubString == '#' || *SubString == '\n') 740 { 741 goto SkipLine; 742 } 743 744 SubBuffer = SubString; 745 746 /* Find start of the non-space */ 747 748 while (*SubString == ' ') 749 { 750 SubString++; 751 } 752 753 /* Find end of the line */ 754 755 if (*SubString == '#' || *SubString == '\n') 756 { 757 goto SkipLine; 758 } 759 760 /* Find end of the line */ 761 762 if (*SubString == '/' || *SubString == '*') 763 { 764 CommentEnd = strstr (SubString, "*/"); 765 if (CommentEnd) 766 { 767 SubString = CommentEnd + 2; 768 goto SkipLine; 769 } 770 } 771 772 SubString = AsRemoveData (SubBuffer, SubString); 773 } 774 } 775 } 776