1 /****************************************************************************** 2 * 3 * Module Name: asremove - Source conversion - removal functions 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, 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 int NestLevel; 446 447 448 SubBuffer = Buffer; 449 SubString = Buffer; 450 451 while (SubString) 452 { 453 SubString = strstr (SubBuffer, Keyword); 454 455 if (SubString) 456 { 457 /* Remove the typedef itself */ 458 459 SubBuffer = SubString + strlen ("typedef") + 1; 460 SubBuffer = AsRemoveData (SubString, SubBuffer); 461 462 /* Find the opening brace of the struct or union */ 463 464 while (*SubString != '{') 465 { 466 SubString++; 467 } 468 SubString++; 469 470 /* Find the closing brace. Handles nested braces */ 471 472 NestLevel = 1; 473 while (*SubString) 474 { 475 if (*SubString == '{') 476 { 477 NestLevel++; 478 } 479 else if (*SubString == '}') 480 { 481 NestLevel--; 482 } 483 484 SubString++; 485 486 if (NestLevel == 0) 487 { 488 break; 489 } 490 } 491 492 /* Remove an extra line feed if present */ 493 494 if (!strncmp (SubString - 3, "\n\n", 2)) 495 { 496 *(SubString -2) = '}'; 497 SubString--; 498 } 499 500 /* Find the end of the typedef name */ 501 502 SubBuffer = AsSkipUntilChar (SubString, ';'); 503 504 /* And remove the typedef name */ 505 506 SubBuffer = AsRemoveData (SubString, SubBuffer); 507 } 508 } 509 } 510 511 512 /****************************************************************************** 513 * 514 * FUNCTION: AsRemoveEmptyBlocks 515 * 516 * DESCRIPTION: Remove any C blocks (e.g., if {}) that contain no code. This 517 * can happen as a result of removing lines such as DEBUG_PRINT. 518 * 519 ******************************************************************************/ 520 521 void 522 AsRemoveEmptyBlocks ( 523 char *Buffer, 524 char *Filename) 525 { 526 char *SubBuffer; 527 char *BlockStart; 528 BOOLEAN EmptyBlock = TRUE; 529 BOOLEAN AnotherPassRequired = TRUE; 530 UINT32 BlockCount = 0; 531 532 533 while (AnotherPassRequired) 534 { 535 SubBuffer = Buffer; 536 AnotherPassRequired = FALSE; 537 538 while (*SubBuffer) 539 { 540 if (*SubBuffer == '{') 541 { 542 BlockStart = SubBuffer; 543 EmptyBlock = TRUE; 544 545 SubBuffer++; 546 while (*SubBuffer != '}') 547 { 548 if ((*SubBuffer != ' ') && 549 (*SubBuffer != '\n')) 550 { 551 EmptyBlock = FALSE; 552 break; 553 } 554 555 SubBuffer++; 556 } 557 558 if (EmptyBlock) 559 { 560 /* Find start of the first line of the block */ 561 562 while (*BlockStart != '\n') 563 { 564 BlockStart--; 565 } 566 567 /* Find end of the last line of the block */ 568 569 SubBuffer = AsSkipUntilChar (SubBuffer, '\n'); 570 if (!SubBuffer) 571 { 572 break; 573 } 574 575 /* Remove the block */ 576 577 SubBuffer = AsRemoveData (BlockStart, SubBuffer); 578 BlockCount++; 579 AnotherPassRequired = TRUE; 580 continue; 581 } 582 } 583 584 SubBuffer++; 585 } 586 } 587 588 if (BlockCount) 589 { 590 Gbl_MadeChanges = TRUE; 591 AsPrint ("Code blocks deleted", BlockCount, Filename); 592 } 593 } 594 595 596 /****************************************************************************** 597 * 598 * FUNCTION: AsRemoveDebugMacros 599 * 600 * DESCRIPTION: Remove all "Debug" macros -- macros that produce debug output. 601 * 602 ******************************************************************************/ 603 604 void 605 AsRemoveDebugMacros ( 606 char *Buffer) 607 { 608 AsRemoveConditionalCompile (Buffer, "ACPI_DEBUG_OUTPUT"); 609 610 AsRemoveStatement (Buffer, "ACPI_DEBUG_PRINT", REPLACE_WHOLE_WORD); 611 AsRemoveStatement (Buffer, "ACPI_DEBUG_PRINT_RAW", REPLACE_WHOLE_WORD); 612 AsRemoveStatement (Buffer, "DEBUG_EXEC", REPLACE_WHOLE_WORD); 613 AsRemoveStatement (Buffer, "FUNCTION_ENTRY", REPLACE_WHOLE_WORD); 614 AsRemoveStatement (Buffer, "PROC_NAME", REPLACE_WHOLE_WORD); 615 AsRemoveStatement (Buffer, "FUNCTION_TRACE", REPLACE_SUBSTRINGS); 616 AsRemoveStatement (Buffer, "DUMP_", REPLACE_SUBSTRINGS); 617 618 AsReplaceString ("return_VOID", "return", REPLACE_WHOLE_WORD, Buffer); 619 AsReplaceString ("return_PTR", "return", REPLACE_WHOLE_WORD, Buffer); 620 AsReplaceString ("return_STR", "return", REPLACE_WHOLE_WORD, Buffer); 621 AsReplaceString ("return_ACPI_STATUS", "return", REPLACE_WHOLE_WORD, Buffer); 622 AsReplaceString ("return_acpi_status", "return", REPLACE_WHOLE_WORD, Buffer); 623 AsReplaceString ("return_VALUE", "return", REPLACE_WHOLE_WORD, Buffer); 624 } 625 626 627 /****************************************************************************** 628 * 629 * FUNCTION: AsCleanupSpecialMacro 630 * 631 * DESCRIPTION: For special macro invocations (invoked without ";" at the end 632 * of the lines), do the following: 633 * 1. Remove spaces appended by indent at the beginning of lines. 634 * 2. Add an empty line between two special macro invocations. 635 * 636 ******************************************************************************/ 637 638 void 639 AsCleanupSpecialMacro ( 640 char *Buffer, 641 char *Keyword) 642 { 643 char *SubString; 644 char *SubBuffer; 645 char *CommentEnd; 646 int NewLine; 647 int NestLevel; 648 649 650 SubBuffer = Buffer; 651 SubString = Buffer; 652 653 while (SubString) 654 { 655 SubString = strstr (SubBuffer, Keyword); 656 657 if (SubString) 658 { 659 /* Find start of the macro parameters */ 660 661 while (*SubString != '(') 662 { 663 SubString++; 664 } 665 666 SubString++; 667 668 NestLevel = 1; 669 while (*SubString) 670 { 671 if (*SubString == '(') 672 { 673 NestLevel++; 674 } 675 else if (*SubString == ')') 676 { 677 NestLevel--; 678 } 679 680 SubString++; 681 682 if (NestLevel == 0) 683 { 684 break; 685 } 686 } 687 688 SkipLine: 689 690 /* Find end of the line */ 691 692 NewLine = FALSE; 693 while (!NewLine && *SubString) 694 { 695 if (*SubString == '\n' && *(SubString - 1) != '\\') 696 { 697 NewLine = TRUE; 698 } 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