1 /****************************************************************************** 2 * 3 * Module Name: asremove - Source conversion - removal functions 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2013, 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 /****************************************************************************** 303 * 304 * FUNCTION: AsRemoveMacro 305 * 306 * DESCRIPTION: Remove every line that contains the keyword. Does not 307 * skip comments. 308 * 309 ******************************************************************************/ 310 311 void 312 AsRemoveMacro ( 313 char *Buffer, 314 char *Keyword) 315 { 316 char *SubString; 317 char *SubBuffer; 318 int NestLevel; 319 320 321 SubBuffer = Buffer; 322 SubString = Buffer; 323 324 325 while (SubString) 326 { 327 SubString = strstr (SubBuffer, Keyword); 328 329 if (SubString) 330 { 331 SubBuffer = SubString; 332 333 /* Find start of the macro parameters */ 334 335 while (*SubString != '(') 336 { 337 SubString++; 338 } 339 SubString++; 340 341 /* Remove the macro name and opening paren */ 342 343 SubString = AsRemoveData (SubBuffer, SubString); 344 345 NestLevel = 1; 346 while (*SubString) 347 { 348 if (*SubString == '(') 349 { 350 NestLevel++; 351 } 352 else if (*SubString == ')') 353 { 354 NestLevel--; 355 } 356 357 SubString++; 358 359 if (NestLevel == 0) 360 { 361 break; 362 } 363 } 364 365 /* Remove the closing paren */ 366 367 SubBuffer = AsRemoveData (SubString-1, SubString); 368 } 369 } 370 } 371 372 373 /****************************************************************************** 374 * 375 * FUNCTION: AsRemoveLine 376 * 377 * DESCRIPTION: Remove every line that contains the keyword. Does not 378 * skip comments. 379 * 380 ******************************************************************************/ 381 382 void 383 AsRemoveLine ( 384 char *Buffer, 385 char *Keyword) 386 { 387 char *SubString; 388 char *SubBuffer; 389 390 391 SubBuffer = Buffer; 392 SubString = Buffer; 393 394 395 while (SubString) 396 { 397 SubString = strstr (SubBuffer, Keyword); 398 399 if (SubString) 400 { 401 SubBuffer = SubString; 402 403 /* Find start of this line */ 404 405 while (*SubString != '\n') 406 { 407 SubString--; 408 } 409 SubString++; 410 411 /* Find end of this line */ 412 413 SubBuffer = AsSkipPastChar (SubBuffer, '\n'); 414 if (!SubBuffer) 415 { 416 return; 417 } 418 419 /* Remove the line */ 420 421 SubBuffer = AsRemoveData (SubString, SubBuffer); 422 } 423 } 424 } 425 426 427 /****************************************************************************** 428 * 429 * FUNCTION: AsReduceTypedefs 430 * 431 * DESCRIPTION: Eliminate certain typedefs 432 * 433 ******************************************************************************/ 434 435 void 436 AsReduceTypedefs ( 437 char *Buffer, 438 char *Keyword) 439 { 440 char *SubString; 441 char *SubBuffer; 442 int NestLevel; 443 444 445 SubBuffer = Buffer; 446 SubString = Buffer; 447 448 449 while (SubString) 450 { 451 SubString = strstr (SubBuffer, Keyword); 452 453 if (SubString) 454 { 455 /* Remove the typedef itself */ 456 457 SubBuffer = SubString + strlen ("typedef") + 1; 458 SubBuffer = AsRemoveData (SubString, SubBuffer); 459 460 /* Find the opening brace of the struct or union */ 461 462 while (*SubString != '{') 463 { 464 SubString++; 465 } 466 SubString++; 467 468 /* Find the closing brace. Handles nested braces */ 469 470 NestLevel = 1; 471 while (*SubString) 472 { 473 if (*SubString == '{') 474 { 475 NestLevel++; 476 } 477 else if (*SubString == '}') 478 { 479 NestLevel--; 480 } 481 482 SubString++; 483 484 if (NestLevel == 0) 485 { 486 break; 487 } 488 } 489 490 /* Remove an extra line feed if present */ 491 492 if (!strncmp (SubString - 3, "\n\n", 2)) 493 { 494 *(SubString -2) = '}'; 495 SubString--; 496 } 497 498 /* Find the end of the typedef name */ 499 500 SubBuffer = AsSkipUntilChar (SubString, ';'); 501 502 /* And remove the typedef name */ 503 504 SubBuffer = AsRemoveData (SubString, SubBuffer); 505 } 506 } 507 } 508 509 510 /****************************************************************************** 511 * 512 * FUNCTION: AsRemoveEmptyBlocks 513 * 514 * DESCRIPTION: Remove any C blocks (e.g., if {}) that contain no code. This 515 * can happen as a result of removing lines such as DEBUG_PRINT. 516 * 517 ******************************************************************************/ 518 519 void 520 AsRemoveEmptyBlocks ( 521 char *Buffer, 522 char *Filename) 523 { 524 char *SubBuffer; 525 char *BlockStart; 526 BOOLEAN EmptyBlock = TRUE; 527 BOOLEAN AnotherPassRequired = TRUE; 528 UINT32 BlockCount = 0; 529 530 531 while (AnotherPassRequired) 532 { 533 SubBuffer = Buffer; 534 AnotherPassRequired = FALSE; 535 536 while (*SubBuffer) 537 { 538 if (*SubBuffer == '{') 539 { 540 BlockStart = SubBuffer; 541 EmptyBlock = TRUE; 542 543 SubBuffer++; 544 while (*SubBuffer != '}') 545 { 546 if ((*SubBuffer != ' ') && 547 (*SubBuffer != '\n')) 548 { 549 EmptyBlock = FALSE; 550 break; 551 } 552 SubBuffer++; 553 } 554 555 if (EmptyBlock) 556 { 557 /* Find start of the first line of the block */ 558 559 while (*BlockStart != '\n') 560 { 561 BlockStart--; 562 } 563 564 /* Find end of the last line of the block */ 565 566 SubBuffer = AsSkipUntilChar (SubBuffer, '\n'); 567 if (!SubBuffer) 568 { 569 break; 570 } 571 572 /* Remove the block */ 573 574 SubBuffer = AsRemoveData (BlockStart, SubBuffer); 575 BlockCount++; 576 AnotherPassRequired = TRUE; 577 continue; 578 } 579 } 580 581 SubBuffer++; 582 } 583 } 584 585 if (BlockCount) 586 { 587 Gbl_MadeChanges = TRUE; 588 AsPrint ("Code blocks deleted", BlockCount, Filename); 589 } 590 } 591 592 593 /****************************************************************************** 594 * 595 * FUNCTION: AsRemoveDebugMacros 596 * 597 * DESCRIPTION: Remove all "Debug" macros -- macros that produce debug output. 598 * 599 ******************************************************************************/ 600 601 void 602 AsRemoveDebugMacros ( 603 char *Buffer) 604 { 605 AsRemoveConditionalCompile (Buffer, "ACPI_DEBUG_OUTPUT"); 606 607 AsRemoveStatement (Buffer, "ACPI_DEBUG_PRINT", REPLACE_WHOLE_WORD); 608 AsRemoveStatement (Buffer, "ACPI_DEBUG_PRINT_RAW", REPLACE_WHOLE_WORD); 609 AsRemoveStatement (Buffer, "DEBUG_EXEC", REPLACE_WHOLE_WORD); 610 AsRemoveStatement (Buffer, "FUNCTION_ENTRY", REPLACE_WHOLE_WORD); 611 AsRemoveStatement (Buffer, "PROC_NAME", REPLACE_WHOLE_WORD); 612 AsRemoveStatement (Buffer, "FUNCTION_TRACE", REPLACE_SUBSTRINGS); 613 AsRemoveStatement (Buffer, "DUMP_", REPLACE_SUBSTRINGS); 614 615 AsReplaceString ("return_VOID", "return", REPLACE_WHOLE_WORD, Buffer); 616 AsReplaceString ("return_PTR", "return", REPLACE_WHOLE_WORD, Buffer); 617 AsReplaceString ("return_ACPI_STATUS", "return", REPLACE_WHOLE_WORD, Buffer); 618 AsReplaceString ("return_acpi_status", "return", REPLACE_WHOLE_WORD, Buffer); 619 AsReplaceString ("return_VALUE", "return", REPLACE_WHOLE_WORD, Buffer); 620 } 621 622 623 /****************************************************************************** 624 * 625 * FUNCTION: AsCleanupSpecialMacro 626 * 627 * DESCRIPTION: For special macro invocations (invoked without ";" at the end 628 * of the lines), do the following: 629 * 1. Remove spaces appended by indent at the beginning of lines. 630 * 2. Add an empty line between two special macro invocations. 631 * 632 ******************************************************************************/ 633 634 void 635 AsCleanupSpecialMacro ( 636 char *Buffer, 637 char *Keyword) 638 { 639 char *SubString; 640 char *SubBuffer; 641 char *CommentEnd; 642 int NewLine; 643 int NestLevel; 644 645 646 SubBuffer = Buffer; 647 SubString = Buffer; 648 649 while (SubString) 650 { 651 SubString = strstr (SubBuffer, Keyword); 652 653 if (SubString) 654 { 655 /* Find start of the macro parameters */ 656 657 while (*SubString != '(') 658 { 659 SubString++; 660 } 661 SubString++; 662 663 NestLevel = 1; 664 while (*SubString) 665 { 666 if (*SubString == '(') 667 { 668 NestLevel++; 669 } 670 else if (*SubString == ')') 671 { 672 NestLevel--; 673 } 674 675 SubString++; 676 677 if (NestLevel == 0) 678 { 679 break; 680 } 681 } 682 683 SkipLine: 684 685 /* Find end of the line */ 686 687 NewLine = FALSE; 688 while (!NewLine && *SubString) 689 { 690 if (*SubString == '\n' && *(SubString - 1) != '\\') 691 { 692 NewLine = TRUE; 693 } 694 SubString++; 695 } 696 697 /* Find end of the line */ 698 699 if (*SubString == '#' || *SubString == '\n') 700 { 701 goto SkipLine; 702 } 703 704 SubBuffer = SubString; 705 706 /* Find start of the non-space */ 707 708 while (*SubString == ' ') 709 { 710 SubString++; 711 } 712 713 /* Find end of the line */ 714 715 if (*SubString == '#' || *SubString == '\n') 716 { 717 goto SkipLine; 718 } 719 720 /* Find end of the line */ 721 722 if (*SubString == '/' || *SubString == '*') 723 { 724 CommentEnd = strstr (SubString, "*/"); 725 if (CommentEnd) 726 { 727 SubString = CommentEnd + 2; 728 goto SkipLine; 729 } 730 } 731 732 SubString = AsRemoveData (SubBuffer, SubString); 733 } 734 } 735 }