1 /****************************************************************************** 2 * 3 * Module Name: asremove - Source conversion - removal functions 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2015, 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 82 while (SubString) 83 { 84 SubString = strstr (SubBuffer, Keyword); 85 86 if (SubString) 87 { 88 SubBuffer = SubString; 89 90 if ((Type == REPLACE_WHOLE_WORD) && 91 (!AsMatchExactWord (SubString, KeywordLength))) 92 { 93 SubBuffer++; 94 continue; 95 } 96 97 /* Find start of this line */ 98 99 while (*SubString != '\n') 100 { 101 SubString--; 102 } 103 SubString++; 104 105 /* Find end of this statement */ 106 107 SubBuffer = AsSkipPastChar (SubBuffer, ';'); 108 if (!SubBuffer) 109 { 110 return; 111 } 112 113 /* Find end of this line */ 114 115 SubBuffer = AsSkipPastChar (SubBuffer, '\n'); 116 if (!SubBuffer) 117 { 118 return; 119 } 120 121 /* If next line is blank, remove it too */ 122 123 if (*SubBuffer == '\n') 124 { 125 SubBuffer++; 126 } 127 128 /* Remove the lines */ 129 130 SubBuffer = AsRemoveData (SubString, SubBuffer); 131 } 132 } 133 } 134 135 136 /****************************************************************************** 137 * 138 * FUNCTION: AsRemoveConditionalCompile 139 * 140 * DESCRIPTION: Remove a "#ifdef" statement, and all text that it encompasses. 141 * Limitations: cannot handle nested ifdefs. 142 * 143 ******************************************************************************/ 144 145 void 146 AsRemoveConditionalCompile ( 147 char *Buffer, 148 char *Keyword) 149 { 150 char *SubString; 151 char *SubBuffer; 152 char *IfPtr; 153 char *EndifPtr; 154 char *ElsePtr; 155 char *Comment; 156 int KeywordLength; 157 158 159 KeywordLength = strlen (Keyword); 160 SubBuffer = Buffer; 161 SubString = Buffer; 162 163 164 while (SubString) 165 { 166 SubBuffer = strstr (SubString, Keyword); 167 if (!SubBuffer) 168 { 169 return; 170 } 171 172 /* 173 * Check for translation escape string -- means to ignore 174 * blocks of code while replacing 175 */ 176 if (Gbl_IgnoreTranslationEscapes) 177 { 178 Comment = NULL; 179 } 180 else 181 { 182 Comment = strstr (SubString, AS_START_IGNORE); 183 } 184 185 if ((Comment) && 186 (Comment < SubBuffer)) 187 { 188 SubString = strstr (Comment, AS_STOP_IGNORE); 189 if (!SubString) 190 { 191 return; 192 } 193 194 SubString += 3; 195 continue; 196 } 197 198 /* Check for ordinary comment */ 199 200 Comment = strstr (SubString, "/*"); 201 202 if ((Comment) && 203 (Comment < SubBuffer)) 204 { 205 SubString = strstr (Comment, "*/"); 206 if (!SubString) 207 { 208 return; 209 } 210 211 SubString += 2; 212 continue; 213 } 214 215 SubString = SubBuffer; 216 if (!AsMatchExactWord (SubString, KeywordLength)) 217 { 218 SubString++; 219 continue; 220 } 221 222 /* Find start of this line */ 223 224 while (*SubString != '\n' && (SubString > Buffer)) 225 { 226 SubString--; 227 } 228 SubString++; 229 230 /* Find the "#ifxxxx" */ 231 232 IfPtr = strstr (SubString, "#if"); 233 if (!IfPtr) 234 { 235 return; 236 } 237 238 if (IfPtr > SubBuffer) 239 { 240 /* Not the right #if */ 241 242 SubString = SubBuffer + strlen (Keyword); 243 continue; 244 } 245 246 /* Find closing #endif or #else */ 247 248 EndifPtr = strstr (SubBuffer, "#endif"); 249 if (!EndifPtr) 250 { 251 /* There has to be an #endif */ 252 253 return; 254 } 255 256 ElsePtr = strstr (SubBuffer, "#else"); 257 if ((ElsePtr) && 258 (EndifPtr > ElsePtr)) 259 { 260 /* This #ifdef contains an #else clause */ 261 /* Find end of this line */ 262 263 SubBuffer = AsSkipPastChar (ElsePtr, '\n'); 264 if (!SubBuffer) 265 { 266 return; 267 } 268 269 /* Remove the #ifdef .... #else code */ 270 271 AsRemoveData (SubString, SubBuffer); 272 273 /* Next, we will remove the #endif statement */ 274 275 EndifPtr = strstr (SubString, "#endif"); 276 if (!EndifPtr) 277 { 278 /* There has to be an #endif */ 279 280 return; 281 } 282 283 SubString = EndifPtr; 284 } 285 286 /* Remove the ... #endif part */ 287 /* Find end of this line */ 288 289 SubBuffer = AsSkipPastChar (EndifPtr, '\n'); 290 if (!SubBuffer) 291 { 292 return; 293 } 294 295 /* Remove the lines */ 296 297 SubBuffer = AsRemoveData (SubString, SubBuffer); 298 } 299 } 300 301 302 #ifdef _OBSOLETE_FUNCTIONS 303 /****************************************************************************** 304 * 305 * FUNCTION: AsRemoveMacro 306 * 307 * DESCRIPTION: Remove every line that contains the keyword. Does not 308 * skip comments. 309 * 310 ******************************************************************************/ 311 312 NOTE: This function is no longer used and is commented out for now. 313 314 Also, it appears to have one or more bugs in it. It can incorrectly remove 315 lines of code, producing some garbage. 316 317 void 318 AsRemoveMacro ( 319 char *Buffer, 320 char *Keyword) 321 { 322 char *SubString; 323 char *SubBuffer; 324 int NestLevel; 325 326 327 SubBuffer = Buffer; 328 SubString = Buffer; 329 330 331 while (SubString) 332 { 333 SubString = strstr (SubBuffer, Keyword); 334 335 if (SubString) 336 { 337 SubBuffer = SubString; 338 339 /* Find start of the macro parameters */ 340 341 while (*SubString != '(') 342 { 343 SubString++; 344 } 345 SubString++; 346 347 /* Remove the macro name and opening paren */ 348 349 SubString = AsRemoveData (SubBuffer, SubString); 350 351 NestLevel = 1; 352 while (*SubString) 353 { 354 if (*SubString == '(') 355 { 356 NestLevel++; 357 } 358 else if (*SubString == ')') 359 { 360 NestLevel--; 361 } 362 363 SubString++; 364 365 if (NestLevel == 0) 366 { 367 break; 368 } 369 } 370 371 /* Remove the closing paren */ 372 373 SubBuffer = AsRemoveData (SubString-1, SubString); 374 } 375 } 376 } 377 #endif 378 379 /****************************************************************************** 380 * 381 * FUNCTION: AsRemoveLine 382 * 383 * DESCRIPTION: Remove every line that contains the keyword. Does not 384 * skip comments. 385 * 386 ******************************************************************************/ 387 388 void 389 AsRemoveLine ( 390 char *Buffer, 391 char *Keyword) 392 { 393 char *SubString; 394 char *SubBuffer; 395 396 397 SubBuffer = Buffer; 398 SubString = Buffer; 399 400 401 while (SubString) 402 { 403 SubString = strstr (SubBuffer, Keyword); 404 405 if (SubString) 406 { 407 SubBuffer = SubString; 408 409 /* Find start of this line */ 410 411 while (*SubString != '\n') 412 { 413 SubString--; 414 } 415 SubString++; 416 417 /* Find end of this line */ 418 419 SubBuffer = AsSkipPastChar (SubBuffer, '\n'); 420 if (!SubBuffer) 421 { 422 return; 423 } 424 425 /* Remove the line */ 426 427 SubBuffer = AsRemoveData (SubString, SubBuffer); 428 } 429 } 430 } 431 432 433 /****************************************************************************** 434 * 435 * FUNCTION: AsReduceTypedefs 436 * 437 * DESCRIPTION: Eliminate certain typedefs 438 * 439 ******************************************************************************/ 440 441 void 442 AsReduceTypedefs ( 443 char *Buffer, 444 char *Keyword) 445 { 446 char *SubString; 447 char *SubBuffer; 448 int NestLevel; 449 450 451 SubBuffer = Buffer; 452 SubString = Buffer; 453 454 455 while (SubString) 456 { 457 SubString = strstr (SubBuffer, Keyword); 458 459 if (SubString) 460 { 461 /* Remove the typedef itself */ 462 463 SubBuffer = SubString + strlen ("typedef") + 1; 464 SubBuffer = AsRemoveData (SubString, SubBuffer); 465 466 /* Find the opening brace of the struct or union */ 467 468 while (*SubString != '{') 469 { 470 SubString++; 471 } 472 SubString++; 473 474 /* Find the closing brace. Handles nested braces */ 475 476 NestLevel = 1; 477 while (*SubString) 478 { 479 if (*SubString == '{') 480 { 481 NestLevel++; 482 } 483 else if (*SubString == '}') 484 { 485 NestLevel--; 486 } 487 488 SubString++; 489 490 if (NestLevel == 0) 491 { 492 break; 493 } 494 } 495 496 /* Remove an extra line feed if present */ 497 498 if (!strncmp (SubString - 3, "\n\n", 2)) 499 { 500 *(SubString -2) = '}'; 501 SubString--; 502 } 503 504 /* Find the end of the typedef name */ 505 506 SubBuffer = AsSkipUntilChar (SubString, ';'); 507 508 /* And remove the typedef name */ 509 510 SubBuffer = AsRemoveData (SubString, SubBuffer); 511 } 512 } 513 } 514 515 516 /****************************************************************************** 517 * 518 * FUNCTION: AsRemoveEmptyBlocks 519 * 520 * DESCRIPTION: Remove any C blocks (e.g., if {}) that contain no code. This 521 * can happen as a result of removing lines such as DEBUG_PRINT. 522 * 523 ******************************************************************************/ 524 525 void 526 AsRemoveEmptyBlocks ( 527 char *Buffer, 528 char *Filename) 529 { 530 char *SubBuffer; 531 char *BlockStart; 532 BOOLEAN EmptyBlock = TRUE; 533 BOOLEAN AnotherPassRequired = TRUE; 534 UINT32 BlockCount = 0; 535 536 537 while (AnotherPassRequired) 538 { 539 SubBuffer = Buffer; 540 AnotherPassRequired = FALSE; 541 542 while (*SubBuffer) 543 { 544 if (*SubBuffer == '{') 545 { 546 BlockStart = SubBuffer; 547 EmptyBlock = TRUE; 548 549 SubBuffer++; 550 while (*SubBuffer != '}') 551 { 552 if ((*SubBuffer != ' ') && 553 (*SubBuffer != '\n')) 554 { 555 EmptyBlock = FALSE; 556 break; 557 } 558 SubBuffer++; 559 } 560 561 if (EmptyBlock) 562 { 563 /* Find start of the first line of the block */ 564 565 while (*BlockStart != '\n') 566 { 567 BlockStart--; 568 } 569 570 /* Find end of the last line of the block */ 571 572 SubBuffer = AsSkipUntilChar (SubBuffer, '\n'); 573 if (!SubBuffer) 574 { 575 break; 576 } 577 578 /* Remove the block */ 579 580 SubBuffer = AsRemoveData (BlockStart, SubBuffer); 581 BlockCount++; 582 AnotherPassRequired = TRUE; 583 continue; 584 } 585 } 586 587 SubBuffer++; 588 } 589 } 590 591 if (BlockCount) 592 { 593 Gbl_MadeChanges = TRUE; 594 AsPrint ("Code blocks deleted", BlockCount, Filename); 595 } 596 } 597 598 599 /****************************************************************************** 600 * 601 * FUNCTION: AsRemoveDebugMacros 602 * 603 * DESCRIPTION: Remove all "Debug" macros -- macros that produce debug output. 604 * 605 ******************************************************************************/ 606 607 void 608 AsRemoveDebugMacros ( 609 char *Buffer) 610 { 611 AsRemoveConditionalCompile (Buffer, "ACPI_DEBUG_OUTPUT"); 612 613 AsRemoveStatement (Buffer, "ACPI_DEBUG_PRINT", REPLACE_WHOLE_WORD); 614 AsRemoveStatement (Buffer, "ACPI_DEBUG_PRINT_RAW", REPLACE_WHOLE_WORD); 615 AsRemoveStatement (Buffer, "DEBUG_EXEC", REPLACE_WHOLE_WORD); 616 AsRemoveStatement (Buffer, "FUNCTION_ENTRY", REPLACE_WHOLE_WORD); 617 AsRemoveStatement (Buffer, "PROC_NAME", REPLACE_WHOLE_WORD); 618 AsRemoveStatement (Buffer, "FUNCTION_TRACE", REPLACE_SUBSTRINGS); 619 AsRemoveStatement (Buffer, "DUMP_", REPLACE_SUBSTRINGS); 620 621 AsReplaceString ("return_VOID", "return", REPLACE_WHOLE_WORD, Buffer); 622 AsReplaceString ("return_PTR", "return", REPLACE_WHOLE_WORD, Buffer); 623 AsReplaceString ("return_ACPI_STATUS", "return", REPLACE_WHOLE_WORD, Buffer); 624 AsReplaceString ("return_acpi_status", "return", REPLACE_WHOLE_WORD, Buffer); 625 AsReplaceString ("return_VALUE", "return", REPLACE_WHOLE_WORD, Buffer); 626 } 627 628 629 /****************************************************************************** 630 * 631 * FUNCTION: AsCleanupSpecialMacro 632 * 633 * DESCRIPTION: For special macro invocations (invoked without ";" at the end 634 * of the lines), do the following: 635 * 1. Remove spaces appended by indent at the beginning of lines. 636 * 2. Add an empty line between two special macro invocations. 637 * 638 ******************************************************************************/ 639 640 void 641 AsCleanupSpecialMacro ( 642 char *Buffer, 643 char *Keyword) 644 { 645 char *SubString; 646 char *SubBuffer; 647 char *CommentEnd; 648 int NewLine; 649 int NestLevel; 650 651 652 SubBuffer = Buffer; 653 SubString = Buffer; 654 655 while (SubString) 656 { 657 SubString = strstr (SubBuffer, Keyword); 658 659 if (SubString) 660 { 661 /* Find start of the macro parameters */ 662 663 while (*SubString != '(') 664 { 665 SubString++; 666 } 667 SubString++; 668 669 NestLevel = 1; 670 while (*SubString) 671 { 672 if (*SubString == '(') 673 { 674 NestLevel++; 675 } 676 else if (*SubString == ')') 677 { 678 NestLevel--; 679 } 680 681 SubString++; 682 683 if (NestLevel == 0) 684 { 685 break; 686 } 687 } 688 689 SkipLine: 690 691 /* Find end of the line */ 692 693 NewLine = FALSE; 694 while (!NewLine && *SubString) 695 { 696 if (*SubString == '\n' && *(SubString - 1) != '\\') 697 { 698 NewLine = TRUE; 699 } 700 SubString++; 701 } 702 703 /* Find end of the line */ 704 705 if (*SubString == '#' || *SubString == '\n') 706 { 707 goto SkipLine; 708 } 709 710 SubBuffer = SubString; 711 712 /* Find start of the non-space */ 713 714 while (*SubString == ' ') 715 { 716 SubString++; 717 } 718 719 /* Find end of the line */ 720 721 if (*SubString == '#' || *SubString == '\n') 722 { 723 goto SkipLine; 724 } 725 726 /* Find end of the line */ 727 728 if (*SubString == '/' || *SubString == '*') 729 { 730 CommentEnd = strstr (SubString, "*/"); 731 if (CommentEnd) 732 { 733 SubString = CommentEnd + 2; 734 goto SkipLine; 735 } 736 } 737 738 SubString = AsRemoveData (SubBuffer, SubString); 739 } 740 } 741 } 742